geet 0.3.15 → 0.3.16
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/.travis.yml +6 -0
- data/bin/geet +7 -0
- data/geet.gemspec +1 -1
- data/lib/geet/commandline/commands.rb +1 -0
- data/lib/geet/commandline/configuration.rb +5 -0
- data/lib/geet/git/repository.rb +4 -0
- data/lib/geet/github/milestone.rb +13 -0
- data/lib/geet/services/close_milestones.rb +46 -0
- data/lib/geet/services/create_issue.rb +5 -3
- data/lib/geet/services/create_pr.rb +5 -3
- data/lib/geet/services/list_issues.rb +4 -1
- data/lib/geet/services/merge_pr.rb +55 -4
- data/lib/geet/shared/branches.rb +9 -0
- data/lib/geet/shared/selection.rb +3 -0
- data/lib/geet/utils/attributes_selection_manager.rb +5 -3
- data/lib/geet/utils/git_client.rb +61 -11
- data/lib/geet/version.rb +1 -1
- data/spec/integration/merge_pr_spec.rb +26 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15603a9a3a61fd8b6c3a377bd8fb1f482c121078b153e0cb8f3bdf12609d01f2
|
4
|
+
data.tar.gz: cde2b52ebcc17f2af2e64466c5565a65fad846e946747d91dfd734e5ce108e2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ea5d57a2f25a0f83910afe316194d335f11d04b4228324ab577845a74b62331705b3650b654cdb951e69c6fa76438441e1fa1caa3bf431e456acefc39f4457d
|
7
|
+
data.tar.gz: 06c954789d0e39cb723daa45de62c190817773cad1c29d1719524452c98731ded5f0cce8f72450f677c54688c38636b21538eca04226dafb45b00d16ab548806
|
data/.travis.yml
CHANGED
@@ -5,6 +5,12 @@ rvm:
|
|
5
5
|
- 2.4
|
6
6
|
- 2.5
|
7
7
|
- 2.6
|
8
|
+
- 2.7
|
9
|
+
- ruby-head
|
10
|
+
matrix:
|
11
|
+
fast_finish: true
|
12
|
+
allow_failures:
|
13
|
+
- rvm: ruby-head
|
8
14
|
# API tokens are always required, but not used in testing, since no requests are actually made.
|
9
15
|
env:
|
10
16
|
- GITHUB_API_TOKEN=phony GITLAB_API_TOKEN=phony
|
data/bin/geet
CHANGED
@@ -46,6 +46,13 @@ class GeetLauncher
|
|
46
46
|
Services::ListIssues.new(repository).execute(options)
|
47
47
|
when LABEL_LIST_COMMAND
|
48
48
|
Services::ListLabels.new(repository).execute
|
49
|
+
when MILESTONE_CLOSE_COMMAND
|
50
|
+
# Don't support user selection. This requires extra complexity, specifically, matching by number
|
51
|
+
# while displaying the titles (see AttributesSelectionManager).
|
52
|
+
#
|
53
|
+
options = {numbers: Shared::Selection::MANUAL_LIST_SELECTION_FLAG}
|
54
|
+
|
55
|
+
Services::CloseMilestones.new(repository).execute(options)
|
49
56
|
when MILESTONE_CREATE_COMMAND
|
50
57
|
title = options.delete(:title)
|
51
58
|
|
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 = '
|
13
|
+
s.date = '2020-11-16'
|
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'
|
@@ -8,6 +8,7 @@ module Geet
|
|
8
8
|
LABEL_CREATE_COMMAND = 'label.create'
|
9
9
|
ISSUE_LIST_COMMAND = 'issue.list'
|
10
10
|
LABEL_LIST_COMMAND = 'label.list'
|
11
|
+
MILESTONE_CLOSE_COMMAND = 'milestone.close'
|
11
12
|
MILESTONE_CREATE_COMMAND = 'milestone.create'
|
12
13
|
MILESTONE_LIST_COMMAND = 'milestone.list'
|
13
14
|
PR_COMMENT_COMMAND = 'pr.comment'
|
@@ -45,6 +45,10 @@ module Geet
|
|
45
45
|
['-u', '--upstream', 'List on the upstream repository'],
|
46
46
|
].freeze
|
47
47
|
|
48
|
+
MILESTONE_CLOSE_OPTIONS = [
|
49
|
+
long_help: 'Close milestones.'
|
50
|
+
]
|
51
|
+
|
48
52
|
MILESTONE_CREATE_OPTIONS = [
|
49
53
|
'title',
|
50
54
|
long_help: 'Create a milestone.'
|
@@ -109,6 +113,7 @@ module Geet
|
|
109
113
|
'list' => LABEL_LIST_OPTIONS,
|
110
114
|
},
|
111
115
|
'milestone' => {
|
116
|
+
'close' => MILESTONE_CLOSE_OPTIONS,
|
112
117
|
'create' => MILESTONE_CREATE_OPTIONS,
|
113
118
|
'list' => MILESTONE_LIST_OPTIONS,
|
114
119
|
},
|
data/lib/geet/git/repository.rb
CHANGED
@@ -70,6 +70,10 @@ module Geet
|
|
70
70
|
attempt_provider_call(:Milestone, :list, api_interface)
|
71
71
|
end
|
72
72
|
|
73
|
+
def close_milestone(number)
|
74
|
+
attempt_provider_call(:Milestone, :close, number, api_interface)
|
75
|
+
end
|
76
|
+
|
73
77
|
def create_pr(title, description, head, base: nil)
|
74
78
|
confirm(LOCAL_ACTION_ON_UPSTREAM_REPOSITORY_MESSAGE) if local_action_on_upstream_repository? && @warnings
|
75
79
|
confirm(ACTION_ON_PROTECTED_REPOSITORY_MESSAGE) if action_on_protected_repository? && @warnings
|
@@ -7,6 +7,8 @@ module Geet
|
|
7
7
|
class Milestone
|
8
8
|
attr_reader :number, :title, :due_on
|
9
9
|
|
10
|
+
STATE_CLOSED = 'closed'
|
11
|
+
|
10
12
|
class << self
|
11
13
|
private
|
12
14
|
|
@@ -64,6 +66,17 @@ module Geet
|
|
64
66
|
new(number, title, due_on, api_interface)
|
65
67
|
end
|
66
68
|
end
|
69
|
+
|
70
|
+
# See https://docs.github.com/en/free-pro-team@latest/rest/reference/issues#update-a-milestone
|
71
|
+
#
|
72
|
+
# This is a convenience method; the underlying operation is a generic update.
|
73
|
+
#
|
74
|
+
def self.close(number, api_interface)
|
75
|
+
api_path = "milestones/#{number}"
|
76
|
+
request_data = { state: STATE_CLOSED }
|
77
|
+
|
78
|
+
api_interface.send_request(api_path, data: request_data)
|
79
|
+
end
|
67
80
|
end
|
68
81
|
end
|
69
82
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../shared/selection'
|
4
|
+
|
5
|
+
module Geet
|
6
|
+
module Services
|
7
|
+
class CloseMilestones
|
8
|
+
include Geet::Shared::Selection
|
9
|
+
|
10
|
+
def initialize(repository, out: $stdout)
|
11
|
+
@repository = repository
|
12
|
+
@out = out
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute(numbers: nil)
|
16
|
+
numbers = find_and_select_milestone_numbers(numbers)
|
17
|
+
|
18
|
+
close_milestone_threads = close_milestones(numbers)
|
19
|
+
|
20
|
+
close_milestone_threads.each(&:join)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def find_and_select_milestone_numbers(numbers)
|
26
|
+
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
27
|
+
|
28
|
+
selection_manager.add_attribute(:milestones, 'milestone', numbers, SELECTION_MULTIPLE, name_method: :title)
|
29
|
+
|
30
|
+
milestones = selection_manager.select_attributes[0]
|
31
|
+
|
32
|
+
milestones.map(&:number)
|
33
|
+
end
|
34
|
+
|
35
|
+
def close_milestones(numbers)
|
36
|
+
@out.puts "Closing milestones #{numbers.join(', ')}..."
|
37
|
+
|
38
|
+
numbers.map do |number|
|
39
|
+
Thread.new do
|
40
|
+
@repository.close_milestone(number)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end # CloseMilestones
|
45
|
+
end # Services
|
46
|
+
end # Geet
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative 'abstract_create_issue'
|
4
4
|
require_relative '../shared/repo_permissions'
|
5
|
+
require_relative '../shared/selection'
|
5
6
|
|
6
7
|
module Geet
|
7
8
|
module Services
|
8
9
|
class CreateIssue < AbstractCreateIssue
|
9
10
|
include Geet::Shared::RepoPermissions
|
11
|
+
include Geet::Shared::Selection
|
10
12
|
|
11
13
|
# options:
|
12
14
|
# :labels
|
@@ -56,9 +58,9 @@ module Geet
|
|
56
58
|
def find_and_select_attributes(labels, milestone, assignees)
|
57
59
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
58
60
|
|
59
|
-
selection_manager.add_attribute(:labels, 'label', labels,
|
60
|
-
selection_manager.add_attribute(:milestones, 'milestone', milestone,
|
61
|
-
selection_manager.add_attribute(:collaborators, 'assignee', assignees,
|
61
|
+
selection_manager.add_attribute(:labels, 'label', labels, SELECTION_MULTIPLE, name_method: :name) if labels
|
62
|
+
selection_manager.add_attribute(:milestones, 'milestone', milestone, SELECTION_SINGLE, name_method: :title) if milestone
|
63
|
+
selection_manager.add_attribute(:collaborators, 'assignee', assignees, SELECTION_MULTIPLE, name_method: :username) if assignees
|
62
64
|
|
63
65
|
selection_manager.select_attributes
|
64
66
|
end
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative 'abstract_create_issue'
|
4
4
|
require_relative '../shared/repo_permissions'
|
5
|
+
require_relative '../shared/selection'
|
5
6
|
|
6
7
|
module Geet
|
7
8
|
module Services
|
8
9
|
class CreatePr < AbstractCreateIssue
|
9
10
|
include Geet::Shared::RepoPermissions
|
11
|
+
include Geet::Shared::Selection
|
10
12
|
|
11
13
|
DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
|
12
14
|
|
@@ -66,11 +68,11 @@ module Geet
|
|
66
68
|
def find_and_select_attributes(labels, milestone, reviewers)
|
67
69
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
68
70
|
|
69
|
-
selection_manager.add_attribute(:labels, 'label', labels,
|
70
|
-
selection_manager.add_attribute(:milestones, 'milestone', milestone,
|
71
|
+
selection_manager.add_attribute(:labels, 'label', labels, SELECTION_MULTIPLE, name_method: :name) if labels
|
72
|
+
selection_manager.add_attribute(:milestones, 'milestone', milestone, SELECTION_SINGLE, name_method: :title) if milestone
|
71
73
|
|
72
74
|
if reviewers
|
73
|
-
selection_manager.add_attribute(:collaborators, 'reviewer', reviewers,
|
75
|
+
selection_manager.add_attribute(:collaborators, 'reviewer', reviewers, SELECTION_MULTIPLE, name_method: :username) do |all_reviewers|
|
74
76
|
authenticated_user = @repository.authenticated_user
|
75
77
|
all_reviewers.delete_if { |reviewer| reviewer.username == authenticated_user.username }
|
76
78
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../utils/attributes_selection_manager'
|
4
|
+
require_relative '../shared/selection'
|
4
5
|
|
5
6
|
module Geet
|
6
7
|
module Services
|
7
8
|
class ListIssues
|
9
|
+
include Geet::Shared::Selection
|
10
|
+
|
8
11
|
def initialize(repository, out: $stdout)
|
9
12
|
@repository = repository
|
10
13
|
@out = out
|
@@ -25,7 +28,7 @@ module Geet
|
|
25
28
|
def find_and_select_attributes(assignee)
|
26
29
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
27
30
|
|
28
|
-
selection_manager.add_attribute(:collaborators, 'assignee', assignee,
|
31
|
+
selection_manager.add_attribute(:collaborators, 'assignee', assignee, SELECTION_SINGLE, name_method: :username)
|
29
32
|
|
30
33
|
selection_manager.select_attributes[0]
|
31
34
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../helpers/services_workflow_helper'
|
4
|
+
require_relative '../shared/branches'
|
4
5
|
|
5
6
|
module Geet
|
6
7
|
module Services
|
@@ -12,6 +13,7 @@ module Geet
|
|
12
13
|
#
|
13
14
|
class MergePr
|
14
15
|
include Geet::Helpers::ServicesWorkflowHelper
|
16
|
+
include Geet::Shared::Branches
|
15
17
|
|
16
18
|
DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
|
17
19
|
|
@@ -24,8 +26,29 @@ module Geet
|
|
24
26
|
def execute(delete_branch: false)
|
25
27
|
merge_owner, merge_head = find_merge_head
|
26
28
|
pr = checked_find_branch_pr(merge_owner, merge_head)
|
29
|
+
|
27
30
|
merge_pr(pr)
|
28
|
-
|
31
|
+
|
32
|
+
if delete_branch
|
33
|
+
branch = @git_client.current_branch
|
34
|
+
|
35
|
+
delete_remote_branch(branch)
|
36
|
+
end
|
37
|
+
|
38
|
+
fetch_repository
|
39
|
+
|
40
|
+
if upstream_branch_gone?
|
41
|
+
pr_branch = @git_client.current_branch
|
42
|
+
|
43
|
+
# The rebase could also be placed after the branch deletion. There are pros/cons;
|
44
|
+
# currently, it's not important.
|
45
|
+
#
|
46
|
+
checkout_branch(MAIN_BRANCH)
|
47
|
+
rebase
|
48
|
+
|
49
|
+
delete_local_branch(pr_branch)
|
50
|
+
end
|
51
|
+
|
29
52
|
pr
|
30
53
|
end
|
31
54
|
|
@@ -37,10 +60,38 @@ module Geet
|
|
37
60
|
pr.merge
|
38
61
|
end
|
39
62
|
|
40
|
-
def
|
41
|
-
@out.puts "Deleting branch #{
|
63
|
+
def delete_remote_branch(branch)
|
64
|
+
@out.puts "Deleting remote branch #{branch}..."
|
65
|
+
|
66
|
+
@repository.delete_branch(branch)
|
67
|
+
end
|
68
|
+
|
69
|
+
def fetch_repository
|
70
|
+
@out.puts "Fetching repository..."
|
71
|
+
|
72
|
+
@git_client.fetch
|
73
|
+
end
|
74
|
+
|
75
|
+
def upstream_branch_gone?
|
76
|
+
@git_client.upstream_branch_gone?
|
77
|
+
end
|
78
|
+
|
79
|
+
def checkout_branch(branch)
|
80
|
+
@out.puts "Checking out #{branch}..."
|
81
|
+
|
82
|
+
@git_client.checkout(branch)
|
83
|
+
end
|
84
|
+
|
85
|
+
def rebase
|
86
|
+
@out.puts "Rebasing..."
|
87
|
+
|
88
|
+
@git_client.rebase
|
89
|
+
end
|
90
|
+
|
91
|
+
def delete_local_branch(branch)
|
92
|
+
@out.puts "Deleting local branch #{branch}..."
|
42
93
|
|
43
|
-
@
|
94
|
+
@git_client.delete_branch(branch)
|
44
95
|
end
|
45
96
|
end
|
46
97
|
end
|
@@ -30,8 +30,10 @@ module Geet
|
|
30
30
|
@selections_data = []
|
31
31
|
end
|
32
32
|
|
33
|
+
# selection_type: SELECTION_SINGLE or SELECTION_MULTIPLE
|
34
|
+
#
|
33
35
|
def add_attribute(repository_call, description, pattern, selection_type, name_method: nil, &pre_selection_hook)
|
34
|
-
raise "Unrecognized selection type #{selection_type.inspect}" if ![
|
36
|
+
raise "Unrecognized selection type #{selection_type.inspect}" if ![SELECTION_SINGLE, SELECTION_MULTIPLE].include?(selection_type)
|
35
37
|
|
36
38
|
finder_thread = find_attribute_entries(repository_call)
|
37
39
|
|
@@ -47,9 +49,9 @@ module Geet
|
|
47
49
|
entries = pre_selection_hook.(entries) if pre_selection_hook
|
48
50
|
|
49
51
|
case selection_type
|
50
|
-
when
|
52
|
+
when SELECTION_SINGLE
|
51
53
|
select_entry(description, entries, pattern, name_method)
|
52
|
-
when
|
54
|
+
when SELECTION_MULTIPLE
|
53
55
|
select_entries(description, entries, pattern, name_method)
|
54
56
|
end
|
55
57
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'English'
|
3
4
|
require 'shellwords'
|
4
5
|
require_relative '../helpers/os_helper'
|
5
6
|
|
@@ -38,13 +39,13 @@ module Geet
|
|
38
39
|
# (which start with `-`)
|
39
40
|
#
|
40
41
|
def cherry(limit)
|
41
|
-
raw_commits =
|
42
|
+
raw_commits = execute_git_command("cherry #{limit.shellescape}")
|
42
43
|
|
43
44
|
raw_commits.split("\n").grep(/^\+/).map { |line| line[3..-1] }
|
44
45
|
end
|
45
46
|
|
46
47
|
def current_branch
|
47
|
-
branch =
|
48
|
+
branch = execute_git_command("rev-parse --abbrev-ref HEAD")
|
48
49
|
|
49
50
|
raise "Couldn't find current branch" if branch == 'HEAD'
|
50
51
|
|
@@ -53,12 +54,14 @@ module Geet
|
|
53
54
|
|
54
55
|
# Not to be confused with `upstream` repository!
|
55
56
|
#
|
57
|
+
# This API doesn't reveal if the remote branch is gone.
|
58
|
+
#
|
56
59
|
# return: nil, if the upstream branch is not configured.
|
57
60
|
#
|
58
61
|
def upstream_branch
|
59
|
-
head_symbolic_ref =
|
62
|
+
head_symbolic_ref = execute_git_command("symbolic-ref -q HEAD")
|
60
63
|
|
61
|
-
raw_upstream_branch =
|
64
|
+
raw_upstream_branch = execute_git_command("for-each-ref --format='%(upstream:short)' #{head_symbolic_ref.shellescape}").strip
|
62
65
|
|
63
66
|
if raw_upstream_branch != ''
|
64
67
|
raw_upstream_branch[UPSTREAM_BRANCH_REGEX, 1] || raise("Unexpected upstream format: #{raw_upstream_branch}")
|
@@ -67,8 +70,30 @@ module Geet
|
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
73
|
+
# TODO: May be merged with :upstream_branch, although it would require designing how a gone
|
74
|
+
# remote branch is expressed.
|
75
|
+
#
|
76
|
+
# Sample command output:
|
77
|
+
#
|
78
|
+
# ## add_milestone_closing...origin/add_milestone_closing [gone]
|
79
|
+
# M spec/integration/merge_pr_spec.rb
|
80
|
+
#
|
81
|
+
def upstream_branch_gone?
|
82
|
+
git_command = "status -b --porcelain"
|
83
|
+
status_output = execute_git_command(git_command)
|
84
|
+
|
85
|
+
# Simplified branch naming pattern. The exact one (see https://stackoverflow.com/a/3651867)
|
86
|
+
# is not worth implementing.
|
87
|
+
#
|
88
|
+
if status_output =~ %r(^## .+\.\.\..+?( \[gone\])?$)
|
89
|
+
!!$LAST_MATCH_INFO[1]
|
90
|
+
else
|
91
|
+
raise "Unexpected git command #{git_command.inspect} output: #{status_output}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
70
95
|
def working_tree_clean?
|
71
|
-
git_message =
|
96
|
+
git_message = execute_git_command("status")
|
72
97
|
|
73
98
|
!!(git_message =~ CLEAN_TREE_MESSAGE_REGEX)
|
74
99
|
end
|
@@ -80,7 +105,7 @@ module Geet
|
|
80
105
|
# Show the description ("<subject>\n\n<body>") for the given git object.
|
81
106
|
#
|
82
107
|
def show_description(object)
|
83
|
-
|
108
|
+
execute_git_command("show --quiet --format='%s\n\n%b' #{object.shellescape}")
|
84
109
|
end
|
85
110
|
|
86
111
|
##########################################################################
|
@@ -117,7 +142,7 @@ module Geet
|
|
117
142
|
# The result is in the format `git@github.com:donaldduck/geet.git`
|
118
143
|
#
|
119
144
|
def remote(name)
|
120
|
-
remote_url =
|
145
|
+
remote_url = execute_git_command("ls-remote --get-url #{name}")
|
121
146
|
|
122
147
|
if remote_url == name
|
123
148
|
raise "Remote #{name.inspect} not found!"
|
@@ -132,7 +157,7 @@ module Geet
|
|
132
157
|
# purposes, any any action that needs to work with the remote, uses #remote.
|
133
158
|
#
|
134
159
|
def remote_defined?(name)
|
135
|
-
remote_url =
|
160
|
+
remote_url = execute_git_command("ls-remote --get-url #{name}")
|
136
161
|
|
137
162
|
# If the remote is not define, `git ls-remote` will return the passed value.
|
138
163
|
remote_url != name
|
@@ -142,12 +167,32 @@ module Geet
|
|
142
167
|
# OPERATION APIS
|
143
168
|
##########################################################################
|
144
169
|
|
170
|
+
def checkout(branch)
|
171
|
+
execute_git_command("checkout #{branch.shellescape}")
|
172
|
+
end
|
173
|
+
|
174
|
+
# Unforced deletion.
|
175
|
+
#
|
176
|
+
def delete_branch(branch)
|
177
|
+
execute_git_command("branch --delete #{branch.shellescape}")
|
178
|
+
end
|
179
|
+
|
180
|
+
def rebase
|
181
|
+
execute_git_command("rebase")
|
182
|
+
end
|
183
|
+
|
145
184
|
# upstream_branch: create an upstream branch.
|
146
185
|
#
|
147
186
|
def push(upstream_branch: nil)
|
148
187
|
upstream_branch_option = "-u origin #{upstream_branch.shellescape}" if upstream_branch
|
149
188
|
|
150
|
-
|
189
|
+
execute_git_command("push #{upstream_branch_option}")
|
190
|
+
end
|
191
|
+
|
192
|
+
# Performs pruning.
|
193
|
+
#
|
194
|
+
def fetch
|
195
|
+
execute_git_command("fetch --prune")
|
151
196
|
end
|
152
197
|
|
153
198
|
##########################################################################
|
@@ -156,8 +201,13 @@ module Geet
|
|
156
201
|
|
157
202
|
private
|
158
203
|
|
159
|
-
|
160
|
-
|
204
|
+
# If executing a git command without calling this API, don't forget to split `gitdir_option`
|
205
|
+
# and use it!
|
206
|
+
#
|
207
|
+
def execute_git_command(command)
|
208
|
+
gitdir_option = "-C #{@location.shellescape}" if @location
|
209
|
+
|
210
|
+
execute_command("git #{gitdir_option} #{command}")
|
161
211
|
end
|
162
212
|
end
|
163
213
|
end
|
data/lib/geet/version.rb
CHANGED
@@ -5,12 +5,25 @@ require 'spec_helper'
|
|
5
5
|
require_relative '../../lib/geet/git/repository'
|
6
6
|
require_relative '../../lib/geet/services/merge_pr'
|
7
7
|
|
8
|
+
# Currently disabled: it requires updates following the addition of the automatic removal of the local
|
9
|
+
# branch.
|
10
|
+
# Specifically, `GitClient#upstream_branch_gone?` needs to be handled, since it returns the current
|
11
|
+
# branch, while it's supposed to return
|
12
|
+
#
|
8
13
|
describe Geet::Services::MergePr do
|
9
14
|
let(:git_client) { Geet::Utils::GitClient.new }
|
10
15
|
let(:repository) { Geet::Git::Repository.new(git_client: git_client) }
|
11
16
|
let(:owner) { 'donaldduck' }
|
12
17
|
let(:branch) { 'mybranch' }
|
13
18
|
|
19
|
+
before :each do
|
20
|
+
expect(git_client).to receive(:fetch)
|
21
|
+
expect(git_client).to receive(:upstream_branch_gone?).and_return(true)
|
22
|
+
expect(git_client).to receive(:checkout).with('master')
|
23
|
+
expect(git_client).to receive(:rebase)
|
24
|
+
expect(git_client).to receive(:delete_branch).with('mybranch')
|
25
|
+
end
|
26
|
+
|
14
27
|
context 'with github.com' do
|
15
28
|
let(:repository_name) { 'testrepo_upstream' }
|
16
29
|
|
@@ -22,6 +35,10 @@ describe Geet::Services::MergePr do
|
|
22
35
|
expected_output = <<~STR
|
23
36
|
Finding PR with head (#{owner}:#{branch})...
|
24
37
|
Merging PR ##{expected_pr_number}...
|
38
|
+
Fetching repository...
|
39
|
+
Checking out master...
|
40
|
+
Rebasing...
|
41
|
+
Deleting local branch mybranch...
|
25
42
|
STR
|
26
43
|
|
27
44
|
actual_output = StringIO.new
|
@@ -44,7 +61,11 @@ describe Geet::Services::MergePr do
|
|
44
61
|
expected_output = <<~STR
|
45
62
|
Finding PR with head (#{owner}:#{branch})...
|
46
63
|
Merging PR ##{expected_pr_number}...
|
47
|
-
Deleting branch #{branch}...
|
64
|
+
Deleting remote branch #{branch}...
|
65
|
+
Fetching repository...
|
66
|
+
Checking out master...
|
67
|
+
Rebasing...
|
68
|
+
Deleting local branch mybranch...
|
48
69
|
STR
|
49
70
|
|
50
71
|
actual_output = StringIO.new
|
@@ -71,6 +92,10 @@ describe Geet::Services::MergePr do
|
|
71
92
|
expected_output = <<~STR
|
72
93
|
Finding PR with head (#{owner}:#{branch})...
|
73
94
|
Merging PR ##{expected_pr_number}...
|
95
|
+
Fetching repository...
|
96
|
+
Checking out master...
|
97
|
+
Rebasing...
|
98
|
+
Deleting local branch mybranch...
|
74
99
|
STR
|
75
100
|
|
76
101
|
actual_output = StringIO.new
|
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.3.
|
4
|
+
version: 0.3.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Saverio Miroddi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simple_scripting
|
@@ -101,6 +101,7 @@ files:
|
|
101
101
|
- lib/geet/helpers/summary_helper.rb
|
102
102
|
- lib/geet/resources/templates/edit_summary.md
|
103
103
|
- lib/geet/services/abstract_create_issue.rb
|
104
|
+
- lib/geet/services/close_milestones.rb
|
104
105
|
- lib/geet/services/comment_pr.rb
|
105
106
|
- lib/geet/services/create_gist.rb
|
106
107
|
- lib/geet/services/create_issue.rb
|
@@ -113,6 +114,7 @@ files:
|
|
113
114
|
- lib/geet/services/list_prs.rb
|
114
115
|
- lib/geet/services/merge_pr.rb
|
115
116
|
- lib/geet/services/open_pr.rb
|
117
|
+
- lib/geet/shared/branches.rb
|
116
118
|
- lib/geet/shared/http_error.rb
|
117
119
|
- lib/geet/shared/repo_permissions.rb
|
118
120
|
- lib/geet/shared/selection.rb
|
@@ -185,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
187
|
- !ruby/object:Gem::Version
|
186
188
|
version: '0'
|
187
189
|
requirements: []
|
188
|
-
rubygems_version: 3.0.
|
190
|
+
rubygems_version: 3.0.8
|
189
191
|
signing_key:
|
190
192
|
specification_version: 4
|
191
193
|
summary: Commandline interface for performing SCM host operations, eg. create a PR
|