geet 0.4.1 → 0.4.2
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/geet.gemspec +1 -1
- data/lib/geet/commandline/configuration.rb +1 -0
- data/lib/geet/github/abstract_issue.rb +3 -0
- data/lib/geet/github/pr.rb +26 -6
- data/lib/geet/helpers/services_workflow_helper.rb +9 -7
- data/lib/geet/services/comment_pr.rb +1 -2
- data/lib/geet/services/create_pr.rb +7 -7
- data/lib/geet/services/merge_pr.rb +4 -5
- data/lib/geet/services/open_pr.rb +2 -3
- data/lib/geet/utils/git_client.rb +12 -14
- data/lib/geet/version.rb +1 -1
- data/spec/integration/create_pr_spec.rb +7 -7
- data/spec/integration/merge_pr_spec.rb +2 -2
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c13aed62c61e4cdaf20931f657c101daee30925b36a9b87fcce3b86d009d3c69
         | 
| 4 | 
            +
              data.tar.gz: 5f13669499214cb7b13d96f05a25547a19a472e9d855e6d58967f5ce3ba3d138
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 8cb5a717299f16140d7ce1506d0bba549b87d97e4405f1d32549ea519ba58ccb2e918ce0561ecf714fcc2d3660f1172890c6fee99fc53270216b6656c730e7b9
         | 
| 7 | 
            +
              data.tar.gz: 7ad452d8d32f8e96b853925aa745ad7664a4dd14cd97754ea6ab47627718938bb8af03e52eb4db28e425d96605bff83de74332a196d79845fd78baa870cbeef9
         | 
    
        data/geet.gemspec
    CHANGED
    
    | @@ -10,7 +10,7 @@ Gem::Specification.new do |s| | |
| 10 10 | 
             
              s.platform    = Gem::Platform::RUBY
         | 
| 11 11 | 
             
              s.required_ruby_version = '>= 2.3.0'
         | 
| 12 12 | 
             
              s.authors     = ['Saverio Miroddi']
         | 
| 13 | 
            -
              s.date        = '2021-07- | 
| 13 | 
            +
              s.date        = '2021-07-26'
         | 
| 14 14 | 
             
              s.email       = ['saverio.pub2@gmail.com']
         | 
| 15 15 | 
             
              s.homepage    = 'https://github.com/saveriomiroddi/geet'
         | 
| 16 16 | 
             
              s.summary     = 'Commandline interface for performing SCM host operations, eg. create a PR on GitHub'
         | 
| @@ -22,6 +22,9 @@ module Geet | |
| 22 22 |  | 
| 23 23 | 
             
                  # See https://developer.github.com/v3/issues/#list-issues-for-a-repository
         | 
| 24 24 | 
             
                  #
         | 
| 25 | 
            +
                  # This works both for Issues and PRs, however, when the `/pulls` API (path) is used, additional
         | 
| 26 | 
            +
                  # information is provided (e.g. `head`).
         | 
| 27 | 
            +
                  #
         | 
| 25 28 | 
             
                  def self.list(api_interface, milestone: nil, assignee: nil, &type_filter)
         | 
| 26 29 | 
             
                    api_path = 'issues'
         | 
| 27 30 |  | 
    
        data/lib/geet/github/pr.rb
    CHANGED
    
    | @@ -32,14 +32,34 @@ module Geet | |
| 32 32 |  | 
| 33 33 | 
             
                    if head
         | 
| 34 34 | 
             
                      api_path = 'pulls'
         | 
| 35 | 
            -
                      request_params = { head: "#{owner}:#{head}" }
         | 
| 36 35 |  | 
| 37 | 
            -
                       | 
| 36 | 
            +
                      # Technically, the upstream approach could be used for both, but it's actually good to have
         | 
| 37 | 
            +
                      # both of them as reference.
         | 
| 38 | 
            +
                      #
         | 
| 39 | 
            +
                      # For upstream pulls, the owner is the authenticated user, otherwise, the repository owner.
         | 
| 40 | 
            +
                      #
         | 
| 41 | 
            +
                      response = if api_interface.upstream?
         | 
| 42 | 
            +
                        unfiltered_response = api_interface.send_request(api_path, multipage: true)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                        # VERY weird. From the docs, it's not clear if the user/org is required in the `head` parameter,
         | 
| 45 | 
            +
                        # but:
         | 
| 46 | 
            +
                        #
         | 
| 47 | 
            +
                        # - if it isn't included (eg. `anything`), the parameter is ignored
         | 
| 48 | 
            +
                        # - if it's included (eg. `saveriomiroddi:local_branch_name`), an empty resultset is returned.
         | 
| 49 | 
            +
                        #
         | 
| 50 | 
            +
                        # For this reason, we can't use that param, and have to filter manually.
         | 
| 51 | 
            +
                        #
         | 
| 52 | 
            +
                        unfiltered_response.select { |pr_data| pr_data.fetch('head').fetch('label') == "#{owner}:#{head}" }
         | 
| 53 | 
            +
                      else
         | 
| 54 | 
            +
                        request_params = { head: "#{owner}:#{head}" }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                        api_interface.send_request(api_path, params: request_params, multipage: true)
         | 
| 57 | 
            +
                      end
         | 
| 38 58 |  | 
| 39 | 
            -
                      response.map do | | 
| 40 | 
            -
                        number =  | 
| 41 | 
            -
                        title =  | 
| 42 | 
            -
                        link =  | 
| 59 | 
            +
                      response.map do |pr_data|
         | 
| 60 | 
            +
                        number = pr_data.fetch('number')
         | 
| 61 | 
            +
                        title = pr_data.fetch('title')
         | 
| 62 | 
            +
                        link = pr_data.fetch('html_url')
         | 
| 43 63 |  | 
| 44 64 | 
             
                        new(number, api_interface, title, link)
         | 
| 45 65 | 
             
                      end
         | 
| @@ -9,17 +9,19 @@ module Geet | |
| 9 9 | 
             
                # Helper for services common workflow, for example, find the merge head.
         | 
| 10 10 | 
             
                #
         | 
| 11 11 | 
             
                module ServicesWorkflowHelper
         | 
| 12 | 
            -
                  # Requires: @git_client
         | 
| 13 | 
            -
                  #
         | 
| 14 | 
            -
                  def find_merge_head
         | 
| 15 | 
            -
                    [@git_client.owner, @git_client.current_branch]
         | 
| 16 | 
            -
                  end
         | 
| 17 | 
            -
             | 
| 18 12 | 
             
                  # Expect to find only one.
         | 
| 19 13 | 
             
                  #
         | 
| 20 14 | 
             
                  # Requires: @out, @repository.
         | 
| 21 15 | 
             
                  #
         | 
| 22 | 
            -
                  def checked_find_branch_pr | 
| 16 | 
            +
                  def checked_find_branch_pr
         | 
| 17 | 
            +
                    owner = if @repository.upstream?
         | 
| 18 | 
            +
                      @repository.authenticated_user.username
         | 
| 19 | 
            +
                    else
         | 
| 20 | 
            +
                      @git_client.owner
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    head = @git_client.current_branch
         | 
| 24 | 
            +
             | 
| 23 25 | 
             
                    @out.puts "Finding PR with head (#{owner}:#{head})..."
         | 
| 24 26 |  | 
| 25 27 | 
             
                    prs = @repository.prs(owner: owner, head: head)
         | 
| @@ -20,8 +20,7 @@ module Geet | |
| 20 20 | 
             
                  end
         | 
| 21 21 |  | 
| 22 22 | 
             
                  def execute(comment, no_open_pr: nil)
         | 
| 23 | 
            -
                     | 
| 24 | 
            -
                    pr = checked_find_branch_pr(merge_owner, merge_head)
         | 
| 23 | 
            +
                    pr = checked_find_branch_pr
         | 
| 25 24 | 
             
                    pr.comment(comment)
         | 
| 26 25 | 
             
                    open_file_with_default_application(pr.link) unless no_open_pr
         | 
| 27 26 | 
             
                    pr
         | 
| @@ -37,7 +37,7 @@ module Geet | |
| 37 37 | 
             
                      selected_labels, selected_milestone, selected_reviewers = find_and_select_attributes(labels, milestone, reviewers)
         | 
| 38 38 | 
             
                    end
         | 
| 39 39 |  | 
| 40 | 
            -
                     | 
| 40 | 
            +
                    sync_with_remote_branch if automated_mode
         | 
| 41 41 |  | 
| 42 42 | 
             
                    pr = create_pr(title, description, base: base, draft: draft)
         | 
| 43 43 |  | 
| @@ -81,17 +81,17 @@ module Geet | |
| 81 81 | 
             
                    selection_manager.select_attributes
         | 
| 82 82 | 
             
                  end
         | 
| 83 83 |  | 
| 84 | 
            -
                  def  | 
| 85 | 
            -
                    if @git_client. | 
| 86 | 
            -
                      @out.puts "Pushing to  | 
| 84 | 
            +
                  def sync_with_remote_branch
         | 
| 85 | 
            +
                    if @git_client.remote_branch
         | 
| 86 | 
            +
                      @out.puts "Pushing to remote branch..."
         | 
| 87 87 |  | 
| 88 88 | 
             
                      @git_client.push
         | 
| 89 89 | 
             
                    else
         | 
| 90 | 
            -
                       | 
| 90 | 
            +
                      remote_branch = @git_client.current_branch
         | 
| 91 91 |  | 
| 92 | 
            -
                      @out.puts "Creating  | 
| 92 | 
            +
                      @out.puts "Creating remote branch #{remote_branch.inspect}..."
         | 
| 93 93 |  | 
| 94 | 
            -
                      @git_client.push( | 
| 94 | 
            +
                      @git_client.push(remote_branch: remote_branch)
         | 
| 95 95 | 
             
                    end
         | 
| 96 96 | 
             
                  end
         | 
| 97 97 |  | 
| @@ -23,8 +23,7 @@ module Geet | |
| 23 23 | 
             
                  end
         | 
| 24 24 |  | 
| 25 25 | 
             
                  def execute(delete_branch: false)
         | 
| 26 | 
            -
                     | 
| 27 | 
            -
                    pr = checked_find_branch_pr(merge_owner, merge_head)
         | 
| 26 | 
            +
                    pr = checked_find_branch_pr
         | 
| 28 27 |  | 
| 29 28 | 
             
                    merge_pr(pr)
         | 
| 30 29 |  | 
| @@ -36,7 +35,7 @@ module Geet | |
| 36 35 |  | 
| 37 36 | 
             
                    fetch_repository
         | 
| 38 37 |  | 
| 39 | 
            -
                    if  | 
| 38 | 
            +
                    if remote_branch_gone?
         | 
| 40 39 | 
             
                      pr_branch = @git_client.current_branch
         | 
| 41 40 | 
             
                      main_branch = @git_client.main_branch
         | 
| 42 41 |  | 
| @@ -72,8 +71,8 @@ module Geet | |
| 72 71 | 
             
                    @git_client.fetch
         | 
| 73 72 | 
             
                  end
         | 
| 74 73 |  | 
| 75 | 
            -
                  def  | 
| 76 | 
            -
                    @git_client. | 
| 74 | 
            +
                  def remote_branch_gone?
         | 
| 75 | 
            +
                    @git_client.remote_branch_gone?
         | 
| 77 76 | 
             
                  end
         | 
| 78 77 |  | 
| 79 78 | 
             
                  def checkout_branch(branch)
         | 
| @@ -19,9 +19,8 @@ module Geet | |
| 19 19 | 
             
                    @git_client = git_client
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 |  | 
| 22 | 
            -
                  def execute(delete_branch: false)
         | 
| 23 | 
            -
                     | 
| 24 | 
            -
                    pr = checked_find_branch_pr(merge_owner, merge_head)
         | 
| 22 | 
            +
                  def execute(delete_branch: false, **)
         | 
| 23 | 
            +
                    pr = checked_find_branch_pr
         | 
| 25 24 | 
             
                    open_file_with_default_application(pr.link)
         | 
| 26 25 | 
             
                    pr
         | 
| 27 26 | 
             
                  end
         | 
| @@ -34,7 +34,7 @@ module Geet | |
| 34 34 | 
             
                    \Z
         | 
| 35 35 | 
             
                  }x
         | 
| 36 36 |  | 
| 37 | 
            -
                   | 
| 37 | 
            +
                  REMOTE_BRANCH_REGEX = %r{\A[^/]+/(.+)\Z}
         | 
| 38 38 |  | 
| 39 39 | 
             
                  MAIN_BRANCH_CONFIG_ENTRY = 'custom.development-branch'
         | 
| 40 40 |  | 
| @@ -65,25 +65,23 @@ module Geet | |
| 65 65 | 
             
                    branch
         | 
| 66 66 | 
             
                  end
         | 
| 67 67 |  | 
| 68 | 
            -
                  # Not to be confused with `upstream` repository!
         | 
| 69 | 
            -
                  #
         | 
| 70 68 | 
             
                  # This API doesn't reveal if the remote branch is gone.
         | 
