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 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
- * Need to make sure when a branch is created, it is always from the pristine remote version, not local
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?
@@ -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
- Creating 'ticket.id-rename' from 'master'.
38
- Checking out branch 'ticket.id-rename'.
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
- Creating 'ticket.id' from 'master'.
61
- Checking out branch 'ticket.id'.
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
- Creating QA branch 'qa_master'.
183
- Adding remote repo 'config.user/gitcycle_test'.
184
- Fetching remote repo 'config.user'.
185
- Merging remote branch 'ticket.id' from 'config.user/gitcycle_test'.
186
- Pushing QA branch 'qa_master'.
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
@@ -6,7 +6,7 @@ $:.unshift lib unless $:.include?(lib)
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "gitcycle"
9
- s.version = '0.1.10'
9
+ s.version = '0.1.11'
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.authors = [ 'Winton Welsh' ]
12
12
  s.email = [ 'mail@wintoni.us' ]
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?("Your work will eventually merge into '#{branch['source']}'. Is this correct?")
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
- unless branches(:match => name)
82
- puts "\nCreating '#{name}' from '#{branch['source']}'.\n".green
83
- run("git branch #{name}")
84
- end
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 branches(:match => name)
88
- puts "Checking out branch '#{name}'.\n".green
89
- run("git checkout #{name}")
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
- puts "Checking out #{qa_branch['source']}.".green
179
- run("git checkout #{qa_branch['source']}")
180
- run("git pull origin #{qa_branch['source']}")
171
+ pass_fail = issues.first
172
+ issues = issues[1..-1]
181
173
 
182
- if issues[1..-1].empty?
183
- if issues.first == 'pass'
184
- puts "Merging '#{branch}' into '#{qa_branch['source']}'.\n".green
185
- run("git merge #{branch}")
186
- run("git pull origin #{qa_branch['source']}")
187
- run("git push origin #{qa_branch['source']}")
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
- branches.each do |branch|
205
- if issues.first == 'pass'
206
- merge_remote_branch(
207
- :user => branch['user'],
208
- :repo => branch['repo'].split(':'),
209
- :branch => branch['branch']
210
- )
211
- end
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]' => branch.gsub(/^qa_/, ''),
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.first == 'pass'
223
- puts "\nMarking Lighthouse tickets as 'pending-approval'.\n".green
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
- branches = qa_branch['branches']
241
- conflict = branches.detect { |branch| branch['conflict'] }
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
- if conflict
244
- puts "Committing merge resolution of #{conflict['branch']} (issue ##{conflict['issue']}).\n".green
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
- puts "Pushing merge resolution of #{conflict['branch']} (issue ##{conflict['issue']}).\n".green
248
- run("git push origin qa_#{qa_branch['source']}")
246
+ puts "\nDe-conflicting on gitcycle.\n".green
247
+ get('qa_branch',
248
+ 'issues' => branches.collect { |branch| branch['issue'] }
249
+ )
249
250
 
250
- create_qa_branch(
251
- :preserve => true,
252
- :range => (branches.index(conflict)+1..-1),
253
- :qa_branch => qa_branch
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 'Pending QA'.\n".green
307
+ puts "\nLabeling issue as '#{label}'.\n".green
302
308
  get('label',
303
309
  'branch[name]' => branches(:current => true),
304
- 'labels' => [ 'Pending QA' ]
310
+ 'labels' => [ label ]
305
311
  )
306
312
  else
307
- puts "\nLabeling issues as 'Pending QA'.\n".green
313
+ puts "\nLabeling issues as '#{label}'.\n".green
308
314
  get('label',
309
315
  'issues' => issues,
310
- 'labels' => [ 'Pending QA' ],
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 "\nFetching remote repo '#{owner}'.\n".green
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 "\nChecking out remote branch '#{branch}' from '#{owner}/#{repo}'.\n".green
388
+ puts "Checking out remote branch '#{target}' from '#{owner}/#{repo}/#{branch}'.\n".green
389
+ run("git checkout -b #{target} #{owner}/#{branch}")
374
390
 
375
- if branches(:match => branch)
376
- run("git checkout #{branch}")
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: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 10
10
- version: 0.1.10
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-20 00:00:00 -08:00
18
+ date: 2012-01-23 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency