git_reflow 0.8.6 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitignore +1 -0
 - data/CHANGELOG.md +348 -348
 - data/Gemfile.lock +13 -15
 - data/LICENSE +20 -20
 - data/README.rdoc +461 -461
 - data/Rakefile +8 -8
 - data/bin/console +7 -7
 - data/bin/setup +6 -6
 - data/circle.yml +5 -5
 - data/exe/git-reflow +36 -36
 - data/git_reflow.gemspec +1 -1
 - data/lib/git_reflow/commands/deliver.rb +10 -10
 - data/lib/git_reflow/commands/refresh.rb +20 -20
 - data/lib/git_reflow/commands/review.rb +13 -13
 - data/lib/git_reflow/commands/setup.rb +11 -11
 - data/lib/git_reflow/commands/stage.rb +9 -9
 - data/lib/git_reflow/commands/start.rb +22 -22
 - data/lib/git_reflow/commands/status.rb +7 -7
 - data/lib/git_reflow/config.rb +9 -9
 - data/lib/git_reflow/git_server/base.rb +68 -68
 - data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
 - data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
 - data/lib/git_reflow/git_server/git_hub/pull_request.rb +4 -1
 - data/lib/git_reflow/git_server/pull_request.rb +11 -2
 - data/lib/git_reflow/git_server.rb +63 -63
 - data/lib/git_reflow/logger.rb +49 -0
 - data/lib/git_reflow/merge_error.rb +9 -9
 - data/lib/git_reflow/os_detector.rb +23 -23
 - data/lib/git_reflow/rspec/command_line_helpers.rb +12 -8
 - data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
 - data/lib/git_reflow/rspec.rb +2 -2
 - data/lib/git_reflow/sandbox.rb +11 -6
 - data/lib/git_reflow/version.rb +1 -1
 - data/lib/git_reflow/workflow.rb +59 -59
 - data/lib/git_reflow/workflows/core.rb +238 -238
 - data/lib/git_reflow/workflows/flat_merge.rb +10 -10
 - data/lib/git_reflow.rb +11 -0
 - data/spec/fixtures/awesome_workflow.rb +7 -0
 - data/spec/fixtures/git/git_config +7 -0
 - data/spec/fixtures/issues/comment.json.erb +27 -0
 - data/spec/fixtures/issues/comments.json +29 -0
 - data/spec/fixtures/issues/comments.json.erb +15 -0
 - data/spec/fixtures/pull_requests/comment.json.erb +45 -0
 - data/spec/fixtures/pull_requests/comments.json +47 -0
 - data/spec/fixtures/pull_requests/comments.json.erb +15 -0
 - data/spec/fixtures/pull_requests/commits.json +29 -0
 - data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
 - data/spec/fixtures/pull_requests/pull_request.json +142 -0
 - data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
 - data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -0
 - data/spec/fixtures/pull_requests/pull_requests.json +136 -0
 - data/spec/fixtures/repositories/commit.json +53 -0
 - data/spec/fixtures/repositories/commit.json.erb +53 -0
 - data/spec/fixtures/repositories/commits.json.erb +13 -0
 - data/spec/fixtures/repositories/statuses.json +31 -0
 - data/spec/fixtures/workflow_with_super.rb +8 -0
 - data/spec/lib/git_reflow/config_spec.rb +74 -0
 - data/spec/lib/git_reflow/git_helpers_spec.rb +182 -0
 - data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -0
 - data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +587 -0
 - data/spec/lib/git_reflow/git_server/git_hub_spec.rb +221 -0
 - data/spec/lib/git_reflow/git_server/pull_request_spec.rb +524 -0
 - data/spec/lib/git_reflow/git_server_spec.rb +101 -0
 - data/spec/lib/git_reflow/logger_spec.rb +18 -0
 - data/spec/lib/git_reflow/sandbox_spec.rb +15 -0
 - data/spec/lib/git_reflow/workflow_spec.rb +59 -0
 - data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
 - data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +59 -0
 - data/spec/lib/git_reflow_spec.rb +75 -0
 - data/spec/spec_helper.rb +38 -0
 - data/spec/support/fake_github.rb +128 -0
 - data/spec/support/fixtures.rb +54 -0
 - data/spec/support/github_helpers.rb +109 -0
 - data/spec/support/mock_pull_request.rb +17 -0
 - data/spec/support/web_mocks.rb +39 -0
 - metadata +83 -6
 
| 
         @@ -1,84 +1,84 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'git_reflow/git_server/pull_request'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module GitReflow
         
     | 
| 
       4 
     | 
    
         
            -
              module GitServer
         
     | 
| 
       5 
     | 
    
         
            -
                class BitBucket
         
     | 
| 
       6 
     | 
    
         
            -
                  class PullRequest < GitReflow::GitServer::PullRequest
         
     | 
| 
       7 
     | 
    
         
            -
                    def initialize(attributes)
         
     | 
| 
       8 
     | 
    
         
            -
                      self.number              = attributes.id
         
     | 
| 
       9 
     | 
    
         
            -
                      self.description         = attributes.body || attributes.description
         
     | 
| 
       10 
     | 
    
         
            -
                      self.html_url            = "#{attributes.source.repository.links.html.href}/pull-request/#{self.number}"
         
     | 
| 
       11 
     | 
    
         
            -
                      self.feature_branch_name = attributes.source.branch.name[/[^:]+$/]
         
     | 
| 
       12 
     | 
    
         
            -
                      self.base_branch_name    = attributes.destination.branch.name[/[^:]+$/]
         
     | 