| 71 69 | 
             
                  #
         | 
| 72 | 
            -
                  # return: nil, if the  | 
| 70 | 
            +
                  # return: nil, if the remote branch is not configured.
         | 
| 73 71 | 
             
                  #
         | 
| 74 | 
            -
                  def  | 
| 72 | 
            +
                  def remote_branch
         | 
| 75 73 | 
             
                    head_symbolic_ref = execute_git_command("symbolic-ref -q HEAD")
         | 
| 76 74 |  | 
| 77 | 
            -
                     | 
| 75 | 
            +
                    raw_remote_branch = execute_git_command("for-each-ref --format='%(upstream:short)' #{head_symbolic_ref.shellescape}").strip
         | 
| 78 76 |  | 
| 79 | 
            -
                    if  | 
| 80 | 
            -
                       | 
| 77 | 
            +
                    if raw_remote_branch != ''
         | 
| 78 | 
            +
                      raw_remote_branch[REMOTE_BRANCH_REGEX, 1] || raise("Unexpected remote branch format: #{raw_remote_branch}")
         | 
| 81 79 | 
             
                    else
         | 
| 82 80 | 
             
                      nil
         | 
| 83 81 | 
             
                    end
         | 
| 84 82 | 
             
                  end
         | 
| 85 83 |  | 
| 86 | 
            -
                  # TODO: May be merged with : | 
| 84 | 
            +
                  # TODO: May be merged with :remote_branch, although it would require designing how a gone
         | 
| 87 85 | 
             
                  # remote branch is expressed.
         | 
| 88 86 | 
             
                  #
         | 
| 89 87 | 
             
                  # Sample command output:
         | 
| @@ -91,7 +89,7 @@ module Geet | |
| 91 89 | 
             
                  #     ## add_milestone_closing...origin/add_milestone_closing [gone]
         | 
| 92 90 | 
             
                  #      M spec/integration/merge_pr_spec.rb
         | 
| 93 91 | 
             
                  #
         | 
| 94 | 
            -
                  def  | 
| 92 | 
            +
                  def remote_branch_gone?
         | 
| 95 93 | 
             
                    git_command = "status -b --porcelain"
         | 
| 96 94 | 
             
                    status_output = execute_git_command(git_command)
         | 
| 97 95 |  | 
| @@ -216,12 +214,12 @@ module Geet | |
| 216 214 | 
             
                    execute_git_command("rebase")
         | 
| 217 215 | 
             
                  end
         | 
| 218 216 |  | 
| 219 | 
            -
                  #  | 
| 217 | 
            +
                  # remote_branch: create an upstream branch.
         | 
| 220 218 | 
             
                  #
         | 
