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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d7b026f77b603e491fcb40a97fba29f9eb12c5a8
4
- data.tar.gz: b950b8dee8e1b081ed4c2bb95033b9efdd192458
3
+ metadata.gz: 7e547458a924539d3d3f6e960d4d7d00bd14bd65
4
+ data.tar.gz: de36ad310f6c68800bc87f2c25c952e406cac2e8
5
5
  SHA512:
6
- metadata.gz: 53b72813791e5837ad5d3b50671eb2ceb0d9ef06e7ce92237c729acf5eaa47ee04b054f13866b21e6f81611ef2f935cc84ef2644542075b66625ac8ef56e16f9
7
- data.tar.gz: 4fb865efda40700eb11588bf83cfa5dd945d22181e7e2865273b5b0fdb6b531af048b07c282164a9401fa2445a006dd888d4b2235dfa3830be3b1ab7caabd0cc
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
- # opts.separator "\nMerge command options"
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 "#{github_project}"
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 pull_summary(p, include_status) }
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 "##{pull.number} from #{pull[:user][:login]}: #{pull.title}\n\n"
390
- statuses = Octokit.statuses(pull.base.repo.full_name, pull.head.sha)
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
- statuses_by_context = {}
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
- statuses_by_context.each do |context, status|
406
- puts "#{status_summary(status.state)} #{status.context.ljust(max_context)} #{status.target_url}"
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
- success = statuses_by_context.all? { |c, s| s.state == 'success' }
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[:head][:user][:login],
8
- pull[:head][:repo][:ssh_url],
9
- pull[:head][:repo][:git_url])
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[:base][:user][:login],
13
- pull[:base][:repo][:ssh_url],
14
- pull[:base][:repo][:git_url])
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
- pull_number = pull[:number]
22
- source_branch = pull[:head][:ref]
23
- source_repo_ssh_url = pull[:head][:repo][:git_url]
24
- source_repo_clone_url = pull[:head][:repo][:clone_url]
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
- target_branch = pull[:base][:ref]
27
- target_repo_ssh_url = pull[:base][:repo][:git_url]
28
- target_repo_clone_url = pull[:base][:repo][:clone_url]
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
- puts "Merging #{pull_summary(pull)}".cyan
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 #{pull_summary(pull)}
152
+ Merge #{pull.summary}
110
153
 
111
- #{pull[:body]}
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
- if GitPr.prompt "\nDo you want to delete the feature branch (y/n)? ".cyan
143
- source_branch_sha = git.branches["#{source_remote}/#{source_branch}"].gcommit.sha[0..6]
144
- GitPr.run_command "git push #{source_remote} :#{source_branch} 2>&1"
145
- if git.is_local_branch? source_branch
146
- source_branch_sha = git.branches[source_branch].gcommit.sha[0..6]
147
- GitPr.run_command "git branch -D #{source_branch}"
148
- end
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"
@@ -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
@@ -1,3 +1,3 @@
1
1
  module GitPr
2
- VERSION = "0.0.14.beta3"
2
+ VERSION = "0.0.14.beta4"
3
3
  end
data/lib/git_pr.rb CHANGED
@@ -27,10 +27,11 @@ module GitPr
27
27
  state = `stty -g`
28
28
  `stty raw -echo -icanon isig`
29
29
 
30
- STDIN.getc.chr
30
+ c = STDIN.getc.chr
31
+ c
31
32
  ensure
32
33
  `stty #{state}`
33
- puts ""
34
+ puts "#{c}"
34
35
  end
35
36
 
36
37
  def self.prompt prompt
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_pr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14.beta3
4
+ version: 0.0.14.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Sharon