| 
       13 
     | 
    
         
            -
                      self.build               = Build.new
         
     | 
| 
       14 
     | 
    
         
            -
                      self.source_object       = attributes
         
     | 
| 
       15 
     | 
    
         
            -
                    end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                    def self.create(options = {})
         
     | 
| 
       18 
     | 
    
         
            -
                      self.new GitReflow.git_server.connection.repos.pull_requests.create(
         
     | 
| 
       19 
     | 
    
         
            -
                        GitReflow.git_server.class.remote_user,
         
     | 
| 
       20 
     | 
    
         
            -
                        GitReflow.git_server.class.remote_repo_name,
         
     | 
| 
       21 
     | 
    
         
            -
                        title: options[:title],
         
     | 
| 
       22 
     | 
    
         
            -
                        description: options[:body] || options[:description],
         
     | 
| 
       23 
     | 
    
         
            -
                        source: {
         
     | 
| 
       24 
     | 
    
         
            -
                          branch: { name: GitReflow.git_server.class.current_branch },
         
     | 
| 
       25 
     | 
    
         
            -
                          repository: { full_name: "#{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}" }
         
     | 
| 
       26 
     | 
    
         
            -
                        },
         
     | 
| 
       27 
     | 
    
         
            -
                        destination: {
         
     | 
| 
       28 
     | 
    
         
            -
                          branch: { name: options[:base] }
         
     | 
| 
       29 
     | 
    
         
            -
                        },
         
     | 
| 
       30 
     | 
    
         
            -
                        reviewers: [username: GitReflow.git_server.class.user])
         
     | 
| 
       31 
     | 
    
         
            -
                    end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                    def self.find_open(to: 'master', from: GitReflow.git_server.class.current_branch)
         
     | 
| 
       34 
     | 
    
         
            -
                      begin
         
     | 
| 
       35 
     | 
    
         
            -
                        matching_pull = GitReflow.git_server.connection.repos.pull_requests.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, limit: 1).select do |pr|
         
     | 
| 
       36 
     | 
    
         
            -
                          pr.source.branch.name == from and
         
     | 
| 
       37 
     | 
    
         
            -
                          pr.destination.branch.name == to
         
     | 
| 
       38 
     | 
    
         
            -
                        end.first
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                        if matching_pull
         
     | 
| 
       41 
     | 
    
         
            -
                          self.new matching_pull
         
     | 
| 
       42 
     | 
    
         
            -
                        end
         
     | 
| 
       43 
     | 
    
         
            -
                      rescue ::BitBucket::Error::NotFound => e
         
     | 
| 
       44 
     | 
    
         
            -
                        GitReflow.git_server.say "No BitBucket repo found for #{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}", :error
         
     | 
| 
       45 
     | 
    
         
            -
                      rescue ::BitBucket::Error::Forbidden => e
         
     | 
| 
       46 
     | 
    
         
            -
                        GitReflow.git_server.say "You don't have API access to this repo", :error
         
     | 
| 
       47 
     | 
    
         
            -
                      end
         
     | 
| 
       48 
     | 
    
         
            -
                    end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                    def commit_author
         
     | 
| 
       51 
     | 
    
         
            -
                      # use the author of the pull request
         
     | 
| 
       52 
     | 
    
         
            -
                      self.author.username
         
     | 
| 
       53 
     | 
    
         
            -
                    end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                    def comments
         
     | 
| 
       56 
     | 
    
         
            -
                      GitReflow.git_server.connection.repos.pull_requests.comments.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id)
         
     | 
| 
       57 
     | 
    
         
            -
                    end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                    def last_comment
         
     | 
| 
       60 
     | 
    
         
            -
                      last_comment = comments.first
         
     | 
| 
       61 
     | 
    
         
            -
                      return "" unless last_comment
         
     | 
| 
       62 
     | 
    
         
            -
                      "#{last_comment.content.raw}"
         
     | 
| 
       63 
     | 
    
         
            -
                    end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                    def reviewers
         
     | 
| 
       66 
     | 
    
         
            -
                      return [] unless comments.size > 0
         
     | 
| 
       67 
     | 
    
         
            -
                      comments.map {|c| c.user.username }.uniq - [GitReflow.git_server.class.user]
         
     | 
| 
       68 
     | 
    
         
            -
                    end
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                    def approvals
         
     | 
| 
       71 
     | 
    
         
            -
                      approved  = []
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                      GitReflow.git_server.connection.repos.pull_requests.activity(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id).each do |activity|
         
     | 
| 
       74 
     | 
    
         
            -
                        break unless activity.respond_to?(:approval) and activity.approval.user.username != GitReflow.git_server.class.user
         
     | 
| 
       75 
     | 
    
         
            -
                        approved |= [activity.approval.user.username]
         
     | 
| 
       76 
     | 
    
         
            -
                      end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                      approved
         
     | 
| 
       79 
     | 
    
         
            -
                    end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                  end
         
     | 
| 
       82 
     | 
    
         
            -
                end
         
     | 
| 
       83 
     | 
    
         
            -
              end
         
     | 
| 
       84 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            require 'git_reflow/git_server/pull_request'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module GitReflow
         
     | 
| 
      
 4 
     | 
    
         
            +
              module GitServer
         
     | 
| 
      
 5 
     | 
    
         
            +
                class BitBucket
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class PullRequest < GitReflow::GitServer::PullRequest
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def initialize(attributes)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      self.number              = attributes.id
         
     | 
| 
      
 9 
     | 
    
         
            +
                      self.description         = attributes.body || attributes.description
         
     | 
