git_pr 0.0.14.beta3 → 0.0.14.beta4
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/bin/git-pr +19 -42
- data/lib/git_pr/github.rb +3 -2
- data/lib/git_pr/merge.rb +69 -25
- data/lib/git_pr/pull_request.rb +40 -0
- data/lib/git_pr/version.rb +1 -1
- data/lib/git_pr.rb +3 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e547458a924539d3d3f6e960d4d7d00bd14bd65
|
4
|
+
data.tar.gz: de36ad310f6c68800bc87f2c25c952e406cac2e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf8767ff0b704faf1309cc2c2a29d0e8612575432ea3b36c2100daad3296ac61aaaf7b49177e4c2f0c39749ee6710b852668fa62a86452ee82b26825764e763f
|
7
|
+
data.tar.gz: a45cd138fa12884339cbbc16dde94092a6b74265d1f31d56bee424cab04ab22a1d16e0db408e73fc063ea26a2c85f90cd77d7febfe6a2bf8887f2adc087fab53
|
data/bin/git-pr
CHANGED
@@ -29,7 +29,7 @@ options = OpenStruct.new(:help => false,
|
|
29
29
|
:diff => OpenStruct.new(),
|
30
30
|
:difftool => OpenStruct.new(),
|
31
31
|
:list => OpenStruct.new(),
|
32
|
-
:merge => OpenStruct.new(),
|
32
|
+
:merge => OpenStruct.new(:yolo => false),
|
33
33
|
:open => OpenStruct.new(),
|
34
34
|
:status => OpenStruct.new())
|
35
35
|
|
@@ -121,7 +121,13 @@ Usage: git pr merge [PR number]
|
|
121
121
|
If a PR number isn't passed, a menu of open PRs will be displayed.
|
122
122
|
eos
|
123
123
|
|
124
|
-
|
124
|
+
opts.separator "\nMerge command options"
|
125
|
+
|
126
|
+
opts.on("-y", "--yolo",
|
127
|
+
"Don't check PR status before merging"
|
128
|
+
) do |y|
|
129
|
+
options.merge.yolo = y
|
130
|
+
end
|
125
131
|
|
126
132
|
opts.separator ""
|
127
133
|
end,
|
@@ -224,37 +230,13 @@ elsif File.exists? File.join(git_dir, '.git')
|
|
224
230
|
git = Git.open git_dir, :repository => submodule_git_dir, :index => File.join(submodule_git_dir, 'index')
|
225
231
|
end
|
226
232
|
|
227
|
-
def pull_request_status(pull)
|
228
|
-
Octokit.combined_status(pull.base.repo.full_name, pull.head.sha)
|
229
|
-
end
|
230
|
-
|
231
|
-
def status_summary(state)
|
232
|
-
case state
|
233
|
-
when "failure"
|
234
|
-
STDOUT.tty? ? "\u2717".red : "-"
|
235
|
-
when "success"
|
236
|
-
STDOUT.tty? ? "\u2713".green : "+"
|
237
|
-
else
|
238
|
-
STDOUT.tty? ? "\u25CF".yellow : "O"
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def pull_summary(pull, include_status)
|
243
|
-
if include_status
|
244
|
-
combined_status = pull_request_status(pull)
|
245
|
-
status_string = "#{status_summary(combined_status.state)} "
|
246
|
-
else
|
247
|
-
status_string = ""
|
248
|
-
end
|
249
|
-
"#{status_string}##{pull[:number]} from #{pull[:user][:login]}: #{pull[:title]}"
|
250
|
-
end
|
251
|
-
|
252
233
|
def find_pull_request_from_command_line_argument(git, github_project, argument)
|
253
234
|
# Look for an existing pull request that fits. A branch name or PR number can
|
254
235
|
# be passed on the command line, or we default to the current branch.
|
255
236
|
pulls = Octokit.pulls github_project
|
256
237
|
source = argument || git.current_branch
|
257
|
-
pulls.any? ? pulls.find { |p| p.head.ref == source || p.number.to_s == source } : nil
|
238
|
+
pull = pulls.any? ? pulls.find { |p| p.head.ref == source || p.number.to_s == source } : nil
|
239
|
+
pull ? GitPr::PullRequest.new(pull) : nil
|
258
240
|
end
|
259
241
|
|
260
242
|
# Figure out what GitHub project we're dealing with.
|
@@ -269,10 +251,10 @@ when "merge"
|
|
269
251
|
end
|
270
252
|
# Load a pull request
|
271
253
|
pull = GitPr::GitHub.find_or_prompt_for_pull_request github_project, pull_request
|
272
|
-
GitPr::merge_pull_cleanly git, pull
|
254
|
+
GitPr::merge_pull_cleanly git, pull, options.merge
|
273
255
|
|
274
256
|
when "list"
|
275
|
-
pulls = Octokit.pulls
|
257
|
+
pulls = Octokit.pulls("#{github_project}").map { |p| GitPr::PullRequest.new(p) }
|
276
258
|
if options.list.user
|
277
259
|
pulls = pulls.select { |p| p[:user][:login] == options.list.user }
|
278
260
|
end
|
@@ -284,7 +266,7 @@ when "list"
|
|
284
266
|
end
|
285
267
|
|
286
268
|
if pulls.any?
|
287
|
-
pulls.each { |p| puts
|
269
|
+
pulls.each { |p| puts p.summary(include_status) }
|
288
270
|
else
|
289
271
|
puts "No open pull requests found.".yellow
|
290
272
|
end
|
@@ -386,28 +368,23 @@ when "status"
|
|
386
368
|
exit 1
|
387
369
|
end
|
388
370
|
|
389
|
-
puts "
|
390
|
-
|
391
|
-
if statuses.empty?
|
371
|
+
puts "#{pull.summary}\n\n"
|
372
|
+
if pull.statuses.empty?
|
392
373
|
puts "No status found."
|
393
374
|
exit
|
394
375
|
end
|
395
376
|
|
396
|
-
|
397
|
-
statuses.sort_by { |s| s.updated_at }.each { |s| statuses_by_context[s.context] = s }
|
398
|
-
|
399
|
-
max_context = statuses_by_context.map { |c, s| s.context.length }.max
|
377
|
+
max_context = pull.statuses.map { |s| s.context.length }.max
|
400
378
|
|
401
379
|
puts <<EOS
|
402
380
|
Status (cmd-double-click to open links):
|
403
381
|
|
404
382
|
EOS
|
405
|
-
|
406
|
-
puts "#{
|
383
|
+
pull.statuses.each do |status|
|
384
|
+
puts "#{GitPr::PullRequest.summary_icon(status.state)} #{status.context.ljust(max_context)} #{status.target_url}"
|
407
385
|
end
|
408
386
|
puts "\n"
|
409
387
|
|
410
|
-
|
411
|
-
exit (success ? 0 : 1)
|
388
|
+
exit (pull.status.state == 'success' ? 0 : 1)
|
412
389
|
|
413
390
|
end
|
data/lib/git_pr/github.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'git_pr/pull_request'
|
1
2
|
require 'io/console'
|
2
3
|
require 'octokit'
|
3
4
|
require 'netrc'
|
@@ -132,7 +133,7 @@ module GitPr
|
|
132
133
|
choose do |menu|
|
133
134
|
menu.prompt = "Select PR to merge: "
|
134
135
|
pulls.each do |pull|
|
135
|
-
menu.choice(pull_summary(pull)) { pull_to_merge = pull }
|
136
|
+
menu.choice(pull_summary(pull)) { pull_to_merge = GitPr::PullRequest.new(pull) }
|
136
137
|
end
|
137
138
|
menu.choice(:Quit, "Exit program.") { exit }
|
138
139
|
end
|
@@ -155,7 +156,7 @@ module GitPr
|
|
155
156
|
else
|
156
157
|
pull = self.query_for_pull_to_merge pulls
|
157
158
|
end
|
158
|
-
pull
|
159
|
+
GitPr::PullRequest.new(pull)
|
159
160
|
end
|
160
161
|
|
161
162
|
end
|
data/lib/git_pr/merge.rb
CHANGED
@@ -4,30 +4,73 @@ module GitPr
|
|
4
4
|
|
5
5
|
def self.ensure_remotes_for_pull_request git, pull
|
6
6
|
source_remote = GitPr.ensure_remote_for_project(git,
|
7
|
-
pull
|
8
|
-
pull
|
9
|
-
pull
|
7
|
+
pull.head.user.login,
|
8
|
+
pull.head.repo.ssh_url,
|
9
|
+
pull.head.repo.git_url)
|
10
10
|
|
11
11
|
target_remote = GitPr.ensure_remote_for_project(git,
|
12
|
-
pull
|
13
|
-
pull
|
14
|
-
pull
|
12
|
+
pull.base.user.login,
|
13
|
+
pull.base.repo.ssh_url,
|
14
|
+
pull.base.repo.git_url)
|
15
15
|
|
16
16
|
[source_remote, target_remote]
|
17
17
|
end
|
18
18
|
|
19
|
-
def self.merge_pull_cleanly git, pull
|
19
|
+
def self.merge_pull_cleanly git, pull, command_options
|
20
|
+
unless command_options.yolo
|
21
|
+
case pull.state
|
22
|
+
when 'failure'
|
23
|
+
failed_statuses = pull.statuses.select { |s| s.state == 'failure' }
|
24
|
+
max_context = failed_statuses.map { |s| s.context.length }.max
|
25
|
+
puts <<EOS
|
26
|
+
#{"ERROR".red}: One or more status checks have failed on this pull request!
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
#{" " * (max_context + 5)}(cmd-double-click to open links)
|
29
|
+
EOS
|
30
|
+
failed_statuses.each do |status|
|
31
|
+
puts "#{GitPr::PullRequest.summary_icon(status.state)} #{status.context.ljust(max_context)} #{status.target_url}"
|
32
|
+
end
|
33
|
+
|
34
|
+
puts <<EOS
|
35
|
+
|
36
|
+
If you're still sure you want to merge, call again with --yolo: 'git pr merge --yolo #{pull.number}'
|
37
|
+
EOS
|
38
|
+
exit 1
|
39
|
+
when 'success'
|
40
|
+
nil
|
41
|
+
else
|
42
|
+
unless pull.statuses.empty?
|
43
|
+
pending_statuses = pull.statuses.select { |s| s.state == 'pending' }
|
44
|
+
max_context = pending_statuses.map { |s| s.context.length }.max
|
45
|
+
puts <<EOS
|
46
|
+
#{"WARNING".yellow}: One or more status checks is in progress on this pull request.
|
47
|
+
You should let them finish.
|
48
|
+
|
49
|
+
#{" " * (max_context + 5)}(cmd-double-click to open links)
|
50
|
+
EOS
|
51
|
+
pending_statuses.each do |status|
|
52
|
+
puts "#{GitPr::PullRequest.summary_icon(status.state)} #{status.context.ljust(max_context)} #{status.target_url}"
|
53
|
+
end
|
54
|
+
|
55
|
+
puts <<EOS
|
56
|
+
|
57
|
+
If you're still sure you want to merge, call again with --yolo: 'git pr merge --yolo #{pull.number}'
|
58
|
+
EOS
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
25
63
|
|
26
|
-
|
27
|
-
|
28
|
-
|
64
|
+
pull_number = pull.number
|
65
|
+
source_branch = pull.head.ref
|
66
|
+
source_repo_ssh_url = pull.head.repo.git_url
|
67
|
+
source_repo_clone_url = pull.head.repo.clone_url
|
29
68
|
|
30
|
-
|
69
|
+
target_branch = pull.base.ref
|
70
|
+
target_repo_ssh_url = pull.base.repo.git_url
|
71
|
+
target_repo_clone_url = pull.base.repo.clone_url
|
72
|
+
|
73
|
+
puts "Merging #{pull.summary}".cyan
|
31
74
|
puts "#{target_repo_ssh_url}/#{target_branch} <= #{source_repo_ssh_url}/#{source_branch}\n".cyan
|
32
75
|
|
33
76
|
# find or add a remote for the PR
|
@@ -106,9 +149,9 @@ module GitPr
|
|
106
149
|
puts "Merging changes from '#{rebase_branch}' to '#{target_branch}'"
|
107
150
|
GitPr.run_command "git checkout -q #{target_branch}"
|
108
151
|
commit_message = <<EOS
|
109
|
-
Merge #{
|
152
|
+
Merge #{pull.summary}
|
110
153
|
|
111
|
-
#{pull
|
154
|
+
#{pull.body}
|
112
155
|
EOS
|
113
156
|
GitPr.run_command "git merge --no-ff #{rebase_branch} -m #{Shellwords.escape commit_message}"
|
114
157
|
|
@@ -139,15 +182,16 @@ EOS
|
|
139
182
|
if GitPr.prompt "\nDo you want to proceed with the merge (y/n)? ".cyan
|
140
183
|
puts "Pushing changes to '#{target_remote}'"
|
141
184
|
GitPr.run_command "git push #{target_remote} #{target_branch} 2>&1"
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
puts "Feature branch '#{source_branch}' deleted. To restore it, run: " + "git branch #{source_branch} #{source_branch_sha}".green
|
185
|
+
|
186
|
+
# Delete the remote and local feature branches
|
187
|
+
source_branch_sha = git.branches["#{source_remote}/#{source_branch}"].gcommit.sha[0..6]
|
188
|
+
GitPr.run_command "git push #{source_remote} :#{source_branch} 2>&1"
|
189
|
+
if git.is_local_branch? source_branch
|
190
|
+
source_branch_sha = git.branches[source_branch].gcommit.sha[0..6]
|
191
|
+
GitPr.run_command "git branch -D #{source_branch}"
|
150
192
|
end
|
193
|
+
puts "Feature branch '#{source_branch}' deleted. To restore it, run: " + "git branch #{source_branch} #{source_branch_sha}".green
|
194
|
+
|
151
195
|
puts "\nMerge complete!".cyan
|
152
196
|
else
|
153
197
|
puts "\nUndoing local merge"
|
data/lib/git_pr/pull_request.rb
CHANGED
@@ -4,6 +4,46 @@ module GitPr
|
|
4
4
|
def initialize(pull)
|
5
5
|
@pull = pull
|
6
6
|
end
|
7
|
+
|
8
|
+
def status
|
9
|
+
unless @_status
|
10
|
+
@_status = Octokit.status(@pull.base.repo.full_name, @pull.head.sha, :accept => Octokit::Client::Statuses::COMBINED_STATUS_MEDIA_TYPE)
|
11
|
+
end
|
12
|
+
@_status
|
13
|
+
end
|
14
|
+
|
15
|
+
def state
|
16
|
+
self.status.state
|
17
|
+
end
|
18
|
+
|
19
|
+
def statuses
|
20
|
+
self.status.statuses
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.summary_icon(state)
|
24
|
+
case state
|
25
|
+
when "failure"
|
26
|
+
STDOUT.tty? ? "\u2717".red : "-"
|
27
|
+
when "success"
|
28
|
+
STDOUT.tty? ? "\u2713".green : "+"
|
29
|
+
else
|
30
|
+
STDOUT.tty? ? "\u25CF".yellow : "O"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def summary(include_status = false)
|
35
|
+
if include_status
|
36
|
+
status_string = "#{PullRequest.summary_icon(self.state)} "
|
37
|
+
else
|
38
|
+
status_string = ""
|
39
|
+
end
|
40
|
+
"#{status_string}##{@pull.number} from #{@pull.user.login}: #{@pull.title}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(method_name, *args, &block)
|
44
|
+
@pull.send method_name, *args, &block
|
45
|
+
end
|
46
|
+
|
7
47
|
end
|
8
48
|
|
9
49
|
end
|
data/lib/git_pr/version.rb
CHANGED
data/lib/git_pr.rb
CHANGED