git-review 1.1.3 → 1.1.5
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.
- data/lib/git-review.rb +124 -49
- metadata +23 -7
data/lib/git-review.rb
CHANGED
@@ -4,6 +4,9 @@ require 'octokit'
|
|
4
4
|
require 'launchy'
|
5
5
|
# Time is used to parse time strings from git back into Time objects.
|
6
6
|
require 'time'
|
7
|
+
# tempfile is used to create a temporary file containing PR's title and body.
|
8
|
+
# This file is going to be edited by the system editor.
|
9
|
+
require 'tempfile'
|
7
10
|
|
8
11
|
# A custom error to raise, if we know we can't go on.
|
9
12
|
class UnprocessableState < StandardError
|
@@ -16,27 +19,30 @@ class GitReview
|
|
16
19
|
|
17
20
|
# List all pending requests.
|
18
21
|
def list
|
19
|
-
|
20
|
-
|
21
|
-
# Find only pending (= unmerged) requests and output summary.
|
22
|
-
#
|
23
|
-
next if merged?(
|
24
|
-
line = format_text(
|
25
|
-
date_string = format_time(
|
22
|
+
output = @current_requests.collect do |request|
|
23
|
+
details = @github.pull_request(source_repo, request.number)
|
24
|
+
# Find only pending (= unmerged) requests and output summary.
|
25
|
+
# Explicitly look for local changes (that GitHub does not yet know about).
|
26
|
+
next if merged?(request.head.sha)
|
27
|
+
line = format_text(request.number, 8)
|
28
|
+
date_string = format_time(request.updated_at)
|
26
29
|
line << format_text(date_string, 11)
|
27
|
-
line << format_text(
|
28
|
-
line << format_text(
|
30
|
+
line << format_text(details.comments + details.review_comments, 10)
|
31
|
+
line << format_text(request.title, 91)
|
29
32
|
line
|
30
33
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
output.compact!
|
35
|
+
if output.empty?
|
36
|
+
puts "No pending requests for '#{source}'."
|
37
|
+
else
|
38
|
+
puts "Pending requests for '#{source}':"
|
39
|
+
puts 'ID Updated Comments Title'
|
40
|
+
output.reverse! if @args.shift == '--reverse'
|
41
|
+
output.each { |line| puts line }
|
34
42
|
end
|
35
|
-
puts "Pending requests for '#{source}'"
|
36
|
-
puts 'ID Updated Comments Title'
|
37
|
-
puts output.compact
|
38
43
|
end
|
39
44
|
|
45
|
+
|
40
46
|
# Show details for a single request.
|
41
47
|
def show
|
42
48
|
return unless request_exists?
|
@@ -58,11 +64,13 @@ class GitReview
|
|
58
64
|
discussion
|
59
65
|
end
|
60
66
|
|
67
|
+
|
61
68
|
# Open a browser window and review a specified request.
|
62
69
|
def browse
|
63
70
|
Launchy.open(@current_request['html_url']) if request_exists?
|
64
71
|
end
|
65
72
|
|
73
|
+
|
66
74
|
# Checkout a specified request's changes to your local repository.
|
67
75
|
def checkout
|
68
76
|
return unless request_exists?
|
@@ -75,6 +83,7 @@ class GitReview
|
|
75
83
|
git_call "checkout #{create_local_branch}#{@current_request['head']['ref']}"
|
76
84
|
end
|
77
85
|
|
86
|
+
|
78
87
|
# Accept a specified request by merging it into master.
|
79
88
|
def merge
|
80
89
|
return unless request_exists?
|
@@ -104,6 +113,7 @@ class GitReview
|
|
104
113
|
puts git_call(exec_cmd)
|
105
114
|
end
|
106
115
|
|
116
|
+
|
107
117
|
# Add an approving comment to the request.
|
108
118
|
def approve
|
109
119
|
return unless request_exists?
|
@@ -116,6 +126,7 @@ class GitReview
|
|
116
126
|
end
|
117
127
|
end
|
118
128
|
|
129
|
+
|
119
130
|
# Close a specified request.
|
120
131
|
def close
|
121
132
|
return unless request_exists?
|
@@ -123,6 +134,7 @@ class GitReview
|
|
123
134
|
puts 'Successfully closed request.' unless request_exists?('open', @current_request['number'])
|
124
135
|
end
|
125
136
|
|
137
|
+
|
126
138
|
# Prepare local repository to create a new request.
|
127
139
|
# Sets @local_branch.
|
128
140
|
def prepare
|
@@ -154,6 +166,7 @@ class GitReview
|
|
154
166
|
end
|
155
167
|
end
|
156
168
|
|
169
|
+
|
157
170
|
# Create a new request.
|
158
171
|
# TODO: Support creating requests to other repositories and branches (like the original repo, this has been forked from).
|
159
172
|
def create
|
@@ -168,18 +181,17 @@ class GitReview
|
|
168
181
|
# Push latest commits to the remote branch (and by that, create it if necessary).
|
169
182
|
git_call "push --set-upstream origin #{@local_branch}", debug_mode, true
|
170
183
|
# Gather information.
|
171
|
-
last_request_id = @current_requests.collect{|req| req['number'] }.sort.last.to_i
|
172
|
-
title =
|
173
|
-
# TODO: Insert commit messages (that are not yet in master) into body (since this will be displayed inside the mail that is sent out).
|
174
|
-
body = 'Please review the following changes:'
|
184
|
+
last_request_id = @current_requests.collect { |req| req['number'] }.sort.last.to_i
|
185
|
+
title, body = create_title_and_body(target_branch)
|
175
186
|
# Create the actual pull request.
|
176
187
|
@github.create_pull_request target_repo, target_branch, source_branch, title, body
|
177
188
|
# Switch back to target_branch and check for success.
|
178
189
|
git_call "checkout #{target_branch}"
|
179
190
|
update
|
180
|
-
potential_new_request = @current_requests.find{ |req| req['title'] == title }
|
191
|
+
potential_new_request = @current_requests.find { |req| req['title'] == title }
|
181
192
|
if potential_new_request and potential_new_request['number'] > last_request_id
|
182
|
-
puts "Successfully created new request ##{potential_new_request['number']}
|
193
|
+
puts "Successfully created new request ##{potential_new_request['number']}" \
|
194
|
+
"(#{File.join("https://github.com", target_repo, "pull", potential_new_request['number'].to_s)})."
|
183
195
|
end
|
184
196
|
# Return to the user's original branch.
|
185
197
|
git_call "checkout #{@original_branch}"
|
@@ -188,10 +200,11 @@ class GitReview
|
|
188
200
|
end
|
189
201
|
end
|
190
202
|
|
203
|
+
|
191
204
|
# Deletes obsolete branches (left over from already closed requests).
|
192
205
|
def clean
|
193
206
|
# Pruning is needed to remove already deleted branches from your local track.
|
194
|
-
git_call
|
207
|
+
git_call 'remote prune origin'
|
195
208
|
# Determine strategy to clean.
|
196
209
|
case @args.size
|
197
210
|
when 0
|
@@ -212,6 +225,7 @@ class GitReview
|
|
212
225
|
end
|
213
226
|
end
|
214
227
|
|
228
|
+
|
215
229
|
# Start a console session (used for debugging).
|
216
230
|
def console
|
217
231
|
puts 'Entering debug console.'
|
@@ -226,13 +240,12 @@ class GitReview
|
|
226
240
|
private
|
227
241
|
|
228
242
|
# Setup variables and call actual commands.
|
229
|
-
def initialize(args)
|
243
|
+
def initialize(args = [])
|
244
|
+
@args = args
|
230
245
|
command = args.shift
|
231
246
|
if command and self.respond_to?(command)
|
232
247
|
@user, @repo = repo_info
|
233
|
-
return
|
234
|
-
@args = args
|
235
|
-
return unless configure_github_access
|
248
|
+
return unless @user && @repo && configure_github_access
|
236
249
|
update unless command == 'clean'
|
237
250
|
self.send command
|
238
251
|
else
|
@@ -245,6 +258,7 @@ class GitReview
|
|
245
258
|
puts 'Execution of git-review command stopped.'
|
246
259
|
end
|
247
260
|
|
261
|
+
|
248
262
|
# Show a quick reference of available commands.
|
249
263
|
def help
|
250
264
|
puts 'Usage: git review <command>'
|
@@ -261,9 +275,10 @@ class GitReview
|
|
261
275
|
puts ' prepare Creates a new local branch for a request.'
|
262
276
|
puts ' create Create a new request.'
|
263
277
|
puts ' clean <ID> [--force] Delete a request\'s remote and local branches.'
|
264
|
-
puts ' clean --all
|
278
|
+
puts ' clean --all Delete all obsolete branches.'
|
265
279
|
end
|
266
280
|
|
281
|
+
|
267
282
|
# Check existence of specified request and assign @current_request.
|
268
283
|
def request_exists?(state = 'open', request_id = nil)
|
269
284
|
# NOTE: If request_id is set explicitly we might need to update to get the
|
@@ -275,7 +290,7 @@ class GitReview
|
|
275
290
|
puts 'Please specify a valid ID.'
|
276
291
|
return false
|
277
292
|
end
|
278
|
-
@current_request = @current_requests.find{ |req| req['number'] == request_id }
|
293
|
+
@current_request = @current_requests.find { |req| req['number'] == request_id }
|
279
294
|
unless @current_request
|
280
295
|
# Additional try to get an older request from Github by specifying the number.
|
281
296
|
request = @github.pull_request source_repo, request_id
|
@@ -290,18 +305,20 @@ class GitReview
|
|
290
305
|
end
|
291
306
|
end
|
292
307
|
|
308
|
+
|
293
309
|
# Get latest changes from GitHub.
|
294
310
|
def update(state = 'open')
|
295
|
-
@current_requests = @github.pull_requests
|
296
|
-
repos = @current_requests.collect do |
|
297
|
-
repo =
|
298
|
-
"#{repo
|
311
|
+
@current_requests = @github.pull_requests(source_repo, state)
|
312
|
+
repos = @current_requests.collect do |request|
|
313
|
+
repo = request.head.repository
|
314
|
+
"#{repo.owner}/#{repo.name}" if repo
|
299
315
|
end
|
300
316
|
repos.uniq.compact.each do |repo|
|
301
|
-
git_call
|
317
|
+
git_call "fetch git@github.com:#{repo}.git +refs/heads/*:refs/pr/#{repo}/*"
|
302
318
|
end
|
303
319
|
end
|
304
320
|
|
321
|
+
|
305
322
|
# Cleans a single request's obsolete branches.
|
306
323
|
def clean_single(force_deletion = false)
|
307
324
|
update('closed')
|
@@ -314,15 +331,16 @@ class GitReview
|
|
314
331
|
delete_branch(branch_name)
|
315
332
|
end
|
316
333
|
|
334
|
+
|
317
335
|
# Cleans all obsolete branches.
|
318
336
|
def clean_all
|
319
337
|
update
|
320
338
|
# Protect all open requests' branches from deletion.
|
321
|
-
protected_branches = @current_requests.collect{|request| request['head']['ref']}
|
339
|
+
protected_branches = @current_requests.collect { |request| request['head']['ref'] }
|
322
340
|
# Select all branches with the correct prefix.
|
323
|
-
review_branches = all_branches.select{|branch| branch.include?('review_')}
|
341
|
+
review_branches = all_branches.select { |branch| branch.include?('review_') }
|
324
342
|
# Only use uniq branch names (no matter if local or remote).
|
325
|
-
review_branches.collect{|branch| branch.split('/').last}.uniq.each do |branch_name|
|
343
|
+
review_branches.collect { |branch| branch.split('/').last }.uniq.each do |branch_name|
|
326
344
|
# Only clean up obsolete branches.
|
327
345
|
unless protected_branches.include?(branch_name) or unmerged_commits?(branch_name, false)
|
328
346
|
delete_branch(branch_name)
|
@@ -330,6 +348,7 @@ class GitReview
|
|
330
348
|
end
|
331
349
|
end
|
332
350
|
|
351
|
+
|
333
352
|
# Delete local and remote branches that match a given name.
|
334
353
|
def delete_branch(branch_name)
|
335
354
|
# Delete local branch if it exists.
|
@@ -338,6 +357,7 @@ class GitReview
|
|
338
357
|
git_call("push origin :#{branch_name}", true) if branch_exists?(:remote, branch_name)
|
339
358
|
end
|
340
359
|
|
360
|
+
|
341
361
|
# Returns a boolean stating whether there are unmerged commits on the local or remote branch.
|
342
362
|
def unmerged_commits?(branch_name, verbose = true)
|
343
363
|
locations = []
|
@@ -354,7 +374,7 @@ class GitReview
|
|
354
374
|
end
|
355
375
|
# Select commits (= non empty, not just an error message and not only duplicate commits staring with '-').
|
356
376
|
unmerged_commits = responses.reject do |response|
|
357
|
-
response.empty? or response.include?('fatal: Unknown commit') or response.split("\n").reject{|x| x.index('-') == 0}.empty?
|
377
|
+
response.empty? or response.include?('fatal: Unknown commit') or response.split("\n").reject { |x| x.index('-') == 0 }.empty?
|
358
378
|
end
|
359
379
|
# If the array ain't empty, we got unmerged commits.
|
360
380
|
if unmerged_commits.empty?
|
@@ -365,6 +385,7 @@ class GitReview
|
|
365
385
|
end
|
366
386
|
end
|
367
387
|
|
388
|
+
|
368
389
|
# Returns a boolean stating whether a branch exists in a specified location.
|
369
390
|
def branch_exists?(location, branch_name)
|
370
391
|
return false unless [:remote, :local].include? location
|
@@ -372,6 +393,7 @@ class GitReview
|
|
372
393
|
all_branches.include?(prefix + branch_name)
|
373
394
|
end
|
374
395
|
|
396
|
+
|
375
397
|
# System call to 'git'.
|
376
398
|
def git_call(command, verbose = debug_mode, enforce_success = false)
|
377
399
|
if verbose
|
@@ -389,6 +411,7 @@ class GitReview
|
|
389
411
|
output
|
390
412
|
end
|
391
413
|
|
414
|
+
|
392
415
|
# Show current discussion for @current_request.
|
393
416
|
def discussion
|
394
417
|
request = @github.pull_request source_repo, @current_request['number']
|
@@ -404,7 +427,7 @@ class GitReview
|
|
404
427
|
when "IssueComment", "CommitComment", "PullRequestReviewComment"
|
405
428
|
output << "added a comment"
|
406
429
|
output << " to \e[36m#{entry['commit_id'][0..6]}\e[m" if entry['commit_id']
|
407
|
-
output <<
|
430
|
+
output << " on #{format_time(entry['created_at'])}"
|
408
431
|
unless entry['created_at'] == entry['updated_at']
|
409
432
|
output << " (updated on #{format_time(entry['updated_at'])})"
|
410
433
|
end
|
@@ -413,75 +436,86 @@ class GitReview
|
|
413
436
|
output << entry['body']
|
414
437
|
# Commits:
|
415
438
|
when "Commit"
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
439
|
+
output << "authored commit \e[36m#{entry['id'][0..6]}\e[m on #{format_time(entry['authored_date'])}"
|
440
|
+
unless entry['authored_date'] == entry['committed_date']
|
441
|
+
output << " (committed on #{format_time(entry['committed_date'])})"
|
442
|
+
end
|
443
|
+
output << ":\n#{''.rjust(output.length + 1, "-")}\n#{entry["message"]}"
|
421
444
|
end
|
422
445
|
output << "\n\n\n"
|
423
446
|
end
|
424
447
|
puts result.compact unless result.empty?
|
425
448
|
end
|
426
449
|
|
450
|
+
|
427
451
|
# Display helper to make output more configurable.
|
428
452
|
def format_text(info, size)
|
429
453
|
info.to_s.gsub("\n", ' ')[0, size-1].ljust(size)
|
430
454
|
end
|
431
455
|
|
456
|
+
|
432
457
|
# Display helper to unify time output.
|
433
458
|
def format_time(time_string)
|
434
459
|
Time.parse(time_string).strftime('%d-%b-%y')
|
435
460
|
end
|
436
461
|
|
462
|
+
|
437
463
|
# Returns a string that specifies the source repo.
|
438
464
|
def source_repo
|
439
465
|
"#{@user}/#{@repo}"
|
440
466
|
end
|
441
467
|
|
468
|
+
|
442
469
|
# Returns a string that specifies the source branch.
|
443
470
|
def source_branch
|
444
471
|
git_call('branch').chomp!.match(/\*(.*)/)[0][2..-1]
|
445
472
|
end
|
446
473
|
|
474
|
+
|
447
475
|
# Returns a string consisting of source repo and branch.
|
448
476
|
def source
|
449
477
|
"#{source_repo}/#{source_branch}"
|
450
478
|
end
|
451
479
|
|
480
|
+
|
452
481
|
# Returns a string that specifies the target repo.
|
453
482
|
def target_repo
|
454
483
|
# TODO: Enable possibility to manually override this and set arbitrary repositories.
|
455
484
|
source_repo
|
456
485
|
end
|
457
486
|
|
487
|
+
|
458
488
|
# Returns a string that specifies the target branch.
|
459
489
|
def target_branch
|
460
490
|
# TODO: Enable possibility to manually override this and set arbitrary branches.
|
461
491
|
ENV['TARGET_BRANCH'] || 'master'
|
462
492
|
end
|
463
493
|
|
494
|
+
|
464
495
|
# Returns a string consisting of target repo and branch.
|
465
496
|
def target
|
466
497
|
"#{target_repo}/#{target_branch}"
|
467
498
|
end
|
468
499
|
|
500
|
+
|
469
501
|
# Returns an Array of all existing branches.
|
470
502
|
def all_branches
|
471
|
-
@branches ||= git_call('branch -a').split("\n").collect{|s|s.strip}
|
503
|
+
@branches ||= git_call('branch -a').split("\n").collect { |s| s.strip }
|
472
504
|
end
|
473
505
|
|
506
|
+
|
474
507
|
# Returns a boolean stating whether a specified commit has already been merged.
|
475
508
|
def merged?(sha)
|
476
509
|
not git_call("rev-list #{sha} ^HEAD 2>&1").split("\n").size > 0
|
477
510
|
end
|
478
511
|
|
512
|
+
|
479
513
|
# Uses Octokit to access GitHub.
|
480
514
|
def configure_github_access
|
481
515
|
if git_config['github.login'] and git_config['github.password']
|
482
516
|
@github = Octokit::Client.new(
|
483
|
-
|
484
|
-
|
517
|
+
:login => git_config['github.login'],
|
518
|
+
:password => git_config['github.password']
|
485
519
|
)
|
486
520
|
true
|
487
521
|
@github.login
|
@@ -495,16 +529,18 @@ class GitReview
|
|
495
529
|
end
|
496
530
|
end
|
497
531
|
|
532
|
+
|
498
533
|
def debug_mode
|
499
534
|
git_config['review.mode'] == 'debug'
|
500
535
|
end
|
501
536
|
|
537
|
+
|
502
538
|
# Collect git config information in a Hash for easy access.
|
503
539
|
# Checks '~/.gitconfig' for credentials.
|
504
540
|
def git_config
|
505
541
|
unless @git_config
|
506
542
|
# Read @git_config from local git config.
|
507
|
-
@git_config = {}
|
543
|
+
@git_config = { }
|
508
544
|
config_list = git_call('config --list', false)
|
509
545
|
config_list.split("\n").each do |line|
|
510
546
|
key, value = line.split('=')
|
@@ -514,6 +550,7 @@ class GitReview
|
|
514
550
|
@git_config
|
515
551
|
end
|
516
552
|
|
553
|
+
|
517
554
|
# Returns an array consisting of information on the user and the project.
|
518
555
|
def repo_info
|
519
556
|
# Extract user and project name from GitHub URL.
|
@@ -524,7 +561,7 @@ class GitReview
|
|
524
561
|
end
|
525
562
|
user, project = github_user_and_project(url)
|
526
563
|
# If there are no results yet, look for 'insteadof' substitutions in URL and try again.
|
527
|
-
unless
|
564
|
+
unless user && project
|
528
565
|
short, base = github_insteadof_matching(config_hash, url)
|
529
566
|
if short and base
|
530
567
|
url = url.sub(short, base)
|
@@ -534,9 +571,10 @@ class GitReview
|
|
534
571
|
[user, project]
|
535
572
|
end
|
536
573
|
|
574
|
+
|
537
575
|
# Looks for 'insteadof' substitutions in URL.
|
538
576
|
def github_insteadof_matching(config_hash, url)
|
539
|
-
first = config_hash.collect { |key,value|
|
577
|
+
first = config_hash.collect { |key, value|
|
540
578
|
[value, /url\.(.*github\.com.*)\.insteadof/.match(key)]
|
541
579
|
}.find { |value, match|
|
542
580
|
url.index(value) and match != nil
|
@@ -544,15 +582,52 @@ class GitReview
|
|
544
582
|
first ? [first[0], first[1][1]] : [nil, nil]
|
545
583
|
end
|
546
584
|
|
585
|
+
|
547
586
|
# Extract user and project name from GitHub URL.
|
548
587
|
def github_user_and_project(github_url)
|
549
588
|
matches = /github\.com.(.*?)\/(.*)/.match(github_url)
|
550
589
|
matches ? [matches[1], matches[2].sub(/\.git\z/, '')] : [nil, nil]
|
551
590
|
end
|
552
591
|
|
592
|
+
|
553
593
|
# Returns a boolean stating whether the last issued system call was successful.
|
554
594
|
def last_command_successful?
|
555
595
|
$?.exitstatus == 0
|
556
596
|
end
|
557
597
|
|
598
|
+
# Returns an array where the 1st item is the title and the 2nd one is the body
|
599
|
+
def create_title_and_body(target_branch)
|
600
|
+
commits = git_call("log --format='%H' HEAD...#{target_branch}").lines.count
|
601
|
+
puts "commits: #{commits}"
|
602
|
+
if commits == 1
|
603
|
+
# we can create a really specific title and body
|
604
|
+
title = git_call("log --format='%s' HEAD...#{target_branch}").chomp
|
605
|
+
body = git_call("log --format='%b' HEAD...#{target_branch}").chomp
|
606
|
+
else
|
607
|
+
title = "[Review] Request from '#{git_config['github.login']}' @ '#{source}'"
|
608
|
+
body = "Please review the following changes:\n"
|
609
|
+
body += git_call("log --oneline HEAD...#{target_branch}").lines.map{|l| " * #{l.chomp}"}.join("\n")
|
610
|
+
end
|
611
|
+
|
612
|
+
tmpfile = Tempfile.new('git-review')
|
613
|
+
tmpfile.write(title + "\n\n" + body)
|
614
|
+
tmpfile.flush
|
615
|
+
editor = ENV['TERM_EDITOR'] || ENV['EDITOR']
|
616
|
+
warn "Please set $EDITOR or $TERM_EDITOR in your .bash_profile." unless editor
|
617
|
+
|
618
|
+
system("#{editor || 'open'} #{tmpfile.path}")
|
619
|
+
|
620
|
+
tmpfile.rewind
|
621
|
+
lines = tmpfile.read.lines.to_a
|
622
|
+
puts lines.inspect
|
623
|
+
title = lines.shift.chomp
|
624
|
+
lines.shift if lines[0].chomp.empty?
|
625
|
+
|
626
|
+
body = lines.join
|
627
|
+
|
628
|
+
tmpfile.unlink
|
629
|
+
|
630
|
+
[title, body]
|
631
|
+
end
|
632
|
+
|
558
633
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-review
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: launchy
|
@@ -32,17 +32,17 @@ dependencies:
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: '0'
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: yajl-ruby
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
62
78
|
description: Manage review workflow for projects hosted on GitHub (using pull requests).
|
63
79
|
email: bamberger.dominik@gmail.com
|
64
80
|
executables:
|
@@ -89,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
105
|
version: '0'
|
90
106
|
requirements: []
|
91
107
|
rubyforge_project:
|
92
|
-
rubygems_version: 1.8.
|
108
|
+
rubygems_version: 1.8.23
|
93
109
|
signing_key:
|
94
110
|
specification_version: 3
|
95
111
|
summary: facilitates GitHub code reviews
|