| 
      
 10 
     | 
    
         
            +
                      self.html_url            = "#{attributes.source.repository.links.html.href}/pull-request/#{self.number}"
         
     | 
| 
      
 11 
     | 
    
         
            +
                      self.feature_branch_name = attributes.source.branch.name[/[^:]+$/]
         
     | 
| 
      
 12 
     | 
    
         
            +
                      self.base_branch_name    = attributes.destination.branch.name[/[^:]+$/]
         
     | 
| 
      
 13 
     | 
    
         
            +
                      self.build               = Build.new
         
     | 
| 
      
 14 
     | 
    
         
            +
                      self.source_object       = attributes
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    def self.create(options = {})
         
     | 
| 
      
 18 
     | 
    
         
            +
                      self.new GitReflow.git_server.connection.repos.pull_requests.create(
         
     | 
| 
      
 19 
     | 
    
         
            +
                        GitReflow.git_server.class.remote_user,
         
     | 
| 
      
 20 
     | 
    
         
            +
                        GitReflow.git_server.class.remote_repo_name,
         
     | 
| 
      
 21 
     | 
    
         
            +
                        title: options[:title],
         
     | 
| 
      
 22 
     | 
    
         
            +
                        description: options[:body] || options[:description],
         
     | 
| 
      
 23 
     | 
    
         
            +
                        source: {
         
     | 
| 
      
 24 
     | 
    
         
            +
                          branch: { name: GitReflow.git_server.class.current_branch },
         
     | 
| 
      
 25 
     | 
    
         
            +
                          repository: { full_name: "#{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}" }
         
     | 
| 
      
 26 
     | 
    
         
            +
                        },
         
     | 
| 
      
 27 
     | 
    
         
            +
                        destination: {
         
     | 
| 
      
 28 
     | 
    
         
            +
                          branch: { name: options[:base] }
         
     | 
| 
      
 29 
     | 
    
         
            +
                        },
         
     | 
| 
      
 30 
     | 
    
         
            +
                        reviewers: [username: GitReflow.git_server.class.user])
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    def self.find_open(to: 'master', from: GitReflow.git_server.class.current_branch)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 35 
     | 
    
         
            +
                        matching_pull = GitReflow.git_server.connection.repos.pull_requests.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, limit: 1).select do |pr|
         
     | 
| 
      
 36 
     | 
    
         
            +
                          pr.source.branch.name == from and
         
     | 
| 
      
 37 
     | 
    
         
            +
                          pr.destination.branch.name == to
         
     | 
| 
      
 38 
     | 
    
         
            +
                        end.first
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                        if matching_pull
         
     | 
| 
      
 41 
     | 
    
         
            +
                          self.new matching_pull
         
     | 
| 
      
 42 
     | 
    
         
            +
                        end
         
     | 
| 
      
 43 
     | 
    
         
            +
                      rescue ::BitBucket::Error::NotFound => e
         
     | 
| 
      
 44 
     | 
    
         
            +
                        GitReflow.git_server.say "No BitBucket repo found for #{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}", :error
         
     | 
| 
      
 45 
     | 
    
         
            +
                      rescue ::BitBucket::Error::Forbidden => e
         
     | 
| 
      
 46 
     | 
    
         
            +
                        GitReflow.git_server.say "You don't have API access to this repo", :error
         
     | 
| 
      
 47 
     | 
    
         
            +
                      end
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    def commit_author
         
     | 
| 
      
 51 
     | 
    
         
            +
                      # use the author of the pull request
         
     | 
| 
      
 52 
     | 
    
         
            +
                      self.author.username
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    def comments
         
     | 
| 
      
 56 
     | 
    
         
            +
                      GitReflow.git_server.connection.repos.pull_requests.comments.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    def last_comment
         
     | 
| 
      
 60 
     | 
    
         
            +
                      last_comment = comments.first
         
     | 
| 
      
 61 
     | 
    
         
            +
                      return "" unless last_comment
         
     | 
| 
      
 62 
     | 
    
         
            +
                      "#{last_comment.content.raw}"
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    def reviewers
         
     | 
| 
      
 66 
     | 
    
         
            +
                      return [] unless comments.size > 0
         
     | 
| 
      
 67 
     | 
    
         
            +
                      comments.map {|c| c.user.username }.uniq - [GitReflow.git_server.class.user]
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    def approvals
         
     | 
| 
      
 71 
     | 
    
         
            +
                      approved  = []
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                      GitReflow.git_server.connection.repos.pull_requests.activity(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id).each do |activity|
         
     | 
| 
      
 74 
     | 
    
         
            +
                        break unless activity.respond_to?(:approval) and activity.approval.user.username != GitReflow.git_server.class.user
         
     | 
| 
      
 75 
     | 
    
         
            +
                        approved |= [activity.approval.user.username]
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                      approved
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,101 +1,101 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'bitbucket_rest_api'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'git_reflow/git_helpers'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            module GitReflow
         
     | 
| 
       5 
     | 
    
         
            -
              module GitServer
         
     | 
| 
       6 
     | 
    
         
            -
                class BitBucket < Base
         
     | 
| 
       7 
     | 
    
         
            -
                  require_relative 'bit_bucket/pull_request'
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                  attr_accessor :connection
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  def initialize(config_options = {})
         
     | 
| 
       12 
     | 
    
         
            -
                    project_only = !!config_options.delete(:project_only)
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    # We remove any existing setup first, then setup our required config settings
         
     | 
