gitcycle 0.3.3 → 0.3.4
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/.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
|