gitcycle 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/README.md +1 -1
- data/gitcycle.gemspec +1 -1
- data/lib/gitcycle/branch.rb +77 -0
- data/lib/gitcycle/checkout.rb +92 -0
- data/lib/gitcycle/commit.rb +44 -0
- data/lib/gitcycle/discuss.rb +36 -0
- data/lib/gitcycle/incident.rb +115 -0
- data/lib/gitcycle/open.rb +32 -0
- data/lib/gitcycle/pull.rb +56 -0
- data/lib/gitcycle/push.rb +24 -0
- data/lib/gitcycle/qa.rb +204 -0
- data/lib/gitcycle/ready.rb +37 -0
- data/lib/gitcycle/review.rb +29 -0
- data/lib/gitcycle/setup.rb +11 -0
- data/lib/gitcycle.rb +43 -612
- data/spec/config/gitcycle.example.yml +2 -0
- data/spec/gitcycle/incident_spec.rb +13 -0
- data/spec/gitcycle_spec.rb +7 -0
- data/spec/spec_helper.rb +20 -0
- metadata +189 -140
- checksums.yaml +0 -7
data/lib/gitcycle.rb
CHANGED
@@ -15,12 +15,24 @@ require 'yajl'
|
|
15
15
|
$:.unshift File.dirname(__FILE__)
|
16
16
|
|
17
17
|
require "ext/string"
|
18
|
+
require "gitcycle/branch"
|
19
|
+
require "gitcycle/checkout"
|
20
|
+
require "gitcycle/commit"
|
21
|
+
require "gitcycle/discuss"
|
22
|
+
require "gitcycle/incident"
|
23
|
+
require "gitcycle/open"
|
24
|
+
require "gitcycle/pull"
|
25
|
+
require "gitcycle/push"
|
26
|
+
require "gitcycle/qa"
|
27
|
+
require "gitcycle/ready"
|
28
|
+
require "gitcycle/review"
|
29
|
+
require "gitcycle/setup"
|
18
30
|
|
19
31
|
class Gitcycle
|
20
32
|
|
21
33
|
API =
|
22
|
-
if ENV['ENV'] == '
|
23
|
-
"http://127.0.0.1:
|
34
|
+
if ENV['ENV'] == 'test'
|
35
|
+
"http://127.0.0.1:3000/api"
|
24
36
|
else
|
25
37
|
"http://gitcycle.bleacherreport.com/api"
|
26
38
|
end
|
@@ -36,6 +48,19 @@ class Gitcycle
|
|
36
48
|
:last_command_errored => 8,
|
37
49
|
}
|
38
50
|
|
51
|
+
include Branch
|
52
|
+
include Checkout
|
53
|
+
include Commit
|
54
|
+
include Discuss
|
55
|
+
include Incident
|
56
|
+
include Open
|
57
|
+
include Pull
|
58
|
+
include Push
|
59
|
+
include QA
|
60
|
+
include Ready
|
61
|
+
include Review
|
62
|
+
include Setup
|
63
|
+
|
39
64
|
def initialize(args=nil)
|
40
65
|
$remotes = {}
|
41
66
|
|
@@ -51,524 +76,6 @@ class Gitcycle
|
|
51
76
|
start(args) if args
|
52
77
|
end
|
53
78
|
|
54
|
-
def branch(*args)
|
55
|
-
url = args.detect { |arg| arg =~ /^https?:\/\// }
|
56
|
-
title = args.detect { |arg| arg =~ /\s/ }
|
57
|
-
|
58
|
-
exec_git(:branch, args) unless url || title
|
59
|
-
|
60
|
-
require_git && require_config
|
61
|
-
|
62
|
-
params = {
|
63
|
-
'branch[source]' => branches(:current => true)
|
64
|
-
}
|
65
|
-
|
66
|
-
if url && url.include?('lighthouseapp.com/')
|
67
|
-
params.merge!('branch[lighthouse_url]' => url)
|
68
|
-
elsif url && url.include?('github.com/')
|
69
|
-
params.merge!('branch[issue_url]' => url)
|
70
|
-
elsif url
|
71
|
-
puts "Gitcycle only supports Lighthouse or Github Issue URLs.".red
|
72
|
-
exit ERROR[:unrecognized_url]
|
73
|
-
elsif title
|
74
|
-
params.merge!(
|
75
|
-
'branch[name]' => title,
|
76
|
-
'branch[title]' => title
|
77
|
-
)
|
78
|
-
else
|
79
|
-
exec_git(:branch, args)
|
80
|
-
end
|
81
|
-
|
82
|
-
unless yes?("\nYour work will eventually merge into '#{params['branch[source]']}'. Is this correct?")
|
83
|
-
params['branch[source]'] = q("What branch would you like to eventually merge into?")
|
84
|
-
end
|
85
|
-
|
86
|
-
source = params['branch[source]']
|
87
|
-
|
88
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
89
|
-
branch = get('branch', params)
|
90
|
-
name = branch['name']
|
91
|
-
|
92
|
-
begin
|
93
|
-
owner, repo = branch['repo'].split(':')
|
94
|
-
branch['home'] ||= @git_login
|
95
|
-
|
96
|
-
unless yes?("Would you like to name your branch '#{name}'?")
|
97
|
-
name = q("\nWhat would you like to name your branch?")
|
98
|
-
name = name.gsub(/[\s\W]/, '-')
|
99
|
-
end
|
100
|
-
|
101
|
-
checkout_remote_branch(
|
102
|
-
:owner => owner,
|
103
|
-
:repo => repo,
|
104
|
-
:branch => branch['source'],
|
105
|
-
:target => name
|
106
|
-
)
|
107
|
-
|
108
|
-
puts "Sending branch information to gitcycle.".green
|
109
|
-
get('branch',
|
110
|
-
'branch[home]' => branch['home'],
|
111
|
-
'branch[name]' => branch['name'],
|
112
|
-
'branch[rename]' => name != branch['name'] ? name : nil,
|
113
|
-
'branch[source]' => branch['source']
|
114
|
-
)
|
115
|
-
rescue SystemExit, Interrupt
|
116
|
-
puts "\nDeleting branch from gitcycle.\n".green
|
117
|
-
get('branch',
|
118
|
-
'branch[name]' => branch['name'],
|
119
|
-
'create' => 0,
|
120
|
-
'reset' => 1
|
121
|
-
)
|
122
|
-
end
|
123
|
-
|
124
|
-
puts "\n"
|
125
|
-
end
|
126
|
-
|
127
|
-
def checkout(*args)
|
128
|
-
if args.length != 1 || options?(args)
|
129
|
-
exec_git(:checkout, args)
|
130
|
-
end
|
131
|
-
|
132
|
-
require_git && require_config
|
133
|
-
|
134
|
-
if args[0] =~ /^https?:\/\//
|
135
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
136
|
-
branch = get('branch', 'branch[lighthouse_url]' => args[0], 'create' => 0)
|
137
|
-
if branch
|
138
|
-
checkout_or_track(:name => branch['name'], :remote => 'origin')
|
139
|
-
else
|
140
|
-
puts "\nBranch not found!\n".red
|
141
|
-
puts "\nDid you mean: gitc branch #{args[0]}\n".yellow
|
142
|
-
end
|
143
|
-
elsif args[0] =~ /^\d*$/
|
144
|
-
puts "\nLooking for a branch for LH ticket ##{args[0]}.\n".green
|
145
|
-
results = branches(:array => true).select {|b| b.include?("-#{args[0]}-") }
|
146
|
-
if results.size == 0
|
147
|
-
puts "\nNo matches for ticket ##{args[0]} found.\n".red
|
148
|
-
elsif results.size == 1
|
149
|
-
branch = results.first
|
150
|
-
if branch.strip == branches(:current => true).strip
|
151
|
-
puts "Already on Github branch for LH ticket ##{args[0]} (#{branch})".yellow
|
152
|
-
else
|
153
|
-
puts "\nSwitching to branch '#{branch}'\n".green
|
154
|
-
run("git checkout #{branch}")
|
155
|
-
end
|
156
|
-
else
|
157
|
-
puts "\nFound #{results.size} matches with that LH ticket number:\n".yellow
|
158
|
-
puts results
|
159
|
-
puts "\nDid not switch branches. Please check your ticket number.\n".red
|
160
|
-
end
|
161
|
-
else
|
162
|
-
remote, branch = args[0].split('/')
|
163
|
-
remote, branch = nil, remote if branch.nil?
|
164
|
-
collab = branch && remote
|
165
|
-
|
166
|
-
unless branches(:match => branch)
|
167
|
-
og_remote = nil
|
168
|
-
|
169
|
-
puts "\nRetrieving repo information from gitcycle.\n".green
|
170
|
-
repo = get('repo')
|
171
|
-
remote = repo['owner'] unless collab
|
172
|
-
|
173
|
-
output = add_remote_and_fetch(
|
174
|
-
:catch => false,
|
175
|
-
:owner => remote,
|
176
|
-
:repo => @git_repo
|
177
|
-
)
|
178
|
-
|
179
|
-
if errored?(output)
|
180
|
-
og_remote = remote
|
181
|
-
remote = repo["owner"]
|
182
|
-
|
183
|
-
add_remote_and_fetch(
|
184
|
-
:owner => remote,
|
185
|
-
:repo => @git_repo
|
186
|
-
)
|
187
|
-
end
|
188
|
-
|
189
|
-
puts "Creating branch '#{branch}' from '#{remote}/#{branch}'.\n".green
|
190
|
-
output = run("git branch --no-track #{branch} #{remote}/#{branch}", :catch => false)
|
191
|
-
|
192
|
-
if errored?(output)
|
193
|
-
puts "Could not find branch #{"'#{og_remote}/#{branch}' or " if og_remote}'#{remote}/#{branch}'.\n".red
|
194
|
-
exit ERROR[:could_not_find_branch]
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
if collab
|
199
|
-
puts "Sending branch information to gitcycle.".green
|
200
|
-
get('branch',
|
201
|
-
'branch[home]' => remote,
|
202
|
-
'branch[name]' => branch,
|
203
|
-
'branch[source]' => branch,
|
204
|
-
'branch[collab]' => 1,
|
205
|
-
'create' => 1
|
206
|
-
)
|
207
|
-
end
|
208
|
-
|
209
|
-
puts "Checking out '#{branch}'.\n".green
|
210
|
-
run("git checkout -q #{branch}")
|
211
|
-
end
|
212
|
-
end
|
213
|
-
alias :co :checkout
|
214
|
-
|
215
|
-
def commit(*args)
|
216
|
-
msg = nil
|
217
|
-
no_add = args.delete("--no-add")
|
218
|
-
|
219
|
-
if args.empty?
|
220
|
-
require_git && require_config
|
221
|
-
|
222
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
223
|
-
branch = get('branch',
|
224
|
-
'branch[name]' => branches(:current => true),
|
225
|
-
'create' => 0
|
226
|
-
)
|
227
|
-
|
228
|
-
id = branch["lighthouse_url"].match(/tickets\/(\d+)/)[1] rescue nil
|
229
|
-
|
230
|
-
if branch && id
|
231
|
-
msg = "[##{id}]"
|
232
|
-
msg += " #{branch["title"]}" if branch["title"]
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
if no_add
|
237
|
-
cmd = "git commit"
|
238
|
-
else
|
239
|
-
cmd = "git add . && git add . -u && git commit -a"
|
240
|
-
end
|
241
|
-
|
242
|
-
if File.exists?("#{Dir.pwd}/.git/MERGE_HEAD")
|
243
|
-
Kernel.exec(cmd)
|
244
|
-
elsif msg
|
245
|
-
run(cmd + " -m #{msg.dump.gsub('`', "'")}")
|
246
|
-
Kernel.exec("git commit --amend")
|
247
|
-
elsif args.empty?
|
248
|
-
Kernel.exec(cmd)
|
249
|
-
else
|
250
|
-
exec_git(:commit, args)
|
251
|
-
end
|
252
|
-
end
|
253
|
-
alias :ci :commit
|
254
|
-
|
255
|
-
def discuss(*issues)
|
256
|
-
require_git && require_config
|
257
|
-
|
258
|
-
if issues.empty?
|
259
|
-
branch = create_pull_request
|
260
|
-
|
261
|
-
if branch == false
|
262
|
-
puts "Branch not found.\n".red
|
263
|
-
elsif branch['issue_url']
|
264
|
-
puts "\nLabeling issue as 'Discuss'.\n".green
|
265
|
-
get('label',
|
266
|
-
'branch[name]' => branch['name'],
|
267
|
-
'labels' => [ 'Discuss' ]
|
268
|
-
)
|
269
|
-
|
270
|
-
puts "Opening issue: #{branch['issue_url']}\n".green
|
271
|
-
Launchy.open(branch['issue_url'])
|
272
|
-
else
|
273
|
-
puts "You must push code before opening a pull request.\n".red
|
274
|
-
end
|
275
|
-
else
|
276
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
277
|
-
|
278
|
-
get('branch', 'issues' => issues, 'scope' => 'repo').each do |branch|
|
279
|
-
if branch['issue_url']
|
280
|
-
puts "Opening issue: #{branch['issue_url']}\n".green
|
281
|
-
Launchy.open(branch['issue_url'])
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
def pull(*args)
|
288
|
-
exec_git(:pull, args) if args.length > 0
|
289
|
-
|
290
|
-
require_git && require_config
|
291
|
-
|
292
|
-
current_branch = branches(:current => true)
|
293
|
-
|
294
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
295
|
-
branch = get('branch',
|
296
|
-
'branch[name]' => current_branch,
|
297
|
-
'include' => [ 'repo' ],
|
298
|
-
'create' => 0
|
299
|
-
)
|
300
|
-
|
301
|
-
if branch && branch['collab']
|
302
|
-
# Merge from collab
|
303
|
-
merge_remote_branch(
|
304
|
-
:owner => owner = branch['home'],
|
305
|
-
:repo => branch['repo']['name'],
|
306
|
-
:branch => branch['source']
|
307
|
-
)
|
308
|
-
elsif branch
|
309
|
-
# Merge from upstream source branch
|
310
|
-
merge_remote_branch(
|
311
|
-
:owner => owner = branch['repo']['owner'],
|
312
|
-
:repo => branch['repo']['name'],
|
313
|
-
:branch => branch['source']
|
314
|
-
)
|
315
|
-
else
|
316
|
-
puts "\nRetrieving repo information from gitcycle.\n".green
|
317
|
-
repo = get('repo')
|
318
|
-
|
319
|
-
# Merge from upstream branch with same name
|
320
|
-
merge_remote_branch(
|
321
|
-
:owner => owner = repo['owner'],
|
322
|
-
:repo => repo['name'],
|
323
|
-
:branch => current_branch
|
324
|
-
)
|
325
|
-
end
|
326
|
-
|
327
|
-
unless branch && branch['collab'] || owner == @git_login
|
328
|
-
# Merge from origin
|
329
|
-
merge_remote_branch(
|
330
|
-
:owner => @git_login,
|
331
|
-
:repo => @git_repo,
|
332
|
-
:branch => current_branch
|
333
|
-
)
|
334
|
-
end
|
335
|
-
|
336
|
-
branch
|
337
|
-
end
|
338
|
-
|
339
|
-
def push(*args)
|
340
|
-
exec_git(:push, args) if args.length > 0
|
341
|
-
|
342
|
-
require_git && require_config
|
343
|
-
|
344
|
-
branch = pull
|
345
|
-
|
346
|
-
if branch && branch['collab']
|
347
|
-
puts "\nPushing branch '#{branch['home']}/#{branch['name']}'.\n".green
|
348
|
-
run("git push #{branch['home']} #{branch['name']} -q")
|
349
|
-
elsif branch
|
350
|
-
puts "\nPushing branch 'origin/#{branch['name']}'.\n".green
|
351
|
-
run("git push origin #{branch['name']} -q")
|
352
|
-
else
|
353
|
-
current_branch = branches(:current => true)
|
354
|
-
puts "\nPushing branch 'origin/#{current_branch}'.\n".green
|
355
|
-
run("git push origin #{current_branch} -q")
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
def qa(*issues)
|
360
|
-
require_git && require_config
|
361
|
-
|
362
|
-
if issues.empty?
|
363
|
-
puts "\n"
|
364
|
-
get('qa_branch').each do |branches|
|
365
|
-
puts "qa_#{branches['source']}_#{branches['user']}".green
|
366
|
-
branches['branches'].each do |branch|
|
367
|
-
puts " #{"issue ##{branch['issue']}".yellow}\t#{branch['user']}/#{branch['branch']}"
|
368
|
-
end
|
369
|
-
puts "\n"
|
370
|
-
end
|
371
|
-
elsif issues.first == 'fail' || issues.first == 'pass'
|
372
|
-
branch = branches(:current => true)
|
373
|
-
pass_fail = issues.first
|
374
|
-
label = pass_fail.capitalize
|
375
|
-
issues = issues[1..-1]
|
376
|
-
|
377
|
-
if pass_fail == 'pass' && !issues.empty?
|
378
|
-
puts "\nWARNING: #{
|
379
|
-
issues.length == 1 ? "This issue" : "These issues"
|
380
|
-
} will merge straight into '#{branch}' without testing.\n".red
|
381
|
-
|
382
|
-
if yes?("Continue?")
|
383
|
-
qa_branch = create_qa_branch(
|
384
|
-
:instructions => false,
|
385
|
-
:issues => issues,
|
386
|
-
:source => branch
|
387
|
-
)
|
388
|
-
`git checkout qa_#{qa_branch['source']}_#{qa_branch['user']} -q`
|
389
|
-
$remotes = {}
|
390
|
-
qa('pass')
|
391
|
-
else
|
392
|
-
exit ERROR[:told_not_to_merge]
|
393
|
-
end
|
394
|
-
elsif branch =~ /^qa_/
|
395
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
396
|
-
qa_branch = get('qa_branch', :source => branch.gsub(/^qa_/, ''))
|
397
|
-
|
398
|
-
if pass_fail == 'pass'
|
399
|
-
checkout_or_track(:name => qa_branch['source'], :remote => 'origin')
|
400
|
-
end
|
401
|
-
|
402
|
-
if issues.empty?
|
403
|
-
branches = qa_branch['branches']
|
404
|
-
else
|
405
|
-
branches = qa_branch['branches'].select do |b|
|
406
|
-
issues.include?(b['issue'])
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
if pass_fail == 'pass' && issues.empty?
|
411
|
-
owner, repo = qa_branch['repo'].split(':')
|
412
|
-
merge_remote_branch(
|
413
|
-
:owner => owner,
|
414
|
-
:repo => repo,
|
415
|
-
:branch => "qa_#{qa_branch['source']}_#{qa_branch['user']}",
|
416
|
-
:type => :from_qa
|
417
|
-
)
|
418
|
-
end
|
419
|
-
|
420
|
-
unless issues.empty?
|
421
|
-
branches.each do |branch|
|
422
|
-
puts "\nLabeling issue #{branch['issue']} as '#{label}'.\n".green
|
423
|
-
get('label',
|
424
|
-
'qa_branch[source]' => qa_branch['source'],
|
425
|
-
'issue' => branch['issue'],
|
426
|
-
'labels' => [ label ]
|
427
|
-
)
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
if issues.empty?
|
432
|
-
puts "\nLabeling all issues as '#{label}'.\n".green
|
433
|
-
get('label',
|
434
|
-
'qa_branch[source]' => qa_branch['source'],
|
435
|
-
'labels' => [ label ]
|
436
|
-
)
|
437
|
-
end
|
438
|
-
else
|
439
|
-
puts "\nYou are not in a QA branch.\n".red
|
440
|
-
end
|
441
|
-
elsif issues.first == 'resolved'
|
442
|
-
branch = branches(:current => true)
|
443
|
-
|
444
|
-
if branch =~ /^qa_/
|
445
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
446
|
-
qa_branch = get('qa_branch', :source => branch.gsub(/^qa_/, ''))
|
447
|
-
|
448
|
-
branches = qa_branch['branches']
|
449
|
-
conflict = branches.detect { |branch| branch['conflict'] }
|
450
|
-
|
451
|
-
if qa_branch && conflict
|
452
|
-
puts "Committing merge resolution of #{conflict['branch']} (issue ##{conflict['issue']}).\n".green
|
453
|
-
run("git add . && git add . -u && git commit -a -F .git/MERGE_MSG")
|
454
|
-
|
455
|
-
puts "Pushing merge resolution of #{conflict['branch']} (issue ##{conflict['issue']}).\n".green
|
456
|
-
run("git push origin qa_#{qa_branch['source']}_#{qa_branch['user']} -q")
|
457
|
-
|
458
|
-
puts "\nDe-conflicting on gitcycle.\n".green
|
459
|
-
get('qa_branch',
|
460
|
-
'issues' => branches.collect { |branch| branch['issue'] }
|
461
|
-
)
|
462
|
-
|
463
|
-
create_qa_branch(
|
464
|
-
:preserve => true,
|
465
|
-
:range => (branches.index(conflict)+1..-1),
|
466
|
-
:qa_branch => qa_branch
|
467
|
-
)
|
468
|
-
else
|
469
|
-
puts "Couldn't find record of a conflicted merge.\n".red
|
470
|
-
end
|
471
|
-
else
|
472
|
-
puts "\nYou aren't on a QA branch.\n".red
|
473
|
-
end
|
474
|
-
else
|
475
|
-
create_qa_branch(:issues => issues)
|
476
|
-
end
|
477
|
-
end
|
478
|
-
|
479
|
-
def ready(*issues)
|
480
|
-
require_git && require_config
|
481
|
-
|
482
|
-
branch = pull
|
483
|
-
|
484
|
-
if branch && !branch['collab']
|
485
|
-
# Recreate pull request if force == true
|
486
|
-
force = branch['labels'] && branch['labels'].include?('Pass')
|
487
|
-
force ||= branch['state'] && branch['state'] == 'closed'
|
488
|
-
|
489
|
-
branch = create_pull_request(branch, force)
|
490
|
-
end
|
491
|
-
|
492
|
-
if branch == false
|
493
|
-
puts "Branch not found.\n".red
|
494
|
-
elsif branch['collab']
|
495
|
-
remote, branch = branch['home'], branch['source']
|
496
|
-
puts "\nPushing branch '#{remote}/#{branch}'.\n".green
|
497
|
-
run("git push #{remote} #{branch} -q")
|
498
|
-
elsif branch['issue_url']
|
499
|
-
puts "\nLabeling issue as 'Pending Review'.\n".green
|
500
|
-
get('label',
|
501
|
-
'branch[name]' => branch['name'],
|
502
|
-
'labels' => [ 'Pending Review' ]
|
503
|
-
)
|
504
|
-
|
505
|
-
puts "Opening issue: #{branch['issue_url']}\n".green
|
506
|
-
Launchy.open(branch['issue_url'])
|
507
|
-
else
|
508
|
-
puts "You have not pushed any commits to '#{branch['name']}'.\n".red
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
def review(pass_fail, *issues)
|
513
|
-
require_git && require_config
|
514
|
-
|
515
|
-
if pass_fail == 'fail'
|
516
|
-
label = 'Fail'
|
517
|
-
else
|
518
|
-
label = 'Pending QA'
|
519
|
-
end
|
520
|
-
|
521
|
-
if issues.empty?
|
522
|
-
puts "\nLabeling issue as '#{label}'.\n".green
|
523
|
-
get('label',
|
524
|
-
'branch[name]' => branches(:current => true),
|
525
|
-
'labels' => [ label ]
|
526
|
-
)
|
527
|
-
else
|
528
|
-
puts "\nLabeling issues as '#{label}'.\n".green
|
529
|
-
get('label',
|
530
|
-
'issues' => issues,
|
531
|
-
'labels' => [ label ],
|
532
|
-
'scope' => 'repo'
|
533
|
-
)
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
|
-
def open(*issues)
|
538
|
-
require_git && require_config
|
539
|
-
|
540
|
-
if issues.empty?
|
541
|
-
branch = create_pull_request
|
542
|
-
|
543
|
-
if branch == false
|
544
|
-
puts "Branch not found.\n".red
|
545
|
-
elsif branch['issue_url']
|
546
|
-
puts "\nOpening the pull request in GitHub\n".green
|
547
|
-
|
548
|
-
puts "Opening issue: #{branch['issue_url']}\n".green
|
549
|
-
Launchy.open(branch['issue_url'])
|
550
|
-
else
|
551
|
-
puts "You must push code before opening a pull request.\n".red
|
552
|
-
end
|
553
|
-
else
|
554
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
555
|
-
|
556
|
-
get('branch', 'issues' => issues, 'scope' => 'repo').each do |branch|
|
557
|
-
if branch['issue_url']
|
558
|
-
puts "Opening issue: #{branch['issue_url']}\n".green
|
559
|
-
Launchy.open(branch['issue_url'])
|
560
|
-
end
|
561
|
-
end
|
562
|
-
end
|
563
|
-
end
|
564
|
-
|
565
|
-
def setup(login, repo, token)
|
566
|
-
repo = "#{login}/#{repo}" unless repo.include?('/')
|
567
|
-
@config[repo] = [ login, token ]
|
568
|
-
save_config
|
569
|
-
puts "\nConfiguration saved.\n".green
|
570
|
-
end
|
571
|
-
|
572
79
|
def start(args=[])
|
573
80
|
command = args.shift
|
574
81
|
|
@@ -700,84 +207,6 @@ class Gitcycle
|
|
700
207
|
branch
|
701
208
|
end
|
702
209
|
|
703
|
-
def create_qa_branch(options)
|
704
|
-
instructions = options[:instructions]
|
705
|
-
issues = options[:issues]
|
706
|
-
range = options[:range] || (0..-1)
|
707
|
-
source = options[:source]
|
708
|
-
|
709
|
-
if (issues && !issues.empty?) || options[:qa_branch]
|
710
|
-
if options[:qa_branch]
|
711
|
-
qa_branch = options[:qa_branch]
|
712
|
-
else
|
713
|
-
unless source
|
714
|
-
source = branches(:current => true)
|
715
|
-
|
716
|
-
unless yes?("\nDo you want to create a QA branch from '#{source}'?")
|
717
|
-
source = q("What branch would you like to base this QA branch off of?")
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
puts "\nRetrieving branch information from gitcycle.\n".green
|
722
|
-
qa_branch = get('qa_branch', 'issues' => issues, 'source' => source)
|
723
|
-
end
|
724
|
-
|
725
|
-
source = qa_branch['source']
|
726
|
-
name = "qa_#{source}_#{qa_branch['user']}"
|
727
|
-
|
728
|
-
unless qa_branch['branches'].empty?
|
729
|
-
qa_branch['branches'][range].each do |branch|
|
730
|
-
if source != branch['source']
|
731
|
-
puts "You can only QA issues based on '#{source}'\n".red
|
732
|
-
exit ERROR[:cannot_qa]
|
733
|
-
end
|
734
|
-
end
|
735
|
-
|
736
|
-
unless options[:preserve]
|
737
|
-
if branches(:match => name, :all => true)
|
738
|
-
puts "Deleting old QA branch '#{name}'.\n".green
|
739
|
-
if branches(:match => name)
|
740
|
-
run("git checkout master -q")
|
741
|
-
run("git branch -D #{name}")
|
742
|
-
end
|
743
|
-
run("git push origin :#{name} -q")
|
744
|
-
end
|
745
|
-
|
746
|
-
checkout_remote_branch(
|
747
|
-
:owner => @git_login,
|
748
|
-
:repo => @git_repo,
|
749
|
-
:branch => source,
|
750
|
-
:target => name
|
751
|
-
)
|
752
|
-
|
753
|
-
puts "\n"
|
754
|
-
end
|
755
|
-
|
756
|
-
qa_branch['branches'][range].each do |branch|
|
757
|
-
issue = branch['issue']
|
758
|
-
owner, repo = branch['repo'].split(':')
|
759
|
-
home = branch['home']
|
760
|
-
|
761
|
-
output = merge_remote_branch(
|
762
|
-
:owner => home,
|
763
|
-
:repo => repo,
|
764
|
-
:branch => branch['branch'],
|
765
|
-
:issue => issue,
|
766
|
-
:issues => qa_branch['branches'].collect { |b| b['issue'] },
|
767
|
-
:type => :to_qa
|
768
|
-
)
|
769
|
-
end
|
770
|
-
|
771
|
-
unless options[:instructions] == false
|
772
|
-
puts "\nType '".yellow + "gitc qa pass".green + "' to approve all issues in this branch.\n".yellow
|
773
|
-
puts "Type '".yellow + "gitc qa fail".red + "' to reject all issues in this branch.\n".yellow
|
774
|
-
end
|
775
|
-
end
|
776
|
-
|
777
|
-
qa_branch
|
778
|
-
end
|
779
|
-
end
|
780
|
-
|
781
210
|
def errored?(output)
|
782
211
|
output.include?("fatal: ") || output.include?("ERROR: ") || $?.exitstatus != 0
|
783
212
|
end
|
@@ -821,7 +250,9 @@ class Gitcycle
|
|
821
250
|
:uid => (0...20).map{ ('a'..'z').to_a[rand(26)] }.join
|
822
251
|
)
|
823
252
|
|
824
|
-
|
253
|
+
hash[:test] = 1 if ENV['ENV'] == 'test'
|
254
|
+
|
255
|
+
puts "Transaction ID: #{hash[:uid]}".green
|
825
256
|
|
826
257
|
params = ''
|
827
258
|
hash[:session] = 0
|
@@ -858,14 +289,6 @@ class Gitcycle
|
|
858
289
|
end
|
859
290
|
end
|
860
291
|
|
861
|
-
def load_config
|
862
|
-
if File.exists?(@config_path)
|
863
|
-
@config = YAML.load(File.read(@config_path))
|
864
|
-
else
|
865
|
-
@config = {}
|
866
|
-
end
|
867
|
-
end
|
868
|
-
|
869
292
|
def git_config_path(path)
|
870
293
|
config = "#{path}/.git/config"
|
871
294
|
if File.exists?(config)
|
@@ -878,6 +301,14 @@ class Gitcycle
|
|
878
301
|
end
|
879
302
|
end
|
880
303
|
|
304
|
+
def load_config
|
305
|
+
if File.exists?(@config_path)
|
306
|
+
@config = YAML.load(File.read(@config_path))
|
307
|
+
else
|
308
|
+
@config = {}
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
881
312
|
def load_git
|
882
313
|
path = git_config_path(Dir.pwd)
|
883
314
|
if path
|
@@ -906,6 +337,11 @@ class Gitcycle
|
|
906
337
|
def options?(args)
|
907
338
|
args.any? { |arg| arg =~ /^-/ }
|
908
339
|
end
|
340
|
+
|
341
|
+
def q(question, extra='')
|
342
|
+
puts "#{question.yellow}#{extra}"
|
343
|
+
$input ? $input.shift : $stdin.gets.strip
|
344
|
+
end
|
909
345
|
|
910
346
|
def remotes(options={})
|
911
347
|
b = `git remote`
|
@@ -915,11 +351,6 @@ class Gitcycle
|
|
915
351
|
b
|
916
352
|
end
|
917
353
|
end
|
918
|
-
|
919
|
-
def q(question, extra='')
|
920
|
-
puts "#{question.yellow}#{extra}"
|
921
|
-
$input ? $input.shift : $stdin.gets.strip
|
922
|
-
end
|
923
354
|
|
924
355
|
def require_config
|
925
356
|
unless @login && @token
|