| 
       15 
     | 
    
         
            -
                    GitReflow::Config.unset('reflow.local-projects', value: "#{self.class.remote_user}/#{self.class.remote_repo_name}")
         
     | 
| 
       16 
     | 
    
         
            -
                    GitReflow::Config.add('reflow.local-projects', "#{self.class.remote_user}/#{self.class.remote_repo_name}") if project_only
         
     | 
| 
       17 
     | 
    
         
            -
                    GitReflow::Config.set('reflow.git-server', 'BitBucket', local: project_only)
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  def self.connection
         
     | 
| 
       21 
     | 
    
         
            -
                    if api_key_setup?
         
     | 
| 
       22 
     | 
    
         
            -
                      @connection ||= ::BitBucket.new login: remote_user, password: api_key
         
     | 
| 
       23 
     | 
    
         
            -
                    end
         
     | 
| 
       24 
     | 
    
         
            -
                  end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  def self.api_endpoint
         
     | 
| 
       27 
     | 
    
         
            -
                    endpoint         = GitReflow::Config.get("bitbucket.endpoint", local: project_only?)
         
     | 
| 
       28 
     | 
    
         
            -
                    (endpoint.length > 0) ? endpoint : ::BitBucket::Configuration::DEFAULT_ENDPOINT
         
     | 
| 
       29 
     | 
    
         
            -
                  end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                  def self.site_url
         
     | 
| 
       32 
     | 
    
         
            -
                    site_url     = GitReflow::Config.get("bitbucket.site", local: project_only?)
         
     | 
| 
       33 
     | 
    
         
            -
                    (site_url.length > 0) ? site_url : 'https://bitbucket.org'
         
     | 
| 
       34 
     | 
    
         
            -
                  end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                  def self.api_key
         
     | 
| 
       37 
     | 
    
         
            -
                    GitReflow::Config.get("bitbucket.api-key", reload: true, local: project_only?)
         
     | 
| 
       38 
     | 
    
         
            -
                  end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  def self.api_key=(key)
         
     | 
| 
       41 
     | 
    
         
            -
                    GitReflow::Config.set("bitbucket.api-key", key, local: project_only?)
         
     | 
| 
       42 
     | 
    
         
            -
                  end
         
     | 
| 
       43 
     | 
    
         
            -
                  def self.api_key_setup?
         
     | 
| 
       44 
     | 
    
         
            -
                    (self.api_key.length > 0)
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                  def self.user
         
     | 
| 
       48 
     | 
    
         
            -
                    GitReflow::Config.get('bitbucket.user', local: project_only?)
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  def self.user=(bitbucket_user)
         
     | 
| 
       52 
     | 
    
         
            -
                    GitReflow::Config.set('bitbucket.user', bitbucket_user, local: project_only?)
         
     | 
| 
       53 
     | 
    
         
            -
                  end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                  def authenticate(options = {silent: false})
         
     | 
| 
       56 
     | 
    
         
            -
                    begin
         
     | 
| 
       57 
     | 
    
         
            -
                      if connection and self.class.api_key_setup?
         
     | 
| 
       58 
     | 
    
         
            -
                        unless options[:silent]
         
     | 
| 
       59 
     | 
    
         
            -
                          GitReflow.say "\nYour BitBucket account was already setup with:"
         
     | 
| 
       60 
     | 
    
         
            -
                          GitReflow.say "\tUser Name: #{self.class.user}"
         
     | 
| 
       61 
     | 
    
         
            -
                        end
         
     | 
| 
       62 
     | 
    
         
            -
                      else
         
     | 
| 
       63 
     | 
    
         
            -
                        self.class.user = options[:user] || ask("Please enter your BitBucket username: ")
         
     | 
| 
       64 
     | 
    
         
            -
                        GitReflow.say "\nIn order to connect your BitBucket account,"
         
     | 
| 
       65 
     | 
    
         
            -
                        GitReflow.say "you'll need to generate an API key for your team"
         
     | 
| 
       66 
     | 
    
         
            -
                        GitReflow.say "Visit #{self.class.site_url}/account/user/#{self.class.remote_user}/api-key/, to generate it\n"
         
     | 
| 
       67 
     | 
    
         
            -
                        self.class.api_key = ask("Please enter your team's API key: ")
         
     | 
| 
       68 
     | 
    
         
            -
                        connection.repos.all(self.class.remote_user).count
         
     | 
| 
       69 
     | 
    
         
            -
                        GitReflow.say "Connected to BitBucket\!", :success
         
     | 
| 
       70 
     | 
    
         
            -
                      end
         
     | 
| 
       71 
     | 
    
         
            -
                    rescue ::BitBucket::Error::Unauthorized => e
         
     | 
| 
       72 
     | 
    
         
            -
                      GitReflow::Config.unset('bitbucket.api-key', local: self.class.project_only?)
         
     | 
| 
       73 
     | 
    
         
            -
                      GitReflow.say "Invalid API key for team #{self.class.remote_user}.", :error
         
     | 
| 
       74 
     | 
    
         
            -
                    end
         
     | 
| 
       75 
     | 
    
         
            -
                  end
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                  def connection
         
     | 
| 
       78 
     | 
    
         
            -
                    @connection ||= self.class.connection
         
     | 
| 
       79 
     | 
    
         
            -
                  end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                  def get_build_status(sha)
         
     | 
| 
       82 
     | 
    
         
            -
                    # BitBucket does not currently support build status via API
         
     | 
| 
       83 
     | 
    
         
            -
                    # for updates: https://bitbucket.org/site/master/issue/8548/better-ci-integration-add-a-build-status
         
     | 
