geet 0.27.2 → 0.27.3
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/.rubocop.yml +7 -0
- data/Gemfile +9 -9
- data/Rakefile +2 -2
- data/bin/geet +7 -7
- data/geet.gemspec +19 -19
- data/lib/geet/commandline/commands.rb +16 -15
- data/lib/geet/commandline/configuration.rb +96 -92
- data/lib/geet/commandline/editor.rb +13 -7
- data/lib/geet/git/repository.rb +75 -6
- data/lib/geet/github/abstract_issue.rb +4 -4
- data/lib/geet/github/api_interface.rb +23 -23
- data/lib/geet/github/gist.rb +8 -8
- data/lib/geet/github/issue.rb +5 -5
- data/lib/geet/github/label.rb +4 -4
- data/lib/geet/github/milestone.rb +8 -8
- data/lib/geet/github/pr.rb +20 -20
- data/lib/geet/github/remote_repository.rb +1 -1
- data/lib/geet/github/user.rb +5 -5
- data/lib/geet/gitlab/api_interface.rb +13 -13
- data/lib/geet/gitlab/issue.rb +3 -3
- data/lib/geet/gitlab/label.rb +3 -3
- data/lib/geet/gitlab/milestone.rb +4 -4
- data/lib/geet/gitlab/pr.rb +3 -3
- data/lib/geet/gitlab/user.rb +2 -2
- data/lib/geet/helpers/json_helper.rb +1 -1
- data/lib/geet/helpers/os_helper.rb +5 -5
- data/lib/geet/helpers/services_workflow_helper.rb +4 -4
- data/lib/geet/services/abstract_create_issue.rb +3 -3
- data/lib/geet/services/add_upstream_repo.rb +1 -1
- data/lib/geet/services/close_milestones.rb +9 -2
- data/lib/geet/services/comment_pr.rb +11 -0
- data/lib/geet/services/create_gist.rb +18 -4
- data/lib/geet/services/create_issue.rb +13 -7
- data/lib/geet/services/create_label.rb +22 -3
- data/lib/geet/services/create_milestone.rb +7 -1
- data/lib/geet/services/create_pr.rb +98 -23
- data/lib/geet/services/list_issues.rb +4 -3
- data/lib/geet/services/list_labels.rb +7 -0
- data/lib/geet/services/list_milestones.rb +35 -6
- data/lib/geet/services/list_prs.rb +7 -0
- data/lib/geet/services/merge_pr.rb +20 -2
- data/lib/geet/services/open_pr.rb +2 -2
- data/lib/geet/services/open_repo.rb +7 -1
- data/lib/geet/shared/repo_permissions.rb +4 -4
- data/lib/geet/shared/selection.rb +2 -2
- data/lib/geet/utils/attributes_selection_manager.rb +30 -10
- data/lib/geet/utils/git_client.rb +74 -33
- data/lib/geet/utils/manual_list_selection.rb +23 -11
- data/lib/geet/utils/string_matching_selection.rb +22 -6
- data/lib/geet/version.rb +2 -1
- data/lib/geet.rb +2 -2
- data/spec/integration/comment_pr_spec.rb +10 -10
- data/spec/integration/create_gist_spec.rb +12 -12
- data/spec/integration/create_issue_spec.rb +21 -21
- data/spec/integration/create_label_spec.rb +33 -33
- data/spec/integration/create_milestone_spec.rb +9 -9
- data/spec/integration/create_pr_spec.rb +120 -134
- data/spec/integration/list_issues_spec.rb +25 -25
- data/spec/integration/list_labels_spec.rb +15 -15
- data/spec/integration/list_milestones_spec.rb +15 -15
- data/spec/integration/list_prs_spec.rb +10 -10
- data/spec/integration/merge_pr_spec.rb +18 -18
- data/spec/integration/open_pr_spec.rb +18 -20
- data/spec/integration/open_repo_spec.rb +18 -18
- data/spec/spec_helper.rb +10 -10
- data/spec/unit/github/pr_spec.rb +73 -73
- metadata +3 -3
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# typed:
|
|
2
|
+
# typed: strict
|
|
3
3
|
|
|
4
|
-
require
|
|
4
|
+
require "io/console" # stdlib
|
|
5
5
|
|
|
6
6
|
module Geet
|
|
7
7
|
module Services
|
|
8
8
|
class CreatePr < AbstractCreateIssue
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
9
11
|
include Geet::Shared::RepoPermissions
|
|
10
12
|
include Geet::Shared::Selection
|
|
11
13
|
|
|
12
14
|
DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
|
|
13
15
|
|
|
16
|
+
sig {
|
|
17
|
+
params(
|
|
18
|
+
repository: Git::Repository,
|
|
19
|
+
out: IO,
|
|
20
|
+
git_client: Utils::GitClient
|
|
21
|
+
).void
|
|
22
|
+
}
|
|
14
23
|
def initialize(repository, out: $stdout, git_client: DEFAULT_GIT_CLIENT)
|
|
15
24
|
super(repository)
|
|
16
25
|
@git_client = git_client
|
|
17
26
|
@out = out
|
|
18
27
|
end
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
sig {
|
|
30
|
+
params(
|
|
31
|
+
title: String,
|
|
32
|
+
description: String,
|
|
33
|
+
labels: T.nilable(String),
|
|
34
|
+
milestone: T.nilable(String),
|
|
35
|
+
reviewers: T.nilable(String),
|
|
36
|
+
base: T.nilable(String),
|
|
37
|
+
draft: T::Boolean,
|
|
38
|
+
open_browser: T::Boolean,
|
|
39
|
+
automerge: T::Boolean
|
|
40
|
+
).returns(T.any(Github::PR, Gitlab::PR))
|
|
41
|
+
}
|
|
26
42
|
def execute(
|
|
27
43
|
title, description, labels: nil, milestone: nil, reviewers: nil,
|
|
28
44
|
base: nil, draft: false, open_browser: false, automerge: false
|
|
@@ -66,29 +82,47 @@ module Geet
|
|
|
66
82
|
|
|
67
83
|
# Internal actions
|
|
68
84
|
|
|
85
|
+
sig { void }
|
|
69
86
|
def ensure_clean_tree
|
|
70
|
-
raise
|
|
87
|
+
raise "The working tree is not clean!" if !@git_client.working_tree_clean?
|
|
71
88
|
end
|
|
72
89
|
|
|
90
|
+
sig {
|
|
91
|
+
params(
|
|
92
|
+
labels: T.nilable(String),
|
|
93
|
+
milestone: T.nilable(String),
|
|
94
|
+
reviewers: T.nilable(String)
|
|
95
|
+
).returns([
|
|
96
|
+
T.nilable(T::Array[T.any(Github::Label, Gitlab::Label)]),
|
|
97
|
+
T.nilable(T.any(Github::Milestone, Gitlab::Milestone)),
|
|
98
|
+
T.nilable(T::Array[T.any(Github::User, Gitlab::User)]),
|
|
99
|
+
])
|
|
100
|
+
}
|
|
73
101
|
def find_and_select_attributes(labels, milestone, reviewers)
|
|
74
102
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
|
75
103
|
|
|
76
|
-
selection_manager.add_attribute(:labels,
|
|
77
|
-
selection_manager.add_attribute(:milestones,
|
|
104
|
+
selection_manager.add_attribute(:labels, "label", labels, SELECTION_MULTIPLE, name_method: :name) if labels
|
|
105
|
+
selection_manager.add_attribute(:milestones, "milestone", milestone, SELECTION_SINGLE, name_method: :title) if milestone
|
|
78
106
|
|
|
79
107
|
if reviewers
|
|
80
|
-
selection_manager.add_attribute(:collaborators,
|
|
108
|
+
selection_manager.add_attribute(:collaborators, "reviewer", reviewers, SELECTION_MULTIPLE, name_method: :username) do |all_reviewers|
|
|
81
109
|
authenticated_user = @repository.authenticated_user
|
|
82
|
-
|
|
110
|
+
reviewers_typed = T.cast(all_reviewers, T::Array[Github::User])
|
|
111
|
+
reviewers_typed.delete_if { |reviewer| reviewer.username == authenticated_user.username }
|
|
83
112
|
end
|
|
84
113
|
end
|
|
85
114
|
|
|
86
|
-
selection_manager.select_attributes
|
|
115
|
+
selected_attributes = selection_manager.select_attributes
|
|
116
|
+
|
|
117
|
+
selected_labels = T.cast(selected_attributes.shift, T.nilable(T::Array[Github::Label])) if labels
|
|
118
|
+
selected_milestone = T.cast(selected_attributes.shift, T.nilable(Github::Milestone)) if milestone
|
|
119
|
+
selected_reviewers = T.cast(selected_attributes.shift, T.nilable(T::Array[Github::User])) if reviewers
|
|
120
|
+
|
|
121
|
+
[selected_labels, selected_milestone, selected_reviewers]
|
|
87
122
|
end
|
|
88
123
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def sync_with_remote_branch(input: T.untyped)
|
|
124
|
+
sig { void }
|
|
125
|
+
def sync_with_remote_branch
|
|
92
126
|
# Fetching doesn't have a real world case when there isn't a remote branch. It's also not generally
|
|
93
127
|
# useful when there is a remote branch, however, since a force push is an option, it's important
|
|
94
128
|
# to be 100% sure of the current diff.
|
|
@@ -98,6 +132,8 @@ module Geet
|
|
|
98
132
|
|
|
99
133
|
@git_client.fetch
|
|
100
134
|
|
|
135
|
+
input = T.let("", String)
|
|
136
|
+
|
|
101
137
|
if !@git_client.remote_branch_diff_commits.empty?
|
|
102
138
|
while true
|
|
103
139
|
@out.print "The local and remote branches differ! Force push (Y/D/Q*)?"
|
|
@@ -105,14 +141,14 @@ module Geet
|
|
|
105
141
|
@out.puts
|
|
106
142
|
|
|
107
143
|
case input.downcase
|
|
108
|
-
when
|
|
144
|
+
when "y"
|
|
109
145
|
@git_client.push(force: true)
|
|
110
146
|
break
|
|
111
|
-
when
|
|
147
|
+
when "d"
|
|
112
148
|
@out.puts "# DIFF: ########################################################################"
|
|
113
149
|
@out.puts @git_client.remote_branch_diff
|
|
114
150
|
@out.puts "################################################################################"
|
|
115
|
-
when
|
|
151
|
+
when "q"
|
|
116
152
|
exit(1)
|
|
117
153
|
end
|
|
118
154
|
end
|
|
@@ -134,7 +170,7 @@ module Geet
|
|
|
134
170
|
@out.puts
|
|
135
171
|
|
|
136
172
|
case input.downcase.rstrip
|
|
137
|
-
when
|
|
173
|
+
when "n", ""
|
|
138
174
|
# exit the cycle
|
|
139
175
|
else
|
|
140
176
|
retry
|
|
@@ -143,14 +179,30 @@ module Geet
|
|
|
143
179
|
end
|
|
144
180
|
end
|
|
145
181
|
|
|
182
|
+
sig {
|
|
183
|
+
params(
|
|
184
|
+
title: String,
|
|
185
|
+
description: String,
|
|
186
|
+
base: T.nilable(String),
|
|
187
|
+
draft: T::Boolean
|
|
188
|
+
).returns(T.any(Github::PR, Gitlab::PR))
|
|
189
|
+
}
|
|
146
190
|
def create_pr(title, description, base:, draft:)
|
|
147
|
-
@out.puts
|
|
191
|
+
@out.puts "Creating PR..."
|
|
148
192
|
|
|
149
193
|
base ||= @git_client.main_branch
|
|
150
194
|
|
|
151
195
|
@repository.create_pr(title, description, @git_client.current_branch, base, draft)
|
|
152
196
|
end
|
|
153
197
|
|
|
198
|
+
sig {
|
|
199
|
+
params(
|
|
200
|
+
pr: T.any(Github::PR, Gitlab::PR),
|
|
201
|
+
labels: T.nilable(T::Array[T.any(Github::Label, Gitlab::Label)]),
|
|
202
|
+
milestone: T.nilable(T.any(Github::Milestone, Gitlab::Milestone)),
|
|
203
|
+
reviewers: T.nilable(T::Array[T.any(Github::User, Gitlab::User)])
|
|
204
|
+
).void
|
|
205
|
+
}
|
|
154
206
|
def edit_pr(pr, labels, milestone, reviewers)
|
|
155
207
|
# labels/reviewers can be nil (parameter not passed) or empty array (parameter passed, but
|
|
156
208
|
# nothing selected)
|
|
@@ -163,10 +215,16 @@ module Geet
|
|
|
163
215
|
request_review_thread&.join
|
|
164
216
|
end
|
|
165
217
|
|
|
218
|
+
sig {
|
|
219
|
+
params(
|
|
220
|
+
pr: T.any(Github::PR, Gitlab::PR),
|
|
221
|
+
selected_labels: T::Array[T.any(Github::Label, Gitlab::Label)]
|
|
222
|
+
).returns(Thread)
|
|
223
|
+
}
|
|
166
224
|
def add_labels(pr, selected_labels)
|
|
167
225
|
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
168
226
|
|
|
169
|
-
labels_list = selected_labels.map(&:name).join(
|
|
227
|
+
labels_list = selected_labels.map(&:name).join(", ")
|
|
170
228
|
|
|
171
229
|
@out.puts "Adding labels #{labels_list}..."
|
|
172
230
|
|
|
@@ -175,6 +233,12 @@ module Geet
|
|
|
175
233
|
end
|
|
176
234
|
end
|
|
177
235
|
|
|
236
|
+
sig {
|
|
237
|
+
params(
|
|
238
|
+
pr: T.any(Github::PR, Gitlab::PR),
|
|
239
|
+
milestone: T.any(Github::Milestone, Gitlab::Milestone)
|
|
240
|
+
).returns(Thread)
|
|
241
|
+
}
|
|
178
242
|
def set_milestone(pr, milestone)
|
|
179
243
|
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
180
244
|
|
|
@@ -185,6 +249,12 @@ module Geet
|
|
|
185
249
|
end
|
|
186
250
|
end
|
|
187
251
|
|
|
252
|
+
sig {
|
|
253
|
+
params(
|
|
254
|
+
pr: T.any(Github::PR, Gitlab::PR),
|
|
255
|
+
reviewers: T::Array[T.any(Github::User, Gitlab::User)]
|
|
256
|
+
).returns(Thread)
|
|
257
|
+
}
|
|
188
258
|
def request_review(pr, reviewers)
|
|
189
259
|
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
190
260
|
|
|
@@ -197,6 +267,11 @@ module Geet
|
|
|
197
267
|
end
|
|
198
268
|
end
|
|
199
269
|
|
|
270
|
+
sig {
|
|
271
|
+
params(
|
|
272
|
+
pr: T.any(Github::PR, Gitlab::PR)
|
|
273
|
+
).void
|
|
274
|
+
}
|
|
200
275
|
def enable_automerge(pr)
|
|
201
276
|
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
202
277
|
|
|
@@ -22,7 +22,8 @@ module Geet
|
|
|
22
22
|
sig {
|
|
23
23
|
params(
|
|
24
24
|
assignee: T.nilable(String)
|
|
25
|
-
)
|
|
25
|
+
)
|
|
26
|
+
.returns(T.any(T::Array[Github::AbstractIssue], T::Array[Gitlab::Issue]))
|
|
26
27
|
}
|
|
27
28
|
def execute(assignee: nil)
|
|
28
29
|
selected_assignee = find_and_select_attributes(assignee) if assignee
|
|
@@ -44,9 +45,9 @@ module Geet
|
|
|
44
45
|
def find_and_select_attributes(assignee)
|
|
45
46
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
|
46
47
|
|
|
47
|
-
selection_manager.add_attribute(:collaborators,
|
|
48
|
+
selection_manager.add_attribute(:collaborators, "assignee", assignee, SELECTION_SINGLE, name_method: :username)
|
|
48
49
|
|
|
49
|
-
selection_manager.select_attributes[0]
|
|
50
|
+
T.cast(selection_manager.select_attributes[0], T.any(Github::User, Gitlab::User))
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
end
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
class ListLabels
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
9
|
+
sig { params(repository: Git::Repository, out: T.any(IO, StringIO)).void }
|
|
6
10
|
def initialize(repository, out: $stdout)
|
|
7
11
|
@repository = repository
|
|
8
12
|
@out = out
|
|
9
13
|
end
|
|
10
14
|
|
|
15
|
+
sig {
|
|
16
|
+
returns(T::Array[T.any(Github::Label, Gitlab::Label)])
|
|
17
|
+
}
|
|
11
18
|
def execute
|
|
12
19
|
labels = @repository.labels
|
|
13
20
|
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
class ListMilestones
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
9
|
+
sig {
|
|
10
|
+
params(
|
|
11
|
+
repository: Git::Repository,
|
|
12
|
+
out: T.any(IO, StringIO)
|
|
13
|
+
).void
|
|
14
|
+
}
|
|
6
15
|
def initialize(repository, out: $stdout)
|
|
7
16
|
@repository = repository
|
|
8
17
|
@out = out
|
|
9
18
|
end
|
|
10
19
|
|
|
20
|
+
sig {
|
|
21
|
+
returns(T::Array[T.any(Github::Milestone, Gitlab::Milestone)])
|
|
22
|
+
}
|
|
11
23
|
def execute
|
|
12
24
|
milestones = find_milestones
|
|
13
25
|
all_milestone_entries = find_all_milestone_entries(milestones)
|
|
@@ -33,24 +45,41 @@ module Geet
|
|
|
33
45
|
|
|
34
46
|
# Not included in the Milestone class because descriptions (which will be customizable)
|
|
35
47
|
# are considered formatters, conceptually external to the class.
|
|
48
|
+
sig {
|
|
49
|
+
params(
|
|
50
|
+
milestone: T.any(Github::Milestone, Gitlab::Milestone)
|
|
51
|
+
).returns(String)
|
|
52
|
+
}
|
|
36
53
|
def milestone_description(milestone)
|
|
37
54
|
description = "#{milestone.number}. #{milestone.title}"
|
|
38
55
|
description += " (due #{milestone.due_on})" if milestone.due_on
|
|
39
56
|
description
|
|
40
57
|
end
|
|
41
58
|
|
|
59
|
+
sig {
|
|
60
|
+
returns(T::Array[T.any(Github::Milestone, Gitlab::Milestone)])
|
|
61
|
+
}
|
|
42
62
|
def find_milestones
|
|
43
|
-
@out.puts
|
|
63
|
+
@out.puts "Finding milestones..."
|
|
44
64
|
|
|
45
65
|
@repository.milestones
|
|
46
66
|
end
|
|
47
67
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
sig {
|
|
69
|
+
params(
|
|
70
|
+
milestones: T::Array[T.any(Github::Milestone, Gitlab::Milestone)]
|
|
71
|
+
).returns(
|
|
72
|
+
T::Hash[
|
|
73
|
+
T.any(Github::Milestone, Gitlab::Milestone),
|
|
74
|
+
{
|
|
75
|
+
issues: T::Array[T.any(Github::Issue, Gitlab::Issue)],
|
|
76
|
+
prs: T::Array[T.any(Github::PR, Gitlab::PR)],
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
}
|
|
52
81
|
def find_all_milestone_entries(milestones)
|
|
53
|
-
@out.puts
|
|
82
|
+
@out.puts "Finding issues and PRs..."
|
|
54
83
|
|
|
55
84
|
all_milestone_entries = {}
|
|
56
85
|
all_threads = []
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
class ListPrs
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
9
|
+
sig { params(repository: Git::Repository, out: T.any(IO, StringIO)).void }
|
|
6
10
|
def initialize(repository, out: $stdout)
|
|
7
11
|
@repository = repository
|
|
8
12
|
@out = out
|
|
9
13
|
end
|
|
10
14
|
|
|
15
|
+
sig {
|
|
16
|
+
returns(T::Array[T.any(Github::PR, Gitlab::PR)])
|
|
17
|
+
}
|
|
11
18
|
def execute
|
|
12
19
|
prs = @repository.prs
|
|
13
20
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
@@ -9,19 +10,29 @@ module Geet
|
|
|
9
10
|
# constraints, but speeds up the workflow.
|
|
10
11
|
#
|
|
11
12
|
class MergePr
|
|
13
|
+
extend T::Sig
|
|
14
|
+
|
|
12
15
|
include Geet::Helpers::ServicesWorkflowHelper
|
|
13
16
|
include Geet::Shared
|
|
14
17
|
|
|
15
18
|
DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
|
|
16
19
|
|
|
20
|
+
sig { params(repository: Git::Repository, out: T.any(IO, StringIO), git_client: Utils::GitClient).void }
|
|
17
21
|
def initialize(repository, out: $stdout, git_client: DEFAULT_GIT_CLIENT)
|
|
18
22
|
@repository = repository
|
|
19
23
|
@out = out
|
|
20
24
|
@git_client = git_client
|
|
21
25
|
end
|
|
22
26
|
|
|
27
|
+
sig {
|
|
28
|
+
params(
|
|
29
|
+
delete_branch: T::Boolean,
|
|
30
|
+
squash: T::Boolean
|
|
31
|
+
)
|
|
32
|
+
.returns(T.any(Github::PR, Gitlab::PR))
|
|
33
|
+
}
|
|
23
34
|
def execute(delete_branch: false, squash: false)
|
|
24
|
-
merge_method =
|
|
35
|
+
merge_method = "squash" if squash
|
|
25
36
|
|
|
26
37
|
@git_client.fetch
|
|
27
38
|
|
|
@@ -62,42 +73,49 @@ module Geet
|
|
|
62
73
|
|
|
63
74
|
private
|
|
64
75
|
|
|
76
|
+
sig { void }
|
|
65
77
|
def check_no_missing_upstream_commits
|
|
66
|
-
missing_upstream_commits = @git_client.cherry(
|
|
78
|
+
missing_upstream_commits = @git_client.cherry("HEAD", head: :main_branch)
|
|
67
79
|
|
|
68
80
|
raise "Found #{missing_upstream_commits.size} missing upstream commits!" if missing_upstream_commits.any?
|
|
69
81
|
end
|
|
70
82
|
|
|
83
|
+
sig { params(pr: T.any(Github::PR, Gitlab::PR), merge_method: T.nilable(String)).void }
|
|
71
84
|
def merge_pr(pr, merge_method: nil)
|
|
72
85
|
@out.puts "Merging PR ##{pr.number}..."
|
|
73
86
|
|
|
74
87
|
pr.merge(merge_method:)
|
|
75
88
|
end
|
|
76
89
|
|
|
90
|
+
sig { params(branch: String).void }
|
|
77
91
|
def delete_remote_branch(branch)
|
|
78
92
|
@out.puts "Deleting remote branch #{branch}..."
|
|
79
93
|
|
|
80
94
|
@repository.delete_branch(branch)
|
|
81
95
|
end
|
|
82
96
|
|
|
97
|
+
sig { void }
|
|
83
98
|
def fetch_repository
|
|
84
99
|
@out.puts "Fetching repository..."
|
|
85
100
|
|
|
86
101
|
@git_client.fetch
|
|
87
102
|
end
|
|
88
103
|
|
|
104
|
+
sig { params(branch: String).void }
|
|
89
105
|
def checkout_branch(branch)
|
|
90
106
|
@out.puts "Checking out #{branch}..."
|
|
91
107
|
|
|
92
108
|
@git_client.checkout(branch)
|
|
93
109
|
end
|
|
94
110
|
|
|
111
|
+
sig { void }
|
|
95
112
|
def rebase
|
|
96
113
|
@out.puts "Rebasing..."
|
|
97
114
|
|
|
98
115
|
@git_client.rebase
|
|
99
116
|
end
|
|
100
117
|
|
|
118
|
+
sig { params(branch: String, force: T::Boolean).void }
|
|
101
119
|
def delete_local_branch(branch, force:)
|
|
102
120
|
@out.puts "Deleting local branch #{branch}..."
|
|
103
121
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# typed: strict
|
|
3
3
|
|
|
4
|
-
require
|
|
4
|
+
require "stringio"
|
|
5
5
|
|
|
6
6
|
module Geet
|
|
7
7
|
module Services
|
|
@@ -18,7 +18,7 @@ module Geet
|
|
|
18
18
|
sig {
|
|
19
19
|
params(
|
|
20
20
|
repository: Git::Repository,
|
|
21
|
-
out:
|
|
21
|
+
out: IO,
|
|
22
22
|
git_client: Utils::GitClient
|
|
23
23
|
).void
|
|
24
24
|
}
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
# Open in the browser the current repository.
|
|
6
7
|
#
|
|
7
8
|
class OpenRepo
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
8
11
|
include Helpers::OsHelper
|
|
9
12
|
|
|
10
13
|
DEFAULT_GIT_CLIENT = Utils::GitClient.new
|
|
11
14
|
|
|
15
|
+
sig { params(repository: Git::Repository, out: IO, git_client: Utils::GitClient).void }
|
|
12
16
|
def initialize(repository, out: $stdout, git_client: DEFAULT_GIT_CLIENT)
|
|
13
17
|
@repository = repository
|
|
14
18
|
@out = out
|
|
15
19
|
@git_client = git_client
|
|
16
20
|
end
|
|
17
21
|
|
|
22
|
+
sig { params(upstream: T::Boolean).returns(String) }
|
|
18
23
|
def execute(upstream: false)
|
|
19
24
|
remote_options = upstream ? {name: Utils::GitClient::UPSTREAM_NAME} : {}
|
|
20
25
|
|
|
@@ -30,6 +35,7 @@ module Geet
|
|
|
30
35
|
|
|
31
36
|
# The repository URL may be in any of the git/http protocols.
|
|
32
37
|
#
|
|
38
|
+
sig { params(repo_url: String).returns(String) }
|
|
33
39
|
def convert_repo_url_to_http_protocol(repo_url)
|
|
34
40
|
case repo_url
|
|
35
41
|
when /https:/
|
|
@@ -39,7 +45,7 @@ module Geet
|
|
|
39
45
|
raise
|
|
40
46
|
end
|
|
41
47
|
|
|
42
|
-
domain, _, path = repo_url.match(Utils::GitClient::REMOTE_URL_REGEX)[2..4]
|
|
48
|
+
domain, _, path = T.must(repo_url.match(Utils::GitClient::REMOTE_URL_REGEX))[2..4]
|
|
43
49
|
|
|
44
50
|
"https://#{domain}/#{path}"
|
|
45
51
|
end
|
|
@@ -6,10 +6,10 @@ module Geet
|
|
|
6
6
|
module RepoPermissions
|
|
7
7
|
extend T::Sig
|
|
8
8
|
|
|
9
|
-
PERMISSION_ADMIN =
|
|
10
|
-
PERMISSION_WRITE =
|
|
11
|
-
PERMISSION_READ =
|
|
12
|
-
PERMISSION_NONE =
|
|
9
|
+
PERMISSION_ADMIN = "admin"
|
|
10
|
+
PERMISSION_WRITE = "write"
|
|
11
|
+
PERMISSION_READ = "read"
|
|
12
|
+
PERMISSION_NONE = "none"
|
|
13
13
|
|
|
14
14
|
ALL_PERMISSIONS = T.let(T.unsafe(nil), T::Array[String]) if defined?(T::sig)
|
|
15
15
|
ALL_PERMISSIONS = [
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
module Geet
|
|
5
5
|
module Shared
|
|
6
6
|
module Selection
|
|
7
|
-
MANUAL_LIST_SELECTION_FLAG =
|
|
7
|
+
MANUAL_LIST_SELECTION_FLAG = "-"
|
|
8
8
|
# Don't select anything; return the null value.
|
|
9
|
-
SKIP_LIST_SELECTION_FLAG =
|
|
9
|
+
SKIP_LIST_SELECTION_FLAG = ""
|
|
10
10
|
|
|
11
11
|
SELECTION_SINGLE = :single
|
|
12
12
|
SELECTION_MULTIPLE = :multiple
|
|
@@ -23,7 +23,7 @@ module Geet
|
|
|
23
23
|
|
|
24
24
|
# Initialize the instance, and starts the background threads.
|
|
25
25
|
#
|
|
26
|
-
sig { params(repository:
|
|
26
|
+
sig { params(repository: Geet::Git::Repository, out: T.any(IO, StringIO)).void }
|
|
27
27
|
def initialize(repository, out: $stdout)
|
|
28
28
|
@repository = repository
|
|
29
29
|
@out = out
|
|
@@ -34,13 +34,14 @@ module Geet
|
|
|
34
34
|
#
|
|
35
35
|
sig {
|
|
36
36
|
params(
|
|
37
|
-
repository_call:
|
|
38
|
-
description:
|
|
39
|
-
pattern: T.
|
|
40
|
-
selection_type:
|
|
41
|
-
name_method: T.
|
|
42
|
-
pre_selection_hook: T.nilable(T.proc.params(
|
|
43
|
-
)
|
|
37
|
+
repository_call: Symbol,
|
|
38
|
+
description: String,
|
|
39
|
+
pattern: T.nilable(String),
|
|
40
|
+
selection_type: Symbol,
|
|
41
|
+
name_method: T.nilable(Symbol),
|
|
42
|
+
pre_selection_hook: T.nilable(T.proc.params(entries: T::Array[T.anything]).returns(T::Array[T.anything]))
|
|
43
|
+
)
|
|
44
|
+
.void
|
|
44
45
|
}
|
|
45
46
|
def add_attribute(repository_call, description, pattern, selection_type, name_method: nil, &pre_selection_hook)
|
|
46
47
|
raise "Unrecognized selection type #{selection_type.inspect}" if ![SELECTION_SINGLE, SELECTION_MULTIPLE].include?(selection_type)
|
|
@@ -52,7 +53,7 @@ module Geet
|
|
|
52
53
|
|
|
53
54
|
# Select and return the attributes, in the same order they've been added.
|
|
54
55
|
#
|
|
55
|
-
sig { returns(T.
|
|
56
|
+
sig { returns(T::Array[T.anything]) }
|
|
56
57
|
def select_attributes
|
|
57
58
|
@selections_data.map do |finder_thread, description, pattern, selection_type, name_method, pre_selection_hook|
|
|
58
59
|
entries = finder_thread.value
|
|
@@ -70,6 +71,7 @@ module Geet
|
|
|
70
71
|
|
|
71
72
|
private
|
|
72
73
|
|
|
74
|
+
sig { params(repository_call: Symbol).returns(Thread) }
|
|
73
75
|
def find_attribute_entries(repository_call)
|
|
74
76
|
@out.puts "Finding #{repository_call}..."
|
|
75
77
|
|
|
@@ -86,6 +88,15 @@ module Geet
|
|
|
86
88
|
#
|
|
87
89
|
# select_entry('milestone', all_milestones, '0.1.0', :title)
|
|
88
90
|
#
|
|
91
|
+
sig {
|
|
92
|
+
params(
|
|
93
|
+
entry_type: String,
|
|
94
|
+
entries: T::Array[T.anything],
|
|
95
|
+
pattern: String,
|
|
96
|
+
name_method: T.nilable(Symbol)
|
|
97
|
+
)
|
|
98
|
+
.returns(T.nilable(T.anything))
|
|
99
|
+
}
|
|
89
100
|
def select_entry(entry_type, entries, pattern, name_method)
|
|
90
101
|
case pattern
|
|
91
102
|
when MANUAL_LIST_SELECTION_FLAG
|
|
@@ -101,13 +112,22 @@ module Geet
|
|
|
101
112
|
#
|
|
102
113
|
# select_entries('reviewer', all_collaborators, 'donaldduck', nil)
|
|
103
114
|
#
|
|
115
|
+
sig {
|
|
116
|
+
params(
|
|
117
|
+
entry_type: String,
|
|
118
|
+
entries: T::Array[T.anything],
|
|
119
|
+
pattern: T.any(String, T::Array[String]),
|
|
120
|
+
name_method: T.nilable(Symbol)
|
|
121
|
+
)
|
|
122
|
+
.returns(T::Array[T.anything])
|
|
123
|
+
}
|
|
104
124
|
def select_entries(entry_type, entries, pattern, name_method)
|
|
105
125
|
# Support both formats Array and String.
|
|
106
126
|
# It seems that at some point, SimpleScripting started splitting arrays automatically, so until
|
|
107
127
|
# the code is adjusted accordingly, this accommodates both the CLI and the test suite.
|
|
108
128
|
# Tracked here: https://github.com/saveriomiroddi/geet/issues/171.
|
|
109
129
|
#
|
|
110
|
-
pattern = pattern.join(
|
|
130
|
+
pattern = pattern.join(",") if pattern.is_a?(Array)
|
|
111
131
|
|
|
112
132
|
case pattern
|
|
113
133
|
when MANUAL_LIST_SELECTION_FLAG
|