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,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# typed:
|
|
2
|
+
# typed: strict
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
4
|
+
require "English"
|
|
5
|
+
require "shellwords"
|
|
6
6
|
|
|
7
7
|
module Geet
|
|
8
8
|
module Utils
|
|
@@ -13,8 +13,8 @@ module Geet
|
|
|
13
13
|
|
|
14
14
|
include Geet::Helpers::OsHelper
|
|
15
15
|
|
|
16
|
-
ORIGIN_NAME =
|
|
17
|
-
UPSTREAM_NAME =
|
|
16
|
+
ORIGIN_NAME = "origin"
|
|
17
|
+
UPSTREAM_NAME = "upstream"
|
|
18
18
|
|
|
19
19
|
# Simplified, but good enough, pattern.
|
|
20
20
|
#
|
|
@@ -38,11 +38,11 @@ module Geet
|
|
|
38
38
|
|
|
39
39
|
REMOTE_BRANCH_REGEX = %r{\A[^/]+/(.+)\Z}
|
|
40
40
|
|
|
41
|
-
MAIN_BRANCH_CONFIG_ENTRY =
|
|
41
|
+
MAIN_BRANCH_CONFIG_ENTRY = "custom.development-branch"
|
|
42
42
|
|
|
43
43
|
CLEAN_TREE_MESSAGE_REGEX = /^nothing to commit, working tree clean$/
|
|
44
44
|
|
|
45
|
-
sig { params(location: T.
|
|
45
|
+
sig { params(location: T.nilable(String)).void }
|
|
46
46
|
def initialize(location: nil)
|
|
47
47
|
@location = location
|
|
48
48
|
end
|
|
@@ -54,40 +54,49 @@ module Geet
|
|
|
54
54
|
# Return the commit SHAs between :head and :upstream, excluding the already applied commits
|
|
55
55
|
# (which start with `-`)
|
|
56
56
|
#
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
sig {
|
|
58
|
+
params(
|
|
59
|
+
upstream: T.any(String, Symbol), # pass :main_branch to use the main branch
|
|
60
|
+
head: T.nilable(T.any(String, Symbol)) # pass :main_branch to use the main branch
|
|
61
|
+
)
|
|
62
|
+
.returns(T::Array[String])
|
|
63
|
+
}
|
|
60
64
|
def cherry(upstream, head: nil)
|
|
61
65
|
upstream = main_branch if upstream == :main_branch
|
|
62
66
|
head = main_branch if head == :main_branch
|
|
63
67
|
|
|
64
|
-
git_params = [upstream, head].compact.map
|
|
68
|
+
git_params = [upstream, head].compact.map { |param| param.to_s.shellescape }
|
|
65
69
|
|
|
66
70
|
raw_commits = execute_git_command("cherry #{git_params.join(' ')}")
|
|
67
71
|
|
|
68
|
-
raw_commits.split("\n").grep(/^\+/).map { |line| line[3..-1] }
|
|
72
|
+
raw_commits.split("\n").grep(/^\+/).map { |line| T.must(line[3..-1]) }
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
sig { returns(String) }
|
|
71
76
|
def current_branch
|
|
72
77
|
branch = execute_git_command("rev-parse --abbrev-ref HEAD")
|
|
73
78
|
|
|
74
|
-
raise "Couldn't find current branch" if branch ==
|
|
79
|
+
raise "Couldn't find current branch" if branch == "HEAD"
|
|
75
80
|
|
|
76
81
|
branch
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
# This API doesn't reveal if the remote branch is gone.
|
|
80
85
|
#
|
|
81
|
-
# qualify: (false) include the remote if true, don't otherwise
|
|
82
|
-
#
|
|
83
86
|
# return: nil, if the remote branch is not configured.
|
|
84
87
|
#
|
|
88
|
+
sig {
|
|
89
|
+
params(
|
|
90
|
+
qualify: T::Boolean # include the remote if true, don't otherwise
|
|
91
|
+
)
|
|
92
|
+
.returns(T.nilable(String))
|
|
93
|
+
}
|
|
85
94
|
def remote_branch(qualify: false)
|
|
86
95
|
head_symbolic_ref = execute_git_command("symbolic-ref -q HEAD")
|
|
87
96
|
|
|
88
97
|
raw_remote_branch = execute_git_command("for-each-ref --format='%(upstream:short)' #{head_symbolic_ref.shellescape}").strip
|
|
89
98
|
|
|
90
|
-
if raw_remote_branch !=
|
|
99
|
+
if raw_remote_branch != ""
|
|
91
100
|
if qualify
|
|
92
101
|
raw_remote_branch
|
|
93
102
|
else
|
|
@@ -106,6 +115,7 @@ module Geet
|
|
|
106
115
|
# ## add_milestone_closing...origin/add_milestone_closing [gone]
|
|
107
116
|
# M spec/integration/merge_pr_spec.rb
|
|
108
117
|
#
|
|
118
|
+
sig { returns(T::Boolean) }
|
|
109
119
|
def remote_branch_gone?
|
|
110
120
|
git_command = "status -b --porcelain"
|
|
111
121
|
status_output = execute_git_command(git_command)
|
|
@@ -122,12 +132,13 @@ module Geet
|
|
|
122
132
|
|
|
123
133
|
# See https://saveriomiroddi.github.io/Conveniently-Handling-non-master-development-default-branches-in-git-hub
|
|
124
134
|
#
|
|
135
|
+
sig { returns(String) }
|
|
125
136
|
def main_branch
|
|
126
137
|
branch_name = execute_git_command("config --get #{MAIN_BRANCH_CONFIG_ENTRY}", allow_error: true)
|
|
127
138
|
|
|
128
139
|
if branch_name.empty?
|
|
129
140
|
full_branch_name = execute_git_command("rev-parse --abbrev-ref #{ORIGIN_NAME}/HEAD")
|
|
130
|
-
full_branch_name.split(
|
|
141
|
+
T.must(full_branch_name.split("/").last)
|
|
131
142
|
else
|
|
132
143
|
branch_name
|
|
133
144
|
end
|
|
@@ -135,18 +146,21 @@ module Geet
|
|
|
135
146
|
|
|
136
147
|
# List of different commits between local and corresponding remote branch.
|
|
137
148
|
#
|
|
149
|
+
sig { returns(String) }
|
|
138
150
|
def remote_branch_diff_commits
|
|
139
|
-
remote_branch = remote_branch(qualify: true)
|
|
151
|
+
remote_branch = T.must(remote_branch(qualify: true))
|
|
140
152
|
|
|
141
153
|
execute_git_command("rev-list #{remote_branch.shellescape}..HEAD")
|
|
142
154
|
end
|
|
143
155
|
|
|
156
|
+
sig { returns(String) }
|
|
144
157
|
def remote_branch_diff
|
|
145
|
-
remote_branch = remote_branch(qualify: true)
|
|
158
|
+
remote_branch = T.must(remote_branch(qualify: true))
|
|
146
159
|
|
|
147
160
|
execute_git_command("diff #{remote_branch.shellescape}")
|
|
148
161
|
end
|
|
149
162
|
|
|
163
|
+
sig { returns(T::Boolean) }
|
|
150
164
|
def working_tree_clean?
|
|
151
165
|
git_message = execute_git_command("status")
|
|
152
166
|
|
|
@@ -159,6 +173,7 @@ module Geet
|
|
|
159
173
|
|
|
160
174
|
# Show the description ("<subject>\n\n<body>") for the given git object.
|
|
161
175
|
#
|
|
176
|
+
sig { params(object: String).returns(String) }
|
|
162
177
|
def show_description(object)
|
|
163
178
|
execute_git_command("show --quiet --format='%s\n\n%b' #{object.shellescape}")
|
|
164
179
|
end
|
|
@@ -170,26 +185,35 @@ module Geet
|
|
|
170
185
|
# Return the components of the remote, according to REMOTE_URL_REGEX; doesn't include the full
|
|
171
186
|
# match.
|
|
172
187
|
#
|
|
188
|
+
sig {
|
|
189
|
+
params(
|
|
190
|
+
name: T.nilable(String) # remote name
|
|
191
|
+
)
|
|
192
|
+
.returns(T::Array[T.nilable(String)])
|
|
193
|
+
}
|
|
173
194
|
def remote_components(name: nil)
|
|
174
|
-
remote.match(REMOTE_URL_REGEX)[1..]
|
|
195
|
+
T.must(remote.match(REMOTE_URL_REGEX))[1..]
|
|
175
196
|
end
|
|
176
197
|
|
|
177
198
|
# Example: `donaldduck/geet`
|
|
178
199
|
#
|
|
200
|
+
sig { params(upstream: T::Boolean).returns(String) }
|
|
179
201
|
def path(upstream: false)
|
|
180
202
|
remote_name_option = upstream ? {name: UPSTREAM_NAME} : {}
|
|
181
203
|
|
|
182
|
-
remote(**remote_name_option)[REMOTE_URL_REGEX, 4]
|
|
204
|
+
T.must(remote(**remote_name_option)[REMOTE_URL_REGEX, 4])
|
|
183
205
|
end
|
|
184
206
|
|
|
207
|
+
sig { returns(String) }
|
|
185
208
|
def owner
|
|
186
|
-
path.split(
|
|
209
|
+
T.must(path.split("/")[0])
|
|
187
210
|
end
|
|
188
211
|
|
|
212
|
+
sig { returns(String) }
|
|
189
213
|
def provider_domain
|
|
190
214
|
# We assume that it's not possible to have origin and upstream on different providers.
|
|
191
215
|
|
|
192
|
-
domain = remote()[REMOTE_URL_REGEX, 2]
|
|
216
|
+
domain = T.must(remote()[REMOTE_URL_REGEX, 2])
|
|
193
217
|
|
|
194
218
|
raise "Can't identify domain in the provider domain string: #{domain}" if domain !~ /\w+\.\w+/
|
|
195
219
|
|
|
@@ -201,9 +225,12 @@ module Geet
|
|
|
201
225
|
#
|
|
202
226
|
# The result is in the format `git@github.com:donaldduck/geet.git`
|
|
203
227
|
#
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
228
|
+
sig {
|
|
229
|
+
params(
|
|
230
|
+
name: T.nilable(String) # remote name; if unspecified, the default remote is used
|
|
231
|
+
)
|
|
232
|
+
.returns(String)
|
|
233
|
+
}
|
|
207
234
|
def remote(name: nil)
|
|
208
235
|
remote_url = execute_git_command("ls-remote --get-url #{name}")
|
|
209
236
|
|
|
@@ -219,6 +246,7 @@ module Geet
|
|
|
219
246
|
# Doesn't sanity check for the remote url format; this action is for querying
|
|
220
247
|
# purposes, any any action that needs to work with the remote, uses #remote.
|
|
221
248
|
#
|
|
249
|
+
sig { params(name: T.nilable(String)).returns(T::Boolean) }
|
|
222
250
|
def remote_defined?(name)
|
|
223
251
|
remote_url = execute_git_command("ls-remote --get-url #{name}")
|
|
224
252
|
|
|
@@ -231,22 +259,30 @@ module Geet
|
|
|
231
259
|
# OPERATION APIS
|
|
232
260
|
##########################################################################
|
|
233
261
|
|
|
262
|
+
sig { params(branch: String).returns(String) }
|
|
234
263
|
def checkout(branch)
|
|
235
264
|
execute_git_command("checkout #{branch.shellescape}")
|
|
236
265
|
end
|
|
237
266
|
|
|
267
|
+
sig { params(branch: String, force: T::Boolean).returns(String) }
|
|
238
268
|
def delete_branch(branch, force:)
|
|
239
269
|
force_option = "--force" if force
|
|
240
270
|
|
|
241
271
|
execute_git_command("branch --delete #{force_option} #{branch.shellescape}")
|
|
242
272
|
end
|
|
243
273
|
|
|
274
|
+
sig { returns(String) }
|
|
244
275
|
def rebase
|
|
245
276
|
execute_git_command("rebase")
|
|
246
277
|
end
|
|
247
278
|
|
|
248
|
-
|
|
249
|
-
|
|
279
|
+
sig {
|
|
280
|
+
params(
|
|
281
|
+
remote_branch: T.nilable(String), # create an upstream branch
|
|
282
|
+
force: T::Boolean
|
|
283
|
+
)
|
|
284
|
+
.returns(String)
|
|
285
|
+
}
|
|
250
286
|
def push(remote_branch: nil, force: false)
|
|
251
287
|
remote_branch_option = "-u #{ORIGIN_NAME} #{remote_branch.shellescape}" if remote_branch
|
|
252
288
|
|
|
@@ -255,10 +291,12 @@ module Geet
|
|
|
255
291
|
|
|
256
292
|
# Performs pruning.
|
|
257
293
|
#
|
|
294
|
+
sig { returns(String) }
|
|
258
295
|
def fetch
|
|
259
296
|
execute_git_command("fetch --prune")
|
|
260
297
|
end
|
|
261
298
|
|
|
299
|
+
sig { params(name: String, url: String).returns(String) }
|
|
262
300
|
def add_remote(name, url)
|
|
263
301
|
execute_git_command("remote add #{name.shellescape} #{url}")
|
|
264
302
|
end
|
|
@@ -272,14 +310,17 @@ module Geet
|
|
|
272
310
|
# If executing a git command without calling this API, don't forget to split `gitdir_option`
|
|
273
311
|
# and use it!
|
|
274
312
|
#
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
313
|
+
sig {
|
|
314
|
+
params(
|
|
315
|
+
command: String,
|
|
316
|
+
options: T.untyped # passed to :execute_command (e.g., allow_error)
|
|
317
|
+
)
|
|
318
|
+
.returns(String)
|
|
319
|
+
}
|
|
279
320
|
def execute_git_command(command, **options)
|
|
280
321
|
gitdir_option = "-C #{@location.shellescape}" if @location
|
|
281
322
|
|
|
282
|
-
execute_command("git #{gitdir_option} #{command}", **options)
|
|
323
|
+
T.must(execute_command("git #{gitdir_option} #{command}", **options))
|
|
283
324
|
end
|
|
284
325
|
end
|
|
285
326
|
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# typed: strict
|
|
3
3
|
|
|
4
|
-
require
|
|
4
|
+
require "tty-prompt"
|
|
5
5
|
|
|
6
6
|
module Geet
|
|
7
7
|
module Utils
|
|
8
8
|
class ManualListSelection
|
|
9
9
|
extend T::Sig
|
|
10
10
|
|
|
11
|
-
NO_SELECTION_KEY =
|
|
11
|
+
NO_SELECTION_KEY = "(none)"
|
|
12
12
|
|
|
13
13
|
PAGER_SIZE = 16
|
|
14
14
|
|
|
@@ -54,27 +54,34 @@ module Geet
|
|
|
54
54
|
|
|
55
55
|
check_entries(entries, entry_type)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
entries_map = create_entries_map(entries, name_method)
|
|
58
58
|
|
|
59
|
-
show_prompt(:multi_select, entry_type,
|
|
59
|
+
T.cast(show_prompt(:multi_select, entry_type, entries_map), T::Array[T.type_parameter(:T)])
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
private
|
|
63
63
|
|
|
64
|
-
sig {
|
|
64
|
+
sig {
|
|
65
|
+
type_parameters(:T).params(
|
|
66
|
+
entries: T::Array[T.type_parameter(:T)],
|
|
67
|
+
entry_type: String
|
|
68
|
+
)
|
|
69
|
+
.void
|
|
70
|
+
}
|
|
65
71
|
def check_entries(entries, entry_type)
|
|
66
72
|
raise "No #{entry_type} provided!" if entries.empty?
|
|
67
73
|
end
|
|
68
74
|
|
|
69
75
|
sig {
|
|
70
|
-
params(
|
|
71
|
-
entries: T::Array[T.
|
|
76
|
+
type_parameters(:T).params(
|
|
77
|
+
entries: T::Array[T.type_parameter(:T)],
|
|
72
78
|
name_method: T.nilable(Symbol)
|
|
73
|
-
)
|
|
79
|
+
)
|
|
80
|
+
.returns(T::Hash[String, T.type_parameter(:T)])
|
|
74
81
|
}
|
|
75
82
|
def create_entries_map(entries, name_method)
|
|
76
83
|
entries.each_with_object({}) do |entry, current_map|
|
|
77
|
-
key = name_method ? entry.send(name_method) : entry
|
|
84
|
+
key = name_method ? T.unsafe(entry).send(name_method) : entry
|
|
78
85
|
current_map[key] = entry
|
|
79
86
|
end
|
|
80
87
|
end
|
|
@@ -101,9 +108,14 @@ module Geet
|
|
|
101
108
|
::TTY::Prompt.new.send(invocation_method, prompt_title, entries, filter: true, per_page: PAGER_SIZE)
|
|
102
109
|
end
|
|
103
110
|
|
|
104
|
-
sig {
|
|
111
|
+
sig {
|
|
112
|
+
params(
|
|
113
|
+
entry: T.anything
|
|
114
|
+
)
|
|
115
|
+
.returns(T::Boolean)
|
|
116
|
+
}
|
|
105
117
|
def no_selection?(entry)
|
|
106
|
-
entry == NO_SELECTION_KEY
|
|
118
|
+
T.unsafe(entry) == NO_SELECTION_KEY
|
|
107
119
|
end
|
|
108
120
|
end
|
|
109
121
|
end
|
|
@@ -6,16 +6,24 @@ module Geet
|
|
|
6
6
|
class StringMatchingSelection
|
|
7
7
|
extend T::Sig
|
|
8
8
|
|
|
9
|
-
sig {
|
|
9
|
+
sig {
|
|
10
|
+
type_parameters(:T).params(
|
|
11
|
+
entry_type: String,
|
|
12
|
+
entries: T::Array[T.type_parameter(:T)],
|
|
13
|
+
pattern: String,
|
|
14
|
+
name_method: T.nilable(Symbol)
|
|
15
|
+
)
|
|
16
|
+
.returns(T.type_parameter(:T))
|
|
17
|
+
}
|
|
10
18
|
def select_entry(entry_type, entries, pattern, name_method: nil)
|
|
11
19
|
entries_found = entries.select do |entry|
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
compared_entry = name_method ? T.unsafe(entry).send(name_method) : entry
|
|
21
|
+
T.unsafe(compared_entry).downcase == pattern.downcase
|
|
14
22
|
end
|
|
15
23
|
|
|
16
24
|
case entries_found.size
|
|
17
25
|
when 1
|
|
18
|
-
entries_found.first
|
|
26
|
+
T.must(entries_found.first)
|
|
19
27
|
when 0
|
|
20
28
|
raise "No entry found for #{entry_type} pattern: #{pattern.inspect}"
|
|
21
29
|
else
|
|
@@ -23,9 +31,17 @@ module Geet
|
|
|
23
31
|
end
|
|
24
32
|
end
|
|
25
33
|
|
|
26
|
-
sig {
|
|
34
|
+
sig {
|
|
35
|
+
type_parameters(:T).params(
|
|
36
|
+
entry_type: String,
|
|
37
|
+
entries: T::Array[T.type_parameter(:T)],
|
|
38
|
+
raw_patterns: String,
|
|
39
|
+
name_method: T.nilable(Symbol)
|
|
40
|
+
)
|
|
41
|
+
.returns(T::Array[T.type_parameter(:T)])
|
|
42
|
+
}
|
|
27
43
|
def select_entries(entry_type, entries, raw_patterns, name_method: nil)
|
|
28
|
-
patterns = raw_patterns.split(
|
|
44
|
+
patterns = raw_patterns.split(",")
|
|
29
45
|
|
|
30
46
|
patterns.map do |pattern|
|
|
31
47
|
# Haha.
|
data/lib/geet/version.rb
CHANGED
data/lib/geet.rb
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
5
|
+
require_relative "../../lib/geet/git/repository"
|
|
6
|
+
require_relative "../../lib/geet/services/comment_pr"
|
|
7
7
|
|
|
8
8
|
describe Geet::Services::CommentPr do
|
|
9
9
|
let(:git_client) { Geet::Utils::GitClient.new }
|
|
10
10
|
let(:repository) { Geet::Git::Repository.new(git_client: git_client) }
|
|
11
|
-
let(:owner) {
|
|
12
|
-
let(:branch) {
|
|
13
|
-
let(:comment) {
|
|
11
|
+
let(:owner) { "donaldduck" }
|
|
12
|
+
let(:branch) { "mybranch" }
|
|
13
|
+
let(:comment) { "this is a programmatically added comment" }
|
|
14
14
|
|
|
15
|
-
context
|
|
16
|
-
let(:repository_name) {
|
|
15
|
+
context "with github.com" do
|
|
16
|
+
let(:repository_name) { "testrepo_upstream" }
|
|
17
17
|
|
|
18
|
-
it
|
|
18
|
+
it "should add a comment to the PR for the current branch" do
|
|
19
19
|
allow(git_client).to receive(:current_branch).and_return(branch)
|
|
20
20
|
allow(git_client).to receive(:remote).with(no_args).and_return("git@github.com:#{owner}/#{repository_name}")
|
|
21
21
|
|
|
@@ -27,7 +27,7 @@ describe Geet::Services::CommentPr do
|
|
|
27
27
|
actual_output = StringIO.new
|
|
28
28
|
service_instance = described_class.new(repository, out: actual_output, git_client: git_client)
|
|
29
29
|
|
|
30
|
-
service_result = VCR.use_cassette(
|
|
30
|
+
service_result = VCR.use_cassette("github_com/comment_pr") do
|
|
31
31
|
service_instance.execute(comment)
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "tmpdir"
|
|
5
5
|
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
6
|
+
require_relative "../../lib/geet/git/repository"
|
|
7
|
+
require_relative "../../lib/geet/services/create_gist"
|
|
8
8
|
|
|
9
9
|
describe Geet::Services::CreateGist do
|
|
10
|
-
let(:temp_filename) { File.join(Dir.tmpdir,
|
|
11
|
-
let(:temp_file) { File.open(temp_filename,
|
|
10
|
+
let(:temp_filename) { File.join(Dir.tmpdir, "geet_gist_test.md") }
|
|
11
|
+
let(:temp_file) { File.open(temp_filename, "w") { |file| file << "testcontent" } }
|
|
12
12
|
|
|
13
|
-
it
|
|
13
|
+
it "should create a public gist" do
|
|
14
14
|
expected_output = <<~STR
|
|
15
15
|
Creating a public gist...
|
|
16
16
|
Gist address: https://gist.github.com/b01dface
|
|
@@ -18,16 +18,16 @@ describe Geet::Services::CreateGist do
|
|
|
18
18
|
|
|
19
19
|
actual_output = StringIO.new
|
|
20
20
|
|
|
21
|
-
VCR.use_cassette(
|
|
21
|
+
VCR.use_cassette("create_gist_public") do
|
|
22
22
|
described_class.new(out: actual_output).execute(
|
|
23
|
-
temp_file.path, description:
|
|
23
|
+
temp_file.path, description: "testdescription", publik: true
|
|
24
24
|
)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
expect(actual_output.string).to eql(expected_output)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
it
|
|
30
|
+
it "should create a private gist" do
|
|
31
31
|
expected_output = <<~STR
|
|
32
32
|
Creating a private gist...
|
|
33
33
|
Gist address: https://gist.github.com/deadbeef
|
|
@@ -35,9 +35,9 @@ describe Geet::Services::CreateGist do
|
|
|
35
35
|
|
|
36
36
|
actual_output = StringIO.new
|
|
37
37
|
|
|
38
|
-
VCR.use_cassette(
|
|
38
|
+
VCR.use_cassette("create_gist_private") do
|
|
39
39
|
described_class.new(out: actual_output).execute(
|
|
40
|
-
temp_file.path, description:
|
|
40
|
+
temp_file.path, description: "testdescription"
|
|
41
41
|
)
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
5
|
+
require_relative "../../lib/geet/git/repository"
|
|
6
|
+
require_relative "../../lib/geet/services/create_issue"
|
|
7
7
|
|
|
8
8
|
describe Geet::Services::CreateIssue do
|
|
9
9
|
let(:git_client) { Geet::Utils::GitClient.new }
|
|
10
10
|
let(:repository) { Geet::Git::Repository.new(warnings: false, git_client: git_client) }
|
|
11
11
|
let(:upstream_repository) { Geet::Git::Repository.new(upstream: true, git_client: git_client) }
|
|
12
12
|
|
|
13
|
-
context
|
|
14
|
-
it
|
|
15
|
-
allow(git_client).to receive(:remote).with(no_args).and_return(
|
|
13
|
+
context "with labels, assignees and milestones" do
|
|
14
|
+
it "should create an issue" do
|
|
15
|
+
allow(git_client).to receive(:remote).with(no_args).and_return("git@github.com:donaldduck/testrepo_f")
|
|
16
16
|
|
|
17
17
|
expected_output = <<~STR
|
|
18
18
|
Finding labels...
|
|
@@ -27,27 +27,27 @@ describe Geet::Services::CreateIssue do
|
|
|
27
27
|
|
|
28
28
|
actual_output = StringIO.new
|
|
29
29
|
|
|
30
|
-
actual_created_issue = VCR.use_cassette(
|
|
30
|
+
actual_created_issue = VCR.use_cassette("create_issue") do
|
|
31
31
|
described_class.new(repository, out: actual_output).execute(
|
|
32
|
-
|
|
33
|
-
labels:
|
|
32
|
+
"Title", "Description",
|
|
33
|
+
labels: "bug,invalid", milestone: "0.0.1", assignees: "donaldduck,donald-fr",
|
|
34
34
|
)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
expect(actual_output.string).to eql(expected_output)
|
|
38
38
|
|
|
39
39
|
expect(actual_created_issue.number).to eql(2)
|
|
40
|
-
expect(actual_created_issue.title).to eql(
|
|
41
|
-
expect(actual_created_issue.link).to eql(
|
|
40
|
+
expect(actual_created_issue.title).to eql("Title")
|
|
41
|
+
expect(actual_created_issue.link).to eql("https://github.com/donaldduck/testrepo_f/issues/2")
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
context
|
|
46
|
-
context
|
|
47
|
-
it
|
|
48
|
-
allow(git_client).to receive(:current_branch).and_return(
|
|
49
|
-
allow(git_client).to receive(:remote).with(no_args).and_return(
|
|
50
|
-
allow(git_client).to receive(:remote).with(name:
|
|
45
|
+
context "without write permissions" do
|
|
46
|
+
context "without labels, assignees and milestones" do
|
|
47
|
+
it "should create an upstream issue" do
|
|
48
|
+
allow(git_client).to receive(:current_branch).and_return("mybranch")
|
|
49
|
+
allow(git_client).to receive(:remote).with(no_args).and_return("git@github.com:donaldduck/testrepo")
|
|
50
|
+
allow(git_client).to receive(:remote).with(name: "upstream").and_return("git@github.com:momcorp/therepo")
|
|
51
51
|
|
|
52
52
|
expected_output = <<~STR
|
|
53
53
|
Creating the issue...
|
|
@@ -56,15 +56,15 @@ describe Geet::Services::CreateIssue do
|
|
|
56
56
|
|
|
57
57
|
actual_output = StringIO.new
|
|
58
58
|
|
|
59
|
-
actual_created_issue = VCR.use_cassette(
|
|
60
|
-
described_class.new(upstream_repository, out: actual_output).execute(
|
|
59
|
+
actual_created_issue = VCR.use_cassette("create_issue_upstream") do
|
|
60
|
+
described_class.new(upstream_repository, out: actual_output).execute("Title", "Description")
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
expect(actual_output.string).to eql(expected_output)
|
|
64
64
|
|
|
65
65
|
expect(actual_created_issue.number).to eql(42)
|
|
66
|
-
expect(actual_created_issue.title).to eql(
|
|
67
|
-
expect(actual_created_issue.link).to eql(
|
|
66
|
+
expect(actual_created_issue.title).to eql("Title")
|
|
67
|
+
expect(actual_created_issue.link).to eql("https://github.com/momcorp/therepo/issues/42")
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
end
|