| 
       84 
     | 
    
         
            -
                    return nil
         
     | 
| 
       85 
     | 
    
         
            -
                  end
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                  def colorized_build_description(state, description)
         
     | 
| 
       88 
     | 
    
         
            -
                    ""
         
     | 
| 
       89 
     | 
    
         
            -
                  end
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                  def create_pull_request(options = {})
         
     | 
| 
       92 
     | 
    
         
            -
                    PullRequest.create(options)
         
     | 
| 
       93 
     | 
    
         
            -
                  end
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
                  def find_open_pull_request(options = {})
         
     | 
| 
       96 
     | 
    
         
            -
                    PullRequest.find_open(options)
         
     | 
| 
       97 
     | 
    
         
            -
                  end
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
                end
         
     | 
| 
       100 
     | 
    
         
            -
              end
         
     | 
| 
       101 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            require 'bitbucket_rest_api'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'git_reflow/git_helpers'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GitReflow
         
     | 
| 
      
 5 
     | 
    
         
            +
              module GitServer
         
     | 
| 
      
 6 
     | 
    
         
            +
                class BitBucket < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                  require_relative 'bit_bucket/pull_request'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  attr_accessor :connection
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(config_options = {})
         
     | 
| 
      
 12 
     | 
    
         
            +
                    project_only = !!config_options.delete(:project_only)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    # We remove any existing setup first, then setup our required config settings
         
     | 
| 
      
 15 
     | 
    
         
            +
                    GitReflow::Config.unset('reflow.local-projects', value: "#{self.class.remote_user}/#{self.class.remote_repo_name}")
         
     | 
| 
      
 16 
     | 
    
         
            +
                    GitReflow::Config.add('reflow.local-projects', "#{self.class.remote_user}/#{self.class.remote_repo_name}") if project_only
         
     | 
| 
      
 17 
     | 
    
         
            +
                    GitReflow::Config.set('reflow.git-server', 'BitBucket', local: project_only)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def self.connection
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if api_key_setup?
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @connection ||= ::BitBucket.new login: remote_user, password: api_key
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def self.api_endpoint
         
     | 
| 
      
 27 
     | 
    
         
            +
                    endpoint         = GitReflow::Config.get("bitbucket.endpoint", local: project_only?)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    (endpoint.length > 0) ? endpoint : ::BitBucket::Configuration::DEFAULT_ENDPOINT
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def self.site_url
         
     | 
| 
      
 32 
     | 
    
         
            +
                    site_url     = GitReflow::Config.get("bitbucket.site", local: project_only?)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    (site_url.length > 0) ? site_url : 'https://bitbucket.org'
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def self.api_key
         
     | 
| 
      
 37 
     | 
    
         
            +
                    GitReflow::Config.get("bitbucket.api-key", reload: true, local: project_only?)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def self.api_key=(key)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    GitReflow::Config.set("bitbucket.api-key", key, local: project_only?)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def self.api_key_setup?
         
     | 
| 
      
 44 
     | 
    
         
            +
                    (self.api_key.length > 0)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def self.user
         
     | 
| 
      
 48 
     | 
    
         
            +
                    GitReflow::Config.get('bitbucket.user', local: project_only?)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def self.user=(bitbucket_user)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    GitReflow::Config.set('bitbucket.user', bitbucket_user, local: project_only?)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  def authenticate(options = {silent: false})
         
     | 
| 
      
 56 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 57 
     | 
    
         
            +
                      if connection and self.class.api_key_setup?
         
     | 
| 
      
 58 
     | 
    
         
            +
                        unless options[:silent]
         
     | 
| 
      
 59 
     | 
    
         
            +
                          GitReflow.say "\nYour BitBucket account was already setup with:"
         
     | 
| 
      
 60 
     | 
    
         
            +
                          GitReflow.say "\tUser Name: #{self.class.user}"
         
     | 
| 
      
 61 
     | 
    
         
            +
                        end
         
     | 
| 
      
 62 
     | 
    
         
            +
                      else
         
     | 
| 
      
 63 
     | 
    
         
            +
                        self.class.user = options[:user] || ask("Please enter your BitBucket username: ")
         
     | 
| 
      
 64 
     | 
    
         
            +
                        GitReflow.say "\nIn order to connect your BitBucket account,"
         
     | 
| 
      
 65 
     | 
    
         
            +
                        GitReflow.say "you'll need to generate an API key for your team"
         
     | 
| 
      
 66 
     | 
    
         
            +
                        GitReflow.say "Visit #{self.class.site_url}/account/user/#{self.class.remote_user}/api-key/, to generate it\n"
         
     | 
| 
      
 67 
     | 
    
         
            +
                        self.class.api_key = ask("Please enter your team's API key: ")
         
     | 
| 
      
 68 
     | 
    
         
            +
                        connection.repos.all(self.class.remote_user).count
         
     | 
| 
      
 69 
     | 
    
         
            +
                        GitReflow.say "Connected to BitBucket\!", :success
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
                    rescue ::BitBucket::Error::Unauthorized => e
         
     | 
| 
      
 72 
     | 
    
         
            +
                      GitReflow::Config.unset('bitbucket.api-key', local: self.class.project_only?)
         
     | 
| 
      
 73 
     | 
    
         
            +
                      GitReflow.say "Invalid API key for team #{self.class.remote_user}.", :error
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  def connection
         
     | 
| 
      
 78 
     | 
    
         
            +
                    @connection ||= self.class.connection
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  def get_build_status(sha)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    # BitBucket does not currently support build status via API
         
     | 
