gitcycle 0.1.10 → 0.1.11
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/README.md +2 -5
- data/features/gitcycle.feature +26 -16
- data/gitcycle.gemspec +1 -1
- data/lib/gitcycle.rb +132 -126
- metadata +4 -4
data/README.md
CHANGED
@@ -99,11 +99,8 @@ This will add a "pass" label to the issue and will complete the pull request by
|
|
99
99
|
Todo
|
100
100
|
----
|
101
101
|
|
102
|
-
* Make ticket active when starting branch
|
103
|
-
* Label issues with ticket milestone?
|
104
102
|
* Check for conflict whenever merge happens
|
103
|
+
* Add conflict check when calling "qa pass [ticket]"
|
105
104
|
* Instead of detecting CONFLICT, use error status $? != 0
|
106
105
|
* Add comment on lighthouse with issue URL
|
107
|
-
*
|
108
|
-
* Add conflict check when calling "qa pass [ticket]"
|
109
|
-
* Need to change Github.parseLabels so we can have a "Fail" label along side a "Pending" tag, but for all other cases there should only be one of these tags present: "Pending QA", "Pending Review", "Pass"
|
106
|
+
* Label issues with ticket milestone?
|
data/features/gitcycle.feature
CHANGED
@@ -29,13 +29,11 @@ Scenario: Feature branch w/ custom branch name
|
|
29
29
|
"""
|
30
30
|
Retrieving branch information from gitcycle.
|
31
31
|
Your work will eventually merge into 'master'. Is this correct? (y/n)
|
32
|
-
Adding remote repo 'br/gitcycle_test'.
|
33
|
-
Fetching remote repo 'br'.
|
34
|
-
Checking out remote branch 'master' from 'br/gitcycle_test'.
|
35
32
|
Would you like to name your branch 'ticket.id'? (y/n)
|
36
33
|
What would you like to name your branch?
|
37
|
-
|
38
|
-
|
34
|
+
Adding remote repo 'config.owner/config.repo'.
|
35
|
+
Fetching remote repo 'config.owner/config.repo'.
|
36
|
+
Checking out remote branch 'ticket.id-rename' from 'config.owner/config.repo/master'.
|
39
37
|
Pushing 'ticket.id-rename'.
|
40
38
|
Sending branch information to gitcycle.
|
41
39
|
"""
|
@@ -53,12 +51,10 @@ Scenario: Feature branch
|
|
53
51
|
"""
|
54
52
|
Retrieving branch information from gitcycle.
|
55
53
|
Your work will eventually merge into 'master'. Is this correct? (y/n)
|
56
|
-
Adding remote repo 'br/gitcycle_test'.
|
57
|
-
Fetching remote repo 'br'.
|
58
|
-
Checking out remote branch 'master' from 'br/gitcycle_test'.
|
59
54
|
Would you like to name your branch 'ticket.id'? (y/n)
|
60
|
-
|
61
|
-
|
55
|
+
Adding remote repo 'config.owner/config.repo'.
|
56
|
+
Fetching remote repo 'config.owner/config.repo'.
|
57
|
+
Checking out remote branch 'ticket.id' from 'config.owner/config.repo/master'.
|
62
58
|
Pushing 'ticket.id'.
|
63
59
|
Sending branch information to gitcycle.
|
64
60
|
"""
|
@@ -99,7 +95,7 @@ Scenario: Pull changes from upstream
|
|
99
95
|
"""
|
100
96
|
Retrieving branch information from gitcycle.
|
101
97
|
Adding remote repo 'config.owner/config.repo'.
|
102
|
-
Fetching remote repo 'config.owner'.
|
98
|
+
Fetching remote repo 'config.owner/config.repo'.
|
103
99
|
Merging remote branch 'master' from 'config.owner/config.repo'.
|
104
100
|
"""
|
105
101
|
And git log should contain the last commit
|
@@ -179,11 +175,25 @@ Scenario: QA issue
|
|
179
175
|
"""
|
180
176
|
Retrieving branch information from gitcycle.
|
181
177
|
Deleting old QA branch 'qa_master'.
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
178
|
+
Adding remote repo 'config.owner/config.repo'.
|
179
|
+
Fetching remote repo 'config.owner/config.repo'.
|
180
|
+
Checking out remote branch 'qa_master' from 'config.owner/config.repo/master'.
|
181
|
+
Pushing 'qa_master'.
|
182
|
+
Adding remote repo 'config.user/config.repo'.
|
183
|
+
Fetching remote repo 'config.user/config.repo'.
|
184
|
+
Merging remote branch 'ticket.id' from 'config.user/config.repo'.
|
185
|
+
Pushing branch 'qa_master'.
|
187
186
|
Type 'gitc qa pass' to approve all issues in this branch.
|
188
187
|
Type 'gitc qa fail' to reject all issues in this branch.
|
188
|
+
"""
|
189
|
+
|
190
|
+
Scenario: QA issue list
|
191
|
+
When I cd to the owner repo
|
192
|
+
And I checkout master
|
193
|
+
And I execute gitcycle with "qa"
|
194
|
+
Then gitcycle runs
|
195
|
+
And output includes
|
196
|
+
"""
|
197
|
+
qa_master
|
198
|
+
issue #issue.id config.user/ticket.id
|
189
199
|
"""
|
data/gitcycle.gemspec
CHANGED
data/lib/gitcycle.rb
CHANGED
@@ -63,39 +63,32 @@ class Gitcycle
|
|
63
63
|
branch['home'] = @git_login
|
64
64
|
branch['source'] = branches(:current => true)
|
65
65
|
|
66
|
-
unless yes?("
|
66
|
+
unless yes?("\nYour work will eventually merge into '#{branch['source']}'. Is this correct?")
|
67
67
|
branch['source'] = q("What branch would you like to eventually merge into?")
|
68
68
|
end
|
69
69
|
|
70
|
-
checkout_remote_branch(
|
71
|
-
:owner => owner,
|
72
|
-
:repo => repo,
|
73
|
-
:branch => branch['source']
|
74
|
-
)
|
75
|
-
|
76
70
|
unless yes?("Would you like to name your branch '#{name}'?")
|
77
71
|
name = q("\nWhat would you like to name your branch?")
|
78
72
|
name = name.gsub(/[\s\W]/, '-')
|
79
73
|
end
|
80
74
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
checkout_remote_branch(
|
76
|
+
:owner => owner,
|
77
|
+
:repo => repo,
|
78
|
+
:branch => branch['source'],
|
79
|
+
:target => name
|
80
|
+
)
|
85
81
|
end
|
86
82
|
|
87
|
-
if
|
88
|
-
|
89
|
-
|
83
|
+
if branch['exists']
|
84
|
+
if branches(:match => name)
|
85
|
+
puts "Checking out branch '#{name}'.\n".green
|
86
|
+
run("git checkout #{name}")
|
87
|
+
else
|
88
|
+
puts "Tracking branch '#{name}'.\n".green
|
89
|
+
run("git fetch && git checkout -b #{name} origin/#{name}")
|
90
|
+
end
|
90
91
|
else
|
91
|
-
puts "Tracking branch '#{name}'.\n".green
|
92
|
-
run("git fetch && git checkout -b #{name} origin/#{name}")
|
93
|
-
end
|
94
|
-
|
95
|
-
unless branch['exists']
|
96
|
-
puts "Pushing '#{name}'.\n".green
|
97
|
-
run("git push origin #{name}")
|
98
|
-
|
99
92
|
puts "Sending branch information to gitcycle.".green
|
100
93
|
get('branch',
|
101
94
|
'branch[home]' => branch['home'],
|
@@ -175,52 +168,56 @@ class Gitcycle
|
|
175
168
|
puts "\nRetrieving branch information from gitcycle.\n".green
|
176
169
|
qa_branch = get('qa_branch', :source => branch.gsub(/^qa_/, ''))
|
177
170
|
|
178
|
-
|
179
|
-
|
180
|
-
run("git pull origin #{qa_branch['source']}")
|
171
|
+
pass_fail = issues.first
|
172
|
+
issues = issues[1..-1]
|
181
173
|
|
182
|
-
if
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
end
|
189
|
-
|
190
|
-
puts "\nLabeling all issues as '#{label}'.\n".green
|
191
|
-
get('label',
|
192
|
-
'qa_branch[source]' => branch.gsub(/^qa_/, ''),
|
193
|
-
'labels' => [ label ]
|
194
|
-
)
|
174
|
+
if pass_fail == 'pass'
|
175
|
+
puts "Checking out #{qa_branch['source']}.".green
|
176
|
+
run("git checkout #{qa_branch['source']}")
|
177
|
+
run("git pull origin #{qa_branch['source']}")
|
178
|
+
# TODO: track if source branch doesn't exist
|
179
|
+
end
|
195
180
|
|
181
|
+
if issues.empty?
|
196
182
|
branches = qa_branch['branches']
|
197
183
|
else
|
198
|
-
issues = [1..-1]
|
199
|
-
|
200
184
|
branches = qa_branch['branches'].select do |b|
|
201
185
|
issues.include?(b['issue'])
|
202
186
|
end
|
187
|
+
end
|
203
188
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
189
|
+
branches.each do |branch|
|
190
|
+
if pass_fail == 'pass'
|
191
|
+
merge_remote_branch(
|
192
|
+
:owner => branch['home'],
|
193
|
+
:repo => branch['repo'].split(':')[1],
|
194
|
+
:branch => branch['branch'],
|
195
|
+
:issue => branch['issue'],
|
196
|
+
:issues => qa_branch['branches'].collect { |b| b['issue'] },
|
197
|
+
:type => :from_qa
|
198
|
+
)
|
199
|
+
end
|
212
200
|
|
201
|
+
if !issues.empty? || pass_fail == 'pass'
|
213
202
|
puts "\nLabeling issue #{branch['issue']} as '#{label}'.\n".green
|
214
203
|
get('label',
|
215
|
-
'qa_branch[source]' =>
|
204
|
+
'qa_branch[source]' => qa_branch['source'],
|
216
205
|
'issue' => branch['issue'],
|
217
206
|
'labels' => [ label ]
|
218
207
|
)
|
219
208
|
end
|
220
209
|
end
|
221
210
|
|
222
|
-
if issues.
|
223
|
-
puts "\
|
211
|
+
if issues.empty? && pass_fail == 'fail'
|
212
|
+
puts "\nLabeling all issues as '#{label}'.\n".green
|
213
|
+
get('label',
|
214
|
+
'qa_branch[source]' => qa_branch['source'],
|
215
|
+
'labels' => [ label ]
|
216
|
+
)
|
217
|
+
end
|
218
|
+
|
219
|
+
if pass_fail == 'pass'
|
220
|
+
puts "Marking Lighthouse tickets as 'pending-approval'.\n".green
|
224
221
|
branches = branches.collect do |b|
|
225
222
|
{ :name => b['branch'], :repo => b['repo'], :user => b['user'] }
|
226
223
|
end
|
@@ -235,26 +232,27 @@ class Gitcycle
|
|
235
232
|
if branch =~ /^qa_/
|
236
233
|
puts "\nRetrieving branch information from gitcycle.\n".green
|
237
234
|
qa_branch = get('qa_branch', :source => branch.gsub(/^qa_/, ''))
|
235
|
+
|
236
|
+
branches = qa_branch['branches']
|
237
|
+
conflict = branches.detect { |branch| branch['conflict'] }
|
238
238
|
|
239
|
-
if qa_branch
|
240
|
-
|
241
|
-
|
239
|
+
if qa_branch && conflict
|
240
|
+
puts "Committing merge resolution of #{conflict['branch']} (issue ##{conflict['issue']}).\n".green
|
241
|
+
run("git add . && git add . -u && git commit -a -F .git/MERGE_MSG")
|
242
242
|
|
243
|
-
|
244
|
-
|
245
|
-
run("git add . && git add . -u && git commit -a -m 'Merge conflict resolution of #{conflict['branch']} (issue ##{conflict['issue']})'")
|
243
|
+
puts "Pushing merge resolution of #{conflict['branch']} (issue ##{conflict['issue']}).\n".green
|
244
|
+
run("git push origin qa_#{qa_branch['source']}")
|
246
245
|
|
247
|
-
|
248
|
-
|
246
|
+
puts "\nDe-conflicting on gitcycle.\n".green
|
247
|
+
get('qa_branch',
|
248
|
+
'issues' => branches.collect { |branch| branch['issue'] }
|
249
|
+
)
|
249
250
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
else
|
256
|
-
puts "Couldn't find record of a conflicted merge.\n".red
|
257
|
-
end
|
251
|
+
create_qa_branch(
|
252
|
+
:preserve => true,
|
253
|
+
:range => (branches.index(conflict)+1..-1),
|
254
|
+
:qa_branch => qa_branch
|
255
|
+
)
|
258
256
|
else
|
259
257
|
puts "Couldn't find record of a conflicted merge.\n".red
|
260
258
|
end
|
@@ -297,17 +295,25 @@ class Gitcycle
|
|
297
295
|
def reviewed(*issues)
|
298
296
|
require_git && require_config
|
299
297
|
|
298
|
+
if issues.include?("fail")
|
299
|
+
issues = issues.reject{|x| x=='fail'}
|
300
|
+
label = 'Fail'
|
301
|
+
else
|
302
|
+
issues = issues.reject{|x| x=='pass'}
|
303
|
+
label = 'Pending QA'
|
304
|
+
end
|
305
|
+
|
300
306
|
if issues.empty?
|
301
|
-
puts "\nLabeling issue as '
|
307
|
+
puts "\nLabeling issue as '#{label}'.\n".green
|
302
308
|
get('label',
|
303
309
|
'branch[name]' => branches(:current => true),
|
304
|
-
'labels' => [
|
310
|
+
'labels' => [ label ]
|
305
311
|
)
|
306
312
|
else
|
307
|
-
puts "\nLabeling issues as '
|
313
|
+
puts "\nLabeling issues as '#{label}'.\n".green
|
308
314
|
get('label',
|
309
315
|
'issues' => issues,
|
310
|
-
'labels' => [
|
316
|
+
'labels' => [ label ],
|
311
317
|
'scope' => 'repo'
|
312
318
|
)
|
313
319
|
end
|
@@ -348,7 +354,7 @@ class Gitcycle
|
|
348
354
|
run("git remote add #{owner} git@github.com:#{owner}/#{repo}.git")
|
349
355
|
end
|
350
356
|
|
351
|
-
puts "
|
357
|
+
puts "Fetching remote repo '#{owner}/#{repo}'.\n".green
|
352
358
|
run("git fetch #{owner}")
|
353
359
|
end
|
354
360
|
|
@@ -367,23 +373,23 @@ class Gitcycle
|
|
367
373
|
owner = options[:owner]
|
368
374
|
repo = options[:repo]
|
369
375
|
branch = options[:branch]
|
376
|
+
target = options[:target] || branch
|
377
|
+
|
378
|
+
if branches(:match => target)
|
379
|
+
unless yes?("You already have a branch called '#{target}'. Overwrite?")
|
380
|
+
run("git checkout #{target}")
|
381
|
+
run("git pull #{owner} #{target}")
|
382
|
+
return
|
383
|
+
end
|
384
|
+
end
|
370
385
|
|
371
386
|
add_remote_and_fetch(options)
|
372
387
|
|
373
|
-
puts "
|
388
|
+
puts "Checking out remote branch '#{target}' from '#{owner}/#{repo}/#{branch}'.\n".green
|
389
|
+
run("git checkout -b #{target} #{owner}/#{branch}")
|
374
390
|
|
375
|
-
|
376
|
-
|
377
|
-
else
|
378
|
-
run("git checkout -b #{branch} #{owner}/#{branch}")
|
379
|
-
end
|
380
|
-
|
381
|
-
if branches(:current => true) == branch
|
382
|
-
run("git pull #{owner} #{branch}")
|
383
|
-
else
|
384
|
-
puts "Oops. Something bad happened.\n".red
|
385
|
-
exit
|
386
|
-
end
|
391
|
+
puts "Pushing '#{target}'.\n".green
|
392
|
+
run("git push origin #{target}")
|
387
393
|
end
|
388
394
|
|
389
395
|
def create_pull_request
|
@@ -423,27 +429,19 @@ class Gitcycle
|
|
423
429
|
|
424
430
|
unless qa_branch['branches'].empty?
|
425
431
|
unless options[:preserve]
|
426
|
-
if branches(:current => source)
|
427
|
-
# Do nothing
|
428
|
-
elsif branches(:match => source)
|
429
|
-
puts "Checking out source branch '#{source}'.\n".green
|
430
|
-
run("git checkout #{source}")
|
431
|
-
else
|
432
|
-
puts "Tracking source branch '#{source}'.\n".green
|
433
|
-
run("git fetch && git checkout -b #{source} origin/#{source}")
|
434
|
-
end
|
435
|
-
|
436
|
-
run("git pull origin #{source}")
|
437
|
-
|
438
432
|
if branches(:match => name, :all => true)
|
439
433
|
puts "Deleting old QA branch '#{name}'.\n".green
|
440
|
-
run("git branch -D #{name}")
|
434
|
+
run("git branch -D #{name}") if branches(:match => name)
|
441
435
|
run("git push origin :#{name}")
|
442
436
|
end
|
443
|
-
|
444
|
-
puts "Creating QA branch '#{name}'.\n".green
|
445
|
-
run("git branch #{name} && git checkout #{name}")
|
446
437
|
|
438
|
+
checkout_remote_branch(
|
439
|
+
:owner => @git_login,
|
440
|
+
:repo => @git_repo,
|
441
|
+
:branch => source,
|
442
|
+
:target => name
|
443
|
+
)
|
444
|
+
|
447
445
|
puts "\n"
|
448
446
|
end
|
449
447
|
|
@@ -456,32 +454,11 @@ class Gitcycle
|
|
456
454
|
output = merge_remote_branch(
|
457
455
|
:owner => home,
|
458
456
|
:repo => repo,
|
459
|
-
:branch => branch
|
457
|
+
:branch => branch,
|
458
|
+
:issue => issue,
|
459
|
+
:issues => qa_branch['branches'].collect { |b| b['issue'] },
|
460
|
+
:type => :to_qa
|
460
461
|
)
|
461
|
-
|
462
|
-
if output.include?('CONFLICT')
|
463
|
-
puts "Conflict occurred when merging '#{branch}' (issue ##{issue}).\n".red
|
464
|
-
answer = q("Would you like to (s)kip or (r)esolve?")
|
465
|
-
|
466
|
-
issues = qa_branch['branches'].collect { |b| b['issue'] }
|
467
|
-
|
468
|
-
if answer.downcase[0..0] == 's'
|
469
|
-
run("git reset --hard HEAD")
|
470
|
-
issues.delete(issue)
|
471
|
-
|
472
|
-
puts "\nSending QA branch information to gitcycle.\n".green
|
473
|
-
get('qa_branch', 'issues' => issues, 'conflict' => issue)
|
474
|
-
else
|
475
|
-
puts "\nSending conflict information to gitcycle.\n".green
|
476
|
-
get('qa_branch', 'issues' => issues, 'conflict' => issue)
|
477
|
-
|
478
|
-
puts "Type 'gitc qa resolved' when finished resolving.\n".yellow
|
479
|
-
exit
|
480
|
-
end
|
481
|
-
else
|
482
|
-
puts "Pushing QA branch '#{name}'.\n".green
|
483
|
-
run("git push origin #{name}")
|
484
|
-
end
|
485
462
|
end
|
486
463
|
|
487
464
|
puts "\nType '".yellow + "gitc qa pass".green + "' to approve all issues in this branch.\n".yellow
|
@@ -490,6 +467,33 @@ class Gitcycle
|
|
490
467
|
end
|
491
468
|
end
|
492
469
|
|
470
|
+
def fix_conflict(options)
|
471
|
+
owner = options[:owner]
|
472
|
+
repo = options[:repo]
|
473
|
+
branch = options[:branch]
|
474
|
+
issue = options[:issue]
|
475
|
+
issues = options[:issues]
|
476
|
+
type = options[:type]
|
477
|
+
|
478
|
+
if $? != 0
|
479
|
+
puts "Conflict occurred when merging '#{branch}'#{" (issue ##{issue})" if issue}.\n".red
|
480
|
+
|
481
|
+
if type # from_qa or to_qa
|
482
|
+
puts "Please resolve this conflict with '#{owner}'.\n".yellow
|
483
|
+
|
484
|
+
puts "\nSending conflict information to gitcycle.\n".green
|
485
|
+
get('qa_branch', 'issues' => issues, "conflict_#{type}" => issue)
|
486
|
+
|
487
|
+
puts "Type 'gitc qa resolved' when finished resolving.\n".yellow
|
488
|
+
exit
|
489
|
+
end
|
490
|
+
elsif type # from_qa or to_qa
|
491
|
+
branch = branches(:current => true)
|
492
|
+
puts "Pushing branch '#{branch}'.\n".green
|
493
|
+
run("git push origin #{branch}")
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
493
497
|
def get(path, hash={})
|
494
498
|
hash.merge!(
|
495
499
|
:login => @login,
|
@@ -538,6 +542,8 @@ class Gitcycle
|
|
538
542
|
|
539
543
|
puts "\nMerging remote branch '#{branch}' from '#{owner}/#{repo}'.\n".green
|
540
544
|
run("git merge #{owner}/#{branch}")
|
545
|
+
|
546
|
+
fix_conflict(options)
|
541
547
|
end
|
542
548
|
|
543
549
|
def remotes(options={})
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitcycle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 11
|
10
|
+
version: 0.1.11
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Winton Welsh
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-23 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|