| 221 | 
            -
                  def push( | 
| 222 | 
            -
                     | 
| 219 | 
            +
                  def push(remote_branch: nil)
         | 
| 220 | 
            +
                    remote_branch_option = "-u #{ORIGIN_NAME} #{remote_branch.shellescape}" if remote_branch
         | 
| 223 221 |  | 
| 224 | 
            -
                    execute_git_command("push #{ | 
| 222 | 
            +
                    execute_git_command("push #{remote_branch_option}")
         | 
| 225 223 | 
             
                  end
         | 
| 226 224 |  | 
| 227 225 | 
             
                  # Performs pruning.
         | 
    
        data/lib/geet/version.rb
    CHANGED
    
    
| @@ -133,17 +133,17 @@ describe Geet::Services::CreatePr do | |
| 133 133 | 
             
                    expect(actual_output.string).to eql(expected_output)
         | 
| 134 134 | 
             
                  end
         | 
| 135 135 |  | 
| 136 | 
            -
                  it 'should push to the  | 
| 136 | 
            +
                  it 'should push to the remote branch' do
         | 
| 137 137 | 
             
                    allow(git_client).to receive(:working_tree_clean?).and_return(true)
         | 
| 138 138 | 
             
                    allow(git_client).to receive(:current_branch).and_return('mybranch')
         | 
| 139 139 | 
             
                    allow(git_client).to receive(:main_branch).and_return('master')
         | 
| 140 | 
            -
                    expect(git_client).to receive(: | 
| 140 | 
            +
                    expect(git_client).to receive(:remote_branch).and_return('mybranch')
         | 
| 141 141 | 
             
                    expect(git_client).to receive(:push)
         | 
| 142 142 |  | 
| 143 143 | 
             
                    allow(git_client).to receive(:remote).with(no_args).and_return('git@github.com:donaldduck/testrepo_f')
         | 
| 144 144 |  | 
| 145 145 | 
             
                    expected_output = <<~STR
         | 
| 146 | 
            -
                      Pushing to  | 
| 146 | 
            +
                      Pushing to remote branch...
         | 
| 147 147 | 
             
                      Creating PR...
         | 
| 148 148 | 
             
                      Assigning authenticated user...
         | 
| 149 149 | 
             
                      PR address: https://github.com/donaldduck/testrepo_f/pull/2
         | 
| @@ -159,17 +159,17 @@ describe Geet::Services::CreatePr do | |
| 159 159 | 
             
                    expect(actual_output.string).to eql(expected_output)
         | 
| 160 160 | 
             
                  end
         | 
| 161 161 |  | 
| 162 | 
            -
                  it "should create  | 
| 162 | 
            +
                  it "should create a remote branch, when there isn't one (is not tracked)" do
         | 
| 163 163 | 
             
                    allow(git_client).to receive(:working_tree_clean?).and_return(true)
         | 
| 164 164 | 
             
                    allow(git_client).to receive(:current_branch).and_return('mybranch')
         | 
| 165 165 | 
             
                    allow(git_client).to receive(:main_branch).and_return('master')
         | 
| 166 | 
            -
                    expect(git_client).to receive(: | 
| 167 | 
            -
                    expect(git_client).to receive(:push).with( | 
| 166 | 
            +
                    expect(git_client).to receive(:remote_branch).and_return(nil)
         | 
| 167 | 
            +
                    expect(git_client).to receive(:push).with(remote_branch: 'mybranch')
         | 
| 168 168 |  | 
| 169 169 | 
             
                    allow(git_client).to receive(:remote).with(no_args).and_return('git@github.com:donaldduck/testrepo_f')
         | 
| 170 170 |  | 
| 171 171 | 
             
                    expected_output = <<~STR
         | 
| 172 | 
            -
                      Creating  | 
| 172 | 
            +
                      Creating remote branch "mybranch"...
         | 
| 173 173 | 
             
                      Creating PR...
         | 
| 174 174 | 
             
                      Assigning authenticated user...
         | 
| 175 175 | 
             
                      PR address: https://github.com/donaldduck/testrepo_f/pull/4
         | 
| @@ -7,7 +7,7 @@ require_relative '../../lib/geet/services/merge_pr' | |
| 7 7 |  | 
| 8 8 | 
             
            # Currently disabled: it requires updates following the addition of the automatic removal of the local
         | 
| 9 9 | 
             
            # branch.
         | 
| 10 | 
            -
            # Specifically, `GitClient# | 
| 10 | 
            +
            # Specifically, `GitClient#remote_branch_gone?` needs to be handled, since it returns the current
         | 
| 11 11 | 
             
            # branch, while it's supposed to return
         | 
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            describe Geet::Services::MergePr do
         | 
| @@ -19,7 +19,7 @@ describe Geet::Services::MergePr do | |
| 19 19 |  | 
| 20 20 | 
             
              before :each do
         | 
| 21 21 | 
             
                expect(git_client).to receive(:fetch)
         | 
| 22 | 
            -
                expect(git_client).to receive(: | 
| 22 | 
            +
                expect(git_client).to receive(:remote_branch_gone?).and_return(true)
         | 
| 23 23 | 
             
                expect(git_client).to receive(:checkout).with(main_branch)
         | 
| 24 24 | 
             
                expect(git_client).to receive(:rebase)
         | 
| 25 25 | 
             
                expect(git_client).to receive(:delete_branch).with('mybranch')
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: geet
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.4. | 
| 4 | 
            +
              version: 0.4.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Saverio Miroddi
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021-07- | 
| 11 | 
            +
            date: 2021-07-26 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: simple_scripting
         | 
| @@ -190,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 190 190 | 
             
                - !ruby/object:Gem::Version
         | 
| 191 191 | 
             
                  version: '0'
         | 
| 192 192 | 
             
            requirements: []
         | 
| 193 | 
            -
            rubygems_version: 3. | 
| 193 | 
            +
            rubygems_version: 3.2.22
         | 
| 194 194 | 
             
            signing_key: 
         | 
| 195 195 | 
             
            specification_version: 4
         | 
| 196 196 | 
             
            summary: Commandline interface for performing SCM host operations, eg. create a PR
         |