| 
      
 83 
     | 
    
         
            +
                    # for updates: https://bitbucket.org/site/master/issue/8548/better-ci-integration-add-a-build-status
         
     | 
| 
      
 84 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  def colorized_build_description(state, description)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    ""
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  def create_pull_request(options = {})
         
     | 
| 
      
 92 
     | 
    
         
            +
                    PullRequest.create(options)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  def find_open_pull_request(options = {})
         
     | 
| 
      
 96 
     | 
    
         
            +
                    PullRequest.find_open(options)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -118,6 +118,9 @@ module GitReflow 
     | 
|
| 
       118 
118 
     | 
    
         | 
| 
       119 
119 
     | 
    
         
             
                          options[:body] = "#{options[:message]}\n" if options[:body].nil? and "#{options[:message]}".length > 0
         
     | 
| 
       120 
120 
     | 
    
         | 
| 
      
 121 
     | 
    
         
            +
                          merge_method   = options[:merge_method] || GitReflow::Config.get("reflow.merge-method")
         
     | 
| 
      
 122 
     | 
    
         
            +
                          merge_method   = "squash" if "#{merge_method}".length < 1
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
       121 
124 
     | 
    
         
             
                          merge_response = GitReflow::GitServer::GitHub.connection.pull_requests.merge(
         
     | 
| 
       122 
125 
     | 
    
         
             
                            "#{GitReflow.git_server.class.remote_user}",
         
     | 
| 
       123 
126 
     | 
    
         
             
                            "#{GitReflow.git_server.class.remote_repo_name}",
         
     | 
| 
         @@ -126,7 +129,7 @@ module GitReflow 
     | 
|
| 
       126 
129 
     | 
    
         
             
                              "commit_title"   => "#{options[:title]}",
         
     | 
| 
       127 
130 
     | 
    
         
             
                              "commit_message" => "#{options[:body]}",
         
     | 
| 
       128 
131 
     | 
    
         
             
                              "sha"            => "#{self.head.sha}",
         
     | 
| 
       129 
     | 
    
         
            -
                              " 
     | 
| 
      
 132 
     | 
    
         
            +
                              "merge_method"   => merge_method
         
     | 
| 
       130 
133 
     | 
    
         
             
                            }
         
     | 
| 
       131 
134 
     | 
    
         
             
                          )
         
     | 
| 
       132 
135 
     | 
    
         | 
| 
         @@ -196,11 +196,20 @@ module GitReflow 
     | 
|
| 
       196 
196 
     | 
    
         
             
                      GitReflow.update_current_branch
         
     | 
| 
       197 
197 
     | 
    
         
             
                      GitReflow.fetch_destination(self.base_branch_name)
         
     | 
| 
       198 
198 
     | 
    
         | 
| 
       199 
     | 
    
         
            -
                      message 
     | 
| 
      
 199 
     | 
    
         
            +
                      message      = commit_message_for_merge
         
     | 
| 
      
 200 
     | 
    
         
            +
                      merge_method = options[:merge_method] || GitReflow::Config.get("reflow.merge-method")
         
     | 
| 
      
 201 
     | 
    
         
            +
                      merge_method = "squash" if "#{merge_method}".length < 1
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
       200 
203 
     | 
    
         | 
| 
       201 
204 
     | 
    
         
             
                      GitReflow.run_command_with_label "git checkout #{self.base_branch_name}"
         
     | 
| 
       202 
205 
     | 
    
         
             
                      GitReflow.run_command_with_label "git pull origin #{self.base_branch_name}"
         
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                      case merge_method
         
     | 
| 
      
 208 
     | 
    
         
            +
                      when /squash/i
         
     | 
| 
      
 209 
     | 
    
         
            +
                        GitReflow.run_command_with_label "git merge --squash #{self.feature_branch_name}"
         
     | 
| 
      
 210 
     | 
    
         
            +
                      else
         
     | 
| 
      
 211 
     | 
    
         
            +
                        GitReflow.run_command_with_label "git merge #{self.feature_branch_name}"
         
     | 
| 
      
 212 
     | 
    
         
            +
                      end
         
     | 
| 
       204 
213 
     | 
    
         | 
| 
       205 
214 
     | 
    
         
             
                      GitReflow.append_to_squashed_commit_message(message) if message.length > 0
         
     | 
| 
       206 
215 
     | 
    
         | 
| 
         @@ -1,63 +1,63 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module GitReflow
         
     | 
| 
       2 
     | 
    
         
            -
              module GitServer
         
     | 
| 
       3 
     | 
    
         
            -
                autoload :Base,        'git_reflow/git_server/base'
         
     | 
| 
       4 
     | 
    
         
            -
                autoload :GitHub,      'git_reflow/git_server/git_hub'
         
     | 
| 
       5 
     | 
    
         
            -
                autoload :PullRequest, 'git_reflow/git_server/pull_request'
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
                extend self
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                class ConnectionError < StandardError; end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                def connect(options = {})
         
     | 
| 
       12 
     | 
    
         
            -
                  options ||= {}
         
     | 
| 
       13 
     | 
    
         
            -
                  options[:provider] = 'GitHub' if "#{options[:provider]}".length <= 0
         
     | 
| 
       14 
     | 
    
         
            -
                  begin
         
     | 
| 
       15 
     | 
    
         
            -
                    provider_name = options[:provider]
         
     | 
| 
       16 
     | 
    
         
            -
                    provider = provider_class_for(options.delete(:provider)).new(options)
         
     | 
| 
       17 
     | 
    
         
            -
                    provider.authenticate(options.keep_if {|key, value| key == :silent })
         
     | 
