git-review 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/git-review.rb +73 -63
- metadata +3 -3
data/lib/git-review.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
require 'octokit'
|
3
3
|
# Launchy is used in 'browse' to open a browser.
|
4
4
|
require 'launchy'
|
5
|
+
# Time is used to parse time strings from git back into Time objects.
|
6
|
+
require 'time'
|
5
7
|
|
6
8
|
class GitReview
|
7
9
|
|
@@ -35,20 +37,16 @@ class GitReview
|
|
35
37
|
return unless request_exists?
|
36
38
|
option = @args.shift == '--full' ? '' : '--stat '
|
37
39
|
sha = @pending_request['head']['sha']
|
38
|
-
puts "
|
40
|
+
puts "ID : #{@pending_request['number']}"
|
39
41
|
puts "Label : #{@pending_request['head']['label']}"
|
40
|
-
puts "
|
41
|
-
puts "Votes : #{@pending_request['votes']}"
|
42
|
+
puts "Updated : #{Time.parse(@pending_request['updated_at']).strftime('%d-%b-%y')}"
|
42
43
|
puts "Comments : #{@pending_request['comments']}"
|
43
44
|
puts
|
44
|
-
puts
|
45
|
-
puts 'Body :'
|
45
|
+
puts @pending_request['title']
|
46
46
|
puts
|
47
47
|
puts @pending_request['body']
|
48
48
|
puts
|
49
|
-
puts
|
50
|
-
puts
|
51
|
-
puts git("diff --color=always #{option}HEAD...#{sha}")
|
49
|
+
puts git_call("diff --color=always #{option}HEAD...#{sha}")
|
52
50
|
end
|
53
51
|
|
54
52
|
# Open a browser window and review a specified request.
|
@@ -64,7 +62,7 @@ class GitReview
|
|
64
62
|
puts
|
65
63
|
puts ' git checkout master'
|
66
64
|
puts
|
67
|
-
|
65
|
+
git_call "checkout origin/#{@pending_request['head']['ref']}"
|
68
66
|
end
|
69
67
|
|
70
68
|
# Accept a specified request by merging it into master.
|
@@ -92,7 +90,7 @@ class GitReview
|
|
92
90
|
puts 'Merge command:'
|
93
91
|
puts " git #{exec_cmd}"
|
94
92
|
puts
|
95
|
-
|
93
|
+
puts git_call(exec_cmd)
|
96
94
|
end
|
97
95
|
|
98
96
|
# Close a specified request.
|
@@ -105,16 +103,16 @@ class GitReview
|
|
105
103
|
# Create a new request.
|
106
104
|
# TODO: Support creating requests to other repositories and branches (like the original repo, this has been forked from).
|
107
105
|
def create
|
108
|
-
|
106
|
+
prepare
|
109
107
|
# Gather information.
|
110
108
|
last_request_id = @pending_requests.collect{|req| req['number'] }.sort.last.to_i
|
111
|
-
title = "[Review] Request from '#{
|
109
|
+
title = "[Review] Request from '#{git_config['github.login']}' @ '#{source}'"
|
112
110
|
# TODO: Insert commit messages (that are not yet in master) into body (since this will be displayed inside the mail that is sent out).
|
113
111
|
body = 'Please review the following changes:'
|
114
112
|
# Create the actual pull request.
|
115
113
|
Octokit.create_pull_request(target_repo, target_branch, source_branch, title, body)
|
116
114
|
# Switch back to target_branch and check for success.
|
117
|
-
|
115
|
+
git_call "checkout #{target_branch}"
|
118
116
|
update
|
119
117
|
potential_new_request = @pending_requests.find{ |req| req['title'] == title }
|
120
118
|
puts 'Successfully created new request.' if potential_new_request['number'] > last_request_id
|
@@ -156,13 +154,13 @@ class GitReview
|
|
156
154
|
puts 'Manage review workflow for projects hosted on GitHub (using pull requests).'
|
157
155
|
puts
|
158
156
|
puts 'Available commands:'
|
159
|
-
puts '
|
160
|
-
puts '
|
161
|
-
puts '
|
162
|
-
puts '
|
163
|
-
puts '
|
164
|
-
puts '
|
165
|
-
puts '
|
157
|
+
puts ' list [--reverse] List all pending requests.'
|
158
|
+
puts ' show <number> [--full] Show details of a single request.'
|
159
|
+
puts ' browse <number> Open a browser window and review a specified request.'
|
160
|
+
puts ' checkout <number> Checkout a specified request\'s changes to your local repository.'
|
161
|
+
puts ' merge <number> Accept a specified request by merging it into master.'
|
162
|
+
puts ' close <number> Close a specified request.'
|
163
|
+
puts ' create Create a new request.'
|
166
164
|
end
|
167
165
|
|
168
166
|
# Check existence of specified request and assign @pending_request.
|
@@ -192,7 +190,7 @@ class GitReview
|
|
192
190
|
end
|
193
191
|
host = URI.parse(github_endpoint).host
|
194
192
|
repos.uniq.compact.each do |repo|
|
195
|
-
|
193
|
+
git_call("fetch git@#{host}:#{repo}.git +refs/heads/*:refs/pr/#{repo}/*")
|
196
194
|
end
|
197
195
|
end
|
198
196
|
|
@@ -208,22 +206,29 @@ class GitReview
|
|
208
206
|
branch_name = gets.chomp.gsub(/\W+/, '_').downcase
|
209
207
|
end
|
210
208
|
# Create the new branch (as a copy of the current one).
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
209
|
+
local_branch = "review_#{Time.now.strftime("%y%m%d")}_#{branch_name}"
|
210
|
+
git_call "checkout -b #{local_branch}"
|
211
|
+
if source_branch == local_branch
|
212
|
+
# Go back to master and get rid of pending commits (as these are now on the new branch).
|
213
|
+
git_call "checkout #{target_branch}"
|
214
|
+
git_call "reset --hard origin/#{target_branch}"
|
215
|
+
git_call "checkout #{local_branch}"
|
216
|
+
end
|
217
217
|
end
|
218
218
|
# Push latest commits to the remote branch (and by that, create it if necessary).
|
219
|
-
|
219
|
+
git_call "push origin"
|
220
220
|
end
|
221
221
|
|
222
222
|
# System call to 'git'.
|
223
|
-
def
|
224
|
-
|
225
|
-
|
226
|
-
|
223
|
+
def git_call(command, verbose = debug_mode)
|
224
|
+
if verbose
|
225
|
+
puts
|
226
|
+
puts " git #{command}"
|
227
|
+
puts
|
228
|
+
end
|
229
|
+
output = `git #{command}`
|
230
|
+
puts output if verbose and not output.empty?
|
231
|
+
output
|
227
232
|
end
|
228
233
|
|
229
234
|
# Display helper to make output more configurable.
|
@@ -238,7 +243,7 @@ class GitReview
|
|
238
243
|
|
239
244
|
# Returns a string that specifies the source branch.
|
240
245
|
def source_branch
|
241
|
-
|
246
|
+
git_call('branch').chomp!.match(/\*(.*)/)[0][2..-1]
|
242
247
|
end
|
243
248
|
|
244
249
|
# Returns a string consisting of source repo and branch.
|
@@ -265,51 +270,56 @@ class GitReview
|
|
265
270
|
|
266
271
|
# Returns a boolean stating whether a specified commit has already been merged.
|
267
272
|
def merged?(sha)
|
268
|
-
not
|
273
|
+
not git_call("rev-list #{sha} ^HEAD 2>&1").split("\n").size > 0
|
269
274
|
end
|
270
275
|
|
271
|
-
#
|
276
|
+
# Uses Octokit to access GitHub.
|
272
277
|
def configure_github_access
|
273
|
-
if
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
config
|
278
|
+
if git_config['github.login'] and git_config['github.token']
|
279
|
+
Octokit.configure do |config|
|
280
|
+
config.login = git_config['github.login']
|
281
|
+
config.token = git_config['github.token']
|
282
|
+
config.endpoint = github_endpoint
|
283
|
+
end
|
284
|
+
true
|
285
|
+
else
|
286
|
+
puts 'Please update your git config and provide your GitHub login and token.'
|
287
|
+
puts
|
288
|
+
puts ' git config --global github.login your_github_login_1234567890'
|
289
|
+
puts ' git config --global github.token your_github_token_1234567890'
|
290
|
+
puts
|
291
|
+
false
|
282
292
|
end
|
283
|
-
true
|
284
293
|
end
|
285
294
|
|
286
|
-
#
|
287
|
-
def
|
288
|
-
|
295
|
+
# Determine GitHub endpoint (defaults to 'https://github.com/').
|
296
|
+
def github_endpoint
|
297
|
+
git_config['github.endpoint'] || 'https://github.com/'
|
289
298
|
end
|
290
299
|
|
291
|
-
|
292
|
-
|
293
|
-
git('config --get-all github.token')
|
300
|
+
def debug_mode
|
301
|
+
git_config['review.mode'] == 'debug'
|
294
302
|
end
|
295
303
|
|
296
|
-
#
|
297
|
-
|
298
|
-
|
299
|
-
|
304
|
+
# Collect git config information in a Hash for easy access.
|
305
|
+
# Checks '~/.gitconfig' for credentials.
|
306
|
+
def git_config
|
307
|
+
unless @git_config
|
308
|
+
# Read @git_config from local git config.
|
309
|
+
@git_config = {}
|
310
|
+
config_list = git_call('config --list', false)
|
311
|
+
config_list.split("\n").each do |line|
|
312
|
+
key, value = line.split('=')
|
313
|
+
@git_config[key] = value
|
314
|
+
end
|
315
|
+
end
|
316
|
+
@git_config
|
300
317
|
end
|
301
318
|
|
302
319
|
# Returns an array consisting of information on the user and the project.
|
303
320
|
def repo_info
|
304
|
-
# Read config_hash from local git config.
|
305
|
-
config_hash = {}
|
306
|
-
config = git('config --list')
|
307
|
-
config.split("\n").each do |line|
|
308
|
-
key, value = line.split('=')
|
309
|
-
config_hash[key] = value
|
310
|
-
end
|
311
321
|
# Extract user and project name from GitHub URL.
|
312
|
-
url =
|
322
|
+
url = git_config['remote.origin.url']
|
313
323
|
if url.nil?
|
314
324
|
puts "Error: Not a git repository."
|
315
325
|
return [nil, nil]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-review
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 0.7.
|
9
|
+
- 2
|
10
|
+
version: 0.7.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dominik Bamberger, Cristian Messel
|