| 
       18 
     | 
    
         
            -
                    provider
         
     | 
| 
       19 
     | 
    
         
            -
                  rescue ConnectionError => e
         
     | 
| 
       20 
     | 
    
         
            -
                    GitReflow.say "Error connecting to #{provider_name}: #{e.message}", :error
         
     | 
| 
       21 
     | 
    
         
            -
                  end
         
     | 
| 
       22 
     | 
    
         
            -
                end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                def connection
         
     | 
| 
       25 
     | 
    
         
            -
                  return nil unless current_provider
         
     | 
| 
       26 
     | 
    
         
            -
                  current_provider.connection
         
     | 
| 
       27 
     | 
    
         
            -
                end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                def current_provider
         
     | 
| 
       30 
     | 
    
         
            -
                  provider = "#{GitReflow::Config.get('reflow.git-server', local: true)  || GitReflow::Config.get('reflow.git-server')}"
         
     | 
| 
       31 
     | 
    
         
            -
                  if provider.length > 0
         
     | 
| 
       32 
     | 
    
         
            -
                    begin
         
     | 
| 
       33 
     | 
    
         
            -
                      provider_class_for(provider)
         
     | 
| 
       34 
     | 
    
         
            -
                    rescue ConnectionError => e
         
     | 
| 
       35 
     | 
    
         
            -
                      GitReflow.say e.message, :error
         
     | 
| 
       36 
     | 
    
         
            -
                      nil
         
     | 
| 
       37 
     | 
    
         
            -
                    end
         
     | 
| 
       38 
     | 
    
         
            -
                  else
         
     | 
| 
       39 
     | 
    
         
            -
                    GitReflow.say "Reflow hasn't been setup yet.  Run 'git reflow setup' to continue", :notice
         
     | 
| 
       40 
     | 
    
         
            -
                    nil
         
     | 
| 
       41 
     | 
    
         
            -
                  end
         
     | 
| 
       42 
     | 
    
         
            -
                end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                def can_connect_to?(provider)
         
     | 
| 
       45 
     | 
    
         
            -
                  GitReflow::GitServer.const_defined?(provider)
         
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                def create_pull_request(options = {})
         
     | 
| 
       49 
     | 
    
         
            -
                  raise "#{self.class.to_s}#create_pull_request method must be implemented"
         
     | 
| 
       50 
     | 
    
         
            -
                end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                def find_open_pull_request(options = {})
         
     | 
| 
       53 
     | 
    
         
            -
                  raise "#{self.class.to_s}#find_open_pull_request method must be implemented"
         
     | 
| 
       54 
     | 
    
         
            -
                end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                private
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                def provider_class_for(provider)
         
     | 
| 
       59 
     | 
    
         
            -
                  raise ConnectionError, "GitServer not setup for \"#{provider}\"" unless self.can_connect_to?(provider)
         
     | 
| 
       60 
     | 
    
         
            -
                  GitReflow::GitServer.const_get(provider)
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
              end
         
     | 
| 
       63 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            module GitReflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module GitServer
         
     | 
| 
      
 3 
     | 
    
         
            +
                autoload :Base,        'git_reflow/git_server/base'
         
     | 
| 
      
 4 
     | 
    
         
            +
                autoload :GitHub,      'git_reflow/git_server/git_hub'
         
     | 
| 
      
 5 
     | 
    
         
            +
                autoload :PullRequest, 'git_reflow/git_server/pull_request'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                extend self
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                class ConnectionError < StandardError; end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def connect(options = {})
         
     | 
| 
      
 12 
     | 
    
         
            +
                  options ||= {}
         
     | 
| 
      
 13 
     | 
    
         
            +
                  options[:provider] = 'GitHub' if "#{options[:provider]}".length <= 0
         
     | 
| 
      
 14 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 15 
     | 
    
         
            +
                    provider_name = options[:provider]
         
     | 
| 
      
 16 
     | 
    
         
            +
                    provider = provider_class_for(options.delete(:provider)).new(options)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    provider.authenticate(options.keep_if {|key, value| key == :silent })
         
     | 
| 
      
 18 
     | 
    
         
            +
                    provider
         
     | 
| 
      
 19 
     | 
    
         
            +
                  rescue ConnectionError => e
         
     | 
| 
      
 20 
     | 
    
         
            +
                    GitReflow.say "Error connecting to #{provider_name}: #{e.message}", :error
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def connection
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return nil unless current_provider
         
     | 
| 
      
 26 
     | 
    
         
            +
                  current_provider.connection
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def current_provider
         
     | 
| 
      
 30 
     | 
    
         
            +
                  provider = "#{GitReflow::Config.get('reflow.git-server', local: true)  || GitReflow::Config.get('reflow.git-server')}"
         
     | 
| 
      
 31 
     | 
    
         
            +
                  if provider.length > 0
         
     | 
| 
      
 32 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 33 
     | 
    
         
            +
                      provider_class_for(provider)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    rescue ConnectionError => e
         
     | 
| 
      
 35 
     | 
    
         
            +
                      GitReflow.say e.message, :error
         
     | 
| 
      
 36 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
                  else
         
     | 
| 
      
 39 
     | 
    
         
            +
                    GitReflow.say "Reflow hasn't been setup yet.  Run 'git reflow setup' to continue", :notice
         
     | 
| 
      
 40 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def can_connect_to?(provider)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  GitReflow::GitServer.const_defined?(provider)
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def create_pull_request(options = {})
         
     | 
| 
      
 49 
     | 
    
         
            +
                  raise "#{self.class.to_s}#create_pull_request method must be implemented"
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def find_open_pull_request(options = {})
         
     | 
| 
      
 53 
     | 
    
         
            +
                  raise "#{self.class.to_s}#find_open_pull_request method must be implemented"
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                private
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def provider_class_for(provider)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  raise ConnectionError, "GitServer not setup for \"#{provider}\"" unless self.can_connect_to?(provider)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  GitReflow::GitServer.const_get(provider)
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'git_reflow/config'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'logger'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module GitReflow
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Logger < ::Logger
         
     | 
| 
      
 6 
     | 
    
         
            +
                DEFAULT_LOG_FILE = "/tmp/git-reflow.log"
         
     | 
| 
      
 7 
     | 
    
         
            +
                COLORS = {
         
     | 
| 
      
 8 
     | 
    
         
            +
                  "FATAL" => :red,
         
     | 
| 
      
 9 
     | 
    
         
            +
                  "ERROR" => :red,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  "WARN"  => :orange,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  "INFO"  => :yellow,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  "DEBUG" => :white,
         
     | 
| 
      
 13 
     | 
    
         
            +
                }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def initialize(*args)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  log_file = args.shift || log_file_path
         
     | 
| 
      
 17 
     | 
    
         
            +
                  args.unshift(log_file)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  super(*args)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @formatter = SimpleFormatter.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # Simple formatter which only displays the message.
         
     | 
| 
      
 23 
     | 
    
         
            +
                class SimpleFormatter < ::Logger::Formatter
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # This method is invoked when a log event occurs
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def call(severity, timestamp, progname, msg)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    if $stdout.tty?
         
     | 
| 
      
 27 
     | 
    
         
            +
                      "#{severity.colorize(COLORS[severity])}: #{String === msg ? msg : msg.inspect}\n"
         
     | 
| 
      
 28 
     | 
    
         
            +
                    else
         
     | 
| 
      
 29 
     | 
    
         
            +
                      "#{severity}: #{String === msg ? msg : msg.inspect}\n"
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                private
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def log_file_path
         
     | 
| 
      
 37 
     | 
    
         
            +
                  return @log_file_path if "#{@log_file_path}".length > 0
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  configured_log_file_path = GitReflow::Config.get('reflow.log_file_path')
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  if configured_log_file_path.length > 0
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @log_file_path = configured_log_file_path
         
     | 
| 
      
 43 
     | 
    
         
            +
                  else
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @log_file_path = DEFAULT_LOG_FILE
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,9 +1,9 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module GitReflow
         
     | 
| 
       2 
     | 
    
         
            -
              module GitServer
         
     | 
| 
       3 
     | 
    
         
            -
                class MergeError < StandardError
         
     | 
| 
       4 
     | 
    
         
            -
                  def initialize(msg="Merge failed")
         
     | 
| 
       5 
     | 
    
         
            -
                    super(msg)
         
     | 
| 
       6 
     | 
    
         
            -
                  end
         
     | 
| 
       7 
     | 
    
         
            -
                end
         
     | 
| 
       8 
     | 
    
         
            -
              end
         
     | 
| 
       9 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            module GitReflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module GitServer
         
     | 
| 
      
 3 
     | 
    
         
            +
                class MergeError < StandardError
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(msg="Merge failed")
         
     | 
| 
      
 5 
     | 
    
         
            +
                    super(msg)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,23 +1,23 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Thanks to http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on
         
     | 
| 
       2 
     | 
    
         
            -
            # and to Thoughtbot: https://github.com/thoughtbot/cocaine/blob/master/lib/cocaine/os_detector.rb
         
     | 
| 
       3 
     | 
    
         
            -
            module GitReflow
         
     | 
| 
       4 
     | 
    
         
            -
              class OSDetector
         
     | 
| 
       5 
     | 
    
         
            -
                def windows?
         
     | 
| 
       6 
     | 
    
         
            -
                  (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
         
     | 
| 
       7 
     | 
    
         
            -
                end
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                def mac?
         
     | 
| 
       10 
     | 
    
         
            -
                  (/darwin/ =~ RUBY_PLATFORM) != nil
         
     | 
| 
       11 
     | 
    
         
            -
                end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                def unix?
         
     | 
| 
       14 
     | 
    
         
            -
                  !OS.windows?
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                def linux?
         
     | 
| 
       18 
     | 
    
         
            -
                  OS.unix? and not OS.mac?
         
     | 
| 
       19 
     | 
    
         
            -
                end
         
     | 
| 
       20 
     | 
    
         
            -
              end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
              OS = OSDetector.new
         
     | 
| 
       23 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            # Thanks to http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on
         
     | 
| 
      
 2 
     | 
    
         
            +
            # and to Thoughtbot: https://github.com/thoughtbot/cocaine/blob/master/lib/cocaine/os_detector.rb
         
     | 
| 
      
 3 
     | 
    
         
            +
            module GitReflow
         
     | 
| 
      
 4 
     | 
    
         
            +
              class OSDetector
         
     | 
| 
      
 5 
     | 
    
         
            +
                def windows?
         
     | 
| 
      
 6 
     | 
    
         
            +
                  (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def mac?
         
     | 
| 
      
 10 
     | 
    
         
            +
                  (/darwin/ =~ RUBY_PLATFORM) != nil
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def unix?
         
     | 
| 
      
 14 
     | 
    
         
            +
                  !OS.windows?
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def linux?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  OS.unix? and not OS.mac?
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              OS = OSDetector.new
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     |