git-maintain 0.7.0 → 0.9.0rc1

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/branch.rb CHANGED
@@ -24,43 +24,45 @@ module GitMaintain
24
24
  ALL_BRANCHES_ACTIONS = [
25
25
  :create
26
26
  ]
27
- ACTION_HELP = [
28
- "* cp: Backport commits and eventually push them to github",
29
- "* create: Create missing local branches from all the stable branches",
30
- "* delete: Delete all local branches using the suffix",
31
- "* steal: Steal commit from upstream that fixes commit in the branch or were tagged as stable",
32
- "* list: List commit present in the branch but not in the stable branch",
33
- "* list_stable: List commit present in the stable branch but not in the latest associated relase",
34
- "* merge: Merge branch with suffix specified in -m <suff> into the main branch",
35
- "* push: Push branches to github for validation",
36
- "* monitor: Check the travis state of all branches",
37
- "* push_stable: Push to stable repo",
38
- "* monitor_stable: Check the travis state of all stable branches",
39
- "* release: Create new release on all concerned branches",
40
- "* reset: Reset branch against upstream",
41
- ]
42
-
43
- def self.load(repo, version, travis, branch_suff)
27
+ ACTION_HELP = {
28
+ :cp => "Backport commits and eventually push them to github",
29
+ :create => "Create missing local branches from all the stable branches",
30
+ :delete => "Delete all local branches using the suffix",
31
+ :steal => "Steal commit from upstream that fixes commit in the branch or were tagged as stable",
32
+ :list => "List commit present in the branch but not in the stable branch",
33
+ :list_stable => "List commit present in the stable branch but not in the latest associated relase",
34
+ :merge => "Merge branch with suffix specified in -m <suff> into the main branch",
35
+ :push => "Push branches to github for validation",
36
+ :monitor => "Check the CI state of all branches",
37
+ :push_stable => "Push to stable repo",
38
+ :monitor_stable => "Check the CI state of all stable branches",
39
+ :release => "Create new release on all concerned branches",
40
+ :reset => "Reset branch against upstream",
41
+ }
42
+
43
+ def self.load(repo, version, ci, branch_suff)
44
44
  repo_name = File.basename(repo.path)
45
- return GitMaintain::loadClass(Branch, repo_name, repo, version, travis, branch_suff)
45
+ return GitMaintain::loadClass(Branch, repo_name, repo, version, ci, branch_suff)
46
46
  end
47
47
 
48
48
  def self.set_opts(action, optsParser, opts)
49
49
  opts[:base_ver] = 0
50
- opts[:version] = /.*/
50
+ opts[:version] = []
51
51
  opts[:commits] = []
52
52
  opts[:do_merge] = false
53
53
  opts[:push_force] = false
54
- opts[:no_travis] = false
55
- opts[:all] = false
54
+ opts[:no_ci] = false
55
+ opts[:steal_base] = nil
56
56
  opts[:check_only] = false
57
57
  opts[:fetch] = nil
58
58
  opts[:watch] = false
59
+ opts[:delete_remote] = false
60
+ opts[:no_edit] = false
59
61
 
60
62
  optsParser.on("-v", "--base-version [MIN_VER]", Integer, "Older release to consider.") {
61
63
  |val| opts[:base_ver] = val}
62
64
  optsParser.on("-V", "--version [regexp]", Regexp, "Regexp to filter versions.") {
63
- |val| opts[:version] = val}
65
+ |val| opts[:version] << val}
64
66
 
65
67
  if ALL_BRANCHES_ACTIONS.index(action) == nil &&
66
68
  action != :merge &&
@@ -79,13 +81,16 @@ module GitMaintain
79
81
  optsParser.banner += "-c <sha1> [-c <sha1> ...]"
80
82
  optsParser.on("-c", "--sha1 [SHA1]", String, "Commit to cherry-pick. Can be used multiple time.") {
81
83
  |val| opts[:commits] << val}
84
+ when :delete
85
+ optsParser.on("--remote", "Delete the remote staging branch instead of the local ones.") {
86
+ |val| opts[:delete_remote] = true}
82
87
  when :merge
83
88
  optsParser.banner += "-m <suffix>"
84
89
  optsParser.on("-m", "--merge [SUFFIX]", "Merge branch with suffix.") {
85
90
  |val| opts[:do_merge] = val}
86
91
  when :monitor, :monitor_stable
87
92
  optsParser.on("-w", "--watch <PERIOD>", Integer,
88
- "Watch and refresh travis status every <PERIOD>.") {
93
+ "Watch and refresh CI status every <PERIOD>.") {
89
94
  |val| opts[:watch] = val}
90
95
  when :push
91
96
  optsParser.banner += "[-f]"
@@ -93,15 +98,21 @@ module GitMaintain
93
98
  |val| opts[:push_force] = val}
94
99
  when :push_stable
95
100
  optsParser.banner += "[-T]"
96
- optsParser.on("-T", "--no-travis", "Ignore Travis build status and push anyway.") {
97
- |val| opts[:no_travis] = true}
101
+ optsParser.on("-T", "--no-ci", "Ignore CI build status and push anyway.") {
102
+ |val| opts[:no_ci] = true}
98
103
  optsParser.on("-c", "--check", "Check if there is something to be pushed.") {
99
104
  |val| opts[:check_only] = true}
105
+ when :release
106
+ optsParser.on("--no-edit", "Do not edit release commit nor tag.") {
107
+ opts[:no_edit] = true }
100
108
  when :steal
101
- optsParser.banner += "[-a]"
109
+ optsParser.banner += "[-a][-b <HEAD>]"
102
110
  optsParser.on("-a", "--all", "Check all commits from master. "+
103
111
  "By default only new commits (since last successful run) are considered.") {
104
- |val| opts[:all] = true}
112
+ |val| opts[:steal_base] = :all}
113
+ optsParser.on("-b", "--base <HEAD>", "Check all commits from this commit. "+
114
+ "By default only new commits (since last successful run) are considered.") {
115
+ |val| opts[:steal_base] = val}
105
116
  end
106
117
  end
107
118
 
@@ -112,18 +123,19 @@ module GitMaintain
112
123
  raise "Action #{opts[:action]} can only be done on 'master' suffixed branches"
113
124
  end
114
125
  end
115
- if opts[:action] == :delete then
126
+ if opts[:action] == :delete && opts[:delete_remote] != true then
116
127
  if opts[:br_suff] == "master" then
117
128
  raise "Action #{opts[:action]} can NOT be done on 'master' suffixed branches"
118
129
  end
119
130
  end
131
+ opts[:version] = [ /.*/ ] if opts[:version].length == 0
120
132
  end
121
133
 
122
134
  def self.execAction(opts, action)
123
135
  repo = Repo::load()
124
- travis = TravisChecker::load(repo)
136
+ ci = CI::load(repo)
125
137
  opts[:repo] = repo
126
- opts[:travis] = travis
138
+ opts[:ci] = ci
127
139
  brClass = GitMaintain::getClass(self, repo.name)
128
140
 
129
141
  if NO_FETCH_ACTIONS.index(action) == nil && opts[:fetch] != false then
@@ -140,7 +152,7 @@ module GitMaintain
140
152
  unfilteredList = repo.getBranchList(opts[:br_suff])
141
153
  end
142
154
  branchList = unfilteredList.map(){|br|
143
- branch = Branch::load(repo, br, travis, opts[:br_suff])
155
+ branch = Branch::load(repo, br, ci, opts[:br_suff])
144
156
  case branch.is_targetted?(opts)
145
157
  when :too_old
146
158
  GitMaintain::log(:VERBOSE, "Skipping older v#{branch.version}")
@@ -153,7 +165,7 @@ module GitMaintain
153
165
  branch
154
166
  }.compact()
155
167
  else
156
- branchList = [ Branch::load(repo, opts[:manual_branch], travis, opts[:br_suff]) ]
168
+ branchList = [ Branch::load(repo, opts[:manual_branch], ci, opts[:br_suff]) ]
157
169
  end
158
170
 
159
171
  loop do
@@ -178,15 +190,15 @@ module GitMaintain
178
190
 
179
191
  break if opts[:watch] == false
180
192
  sleep(opts[:watch])
181
- travis.emptyCache()
193
+ ci.emptyCache()
182
194
  end
183
195
  end
184
196
 
185
- def initialize(repo, version, travis, branch_suff)
197
+ def initialize(repo, version, ci, branch_suff)
186
198
  GitMaintain::checkDirectConstructor(self.class)
187
199
 
188
200
  @repo = repo
189
- @travis = travis
201
+ @ci = ci
190
202
  @version = version
191
203
  @branch_suff = branch_suff
192
204
 
@@ -223,10 +235,10 @@ module GitMaintain
223
235
  if @version.to_i < opts[:base_ver] then
224
236
  return :too_old
225
237
  end
226
- if @version !~ opts[:version] then
227
- return :no_match
228
- end
229
- return true
238
+ opts[:version].each() {|regexp|
239
+ return true if @version =~ regexp
240
+ }
241
+ return :no_match
230
242
  end
231
243
 
232
244
  # Checkout the repo to the given branch
@@ -261,17 +273,27 @@ module GitMaintain
261
273
 
262
274
  # If we are not force checking everything,
263
275
  # try to start from the last tag we steal upto
264
- if opts[:all] != true then
265
- sha = @repo.runGit("rev-parse 'git-maintain/steal/last/#{@stable_base}' 2>&1")
266
- if $? == 0 then
267
- base_ref=sha
268
- log(:VERBOSE, "Starting from last successfull run:")
269
- log(:VERBOSE, @repo.getCommitHeadline(base_ref))
270
- end
276
+ case opts[:steal_base]
277
+ when nil
278
+ sha = @repo.runGit("rev-parse 'git-maintain/steal/last/#{@stable_base}' 2>&1")
279
+ if $? == 0 then
280
+ base_ref=sha
281
+ log(:VERBOSE, "Starting from last successfull run:")
282
+ log(:VERBOSE, @repo.getCommitHeadline(base_ref))
283
+ end
284
+ when :all
285
+ base_ref=@stable_base
286
+ else
287
+ sha = @repo.runGit("rev-parse #{opts[:steal_base]} 2>&1")
288
+ if $? == 0 then
289
+ base_ref=sha
290
+ log(:VERBOSE, "Starting from base:")
291
+ log(:VERBOSE, @repo.getCommitHeadline(base_ref))
292
+ end
271
293
  end
272
294
 
273
295
  master_sha=@repo.runGit("rev-parse origin/master")
274
- res = steal_all(opts, "#{base_ref}..#{master_sha}")
296
+ res = steal_all(opts, "#{base_ref}..#{master_sha}", true)
275
297
 
276
298
  # If we picked all the commits (or nothing happened)
277
299
  # Mark the current master as the last checked point so we
@@ -328,8 +350,9 @@ module GitMaintain
328
350
 
329
351
  # Push the branch to the validation repo
330
352
  def push(opts)
331
- if same_sha?(@local_branch, @repo.valid_repo + "/" + @local_branch) then
332
- log(:INFO, "Nothing to push")
353
+ if same_sha?(@local_branch, @repo.valid_repo + "/" + @local_branch) ||
354
+ same_sha?(@local_branch, @remote_ref) then
355
+ log(:INFO, "Nothing to push on #{@local_branch}")
333
356
  return
334
357
  end
335
358
  return "#{@local_branch}:#{@local_branch}"
@@ -345,22 +368,22 @@ module GitMaintain
345
368
  "#{opts[:repo].valid_repo} #{branches.join(" ")}")
346
369
  end
347
370
 
348
- # Monitor the build status on Travis
371
+ # Monitor the build status on CI
349
372
  def monitor(opts)
350
- st = @travis.getValidState(head)
373
+ st = @ci.getValidState(self, @head)
351
374
  suff=""
352
375
  case st
353
376
  when "started"
354
- suff= " started at #{@travis.getValidTS(head)}"
377
+ suff= " started at #{@ci.getValidTS(self, @head)}"
355
378
  end
356
379
  log(:INFO, "Status for v#{@version}: " + st + suff)
357
- if (st == "failed" || st == "errored") && opts[:watch] == false
380
+ if @ci.isErrored(self, st) && opts[:watch] == false
358
381
  rep = "y"
359
382
  suff=""
360
383
  while rep == "y"
361
384
  rep = GitMaintain::confirm(opts, "see the build log#{suff}")
362
385
  if rep == "y" then
363
- log = @travis.getValidLog(head)
386
+ log = @ci.getValidLog(self, @head)
364
387
  tmp = `mktemp`.chomp()
365
388
  tmpfile = File.open(tmp, "w+")
366
389
  tmpfile.puts(log)
@@ -375,14 +398,14 @@ module GitMaintain
375
398
 
376
399
  # Push branch to the stable repo
377
400
  def push_stable(opts)
378
- if (opts[:no_travis] != true && @NO_TRAVIS != true) &&
379
- @travis.checkValidState(@head) != true then
380
- log(:WARNING, "Build is not passed on travis. Skipping push to stable")
401
+ if same_sha?(@local_branch, @remote_ref) then
402
+ log(:INFO, "Stable is already up-to-date")
381
403
  return
382
404
  end
383
405
 
384
- if same_sha?(@local_branch, @remote_ref) then
385
- log(:INFO, "Stable is already up-to-date")
406
+ if (opts[:no_ci] != true && @NO_CI != true) &&
407
+ @ci.checkValidState(self, @head) != true then
408
+ log(:WARNING, "Build is not passed on CI. Skipping push to stable")
386
409
  return
387
410
  end
388
411
 
@@ -408,13 +431,13 @@ module GitMaintain
408
431
  return if branches.length == 0
409
432
  opts[:repo].runGit("push #{opts[:repo].stable_repo} #{branches.join(" ")}")
410
433
  end
411
- # Monitor the build status of the stable branch on Travis
434
+ # Monitor the build status of the stable branch on CI
412
435
  def monitor_stable(opts)
413
- st = @travis.getStableState(@stable_head)
436
+ st = @ci.getStableState(self, @stable_head)
414
437
  suff=""
415
438
  case st
416
439
  when "started"
417
- suff= " started at #{@travis.getStableTS(@stable_head)}"
440
+ suff= " started at #{@ci.getStableTS(self, @stable_head)}"
418
441
  end
419
442
  log(:INFO, "Status for v#{@version}: " + st + suff)
420
443
  end
@@ -446,14 +469,41 @@ module GitMaintain
446
469
  end
447
470
 
448
471
  def delete(opts)
449
- rep = GitMaintain::confirm(opts, "delete branch #{@local_branch}")
472
+ if opts[:delete_remote] == true then
473
+ @repo.runGit("rev-parse --verify --quiet #{@repo.valid_repo}/#{@local_branch}")
474
+ if $? != 0 then
475
+ log(:DEBUG, "Skipping non existing remote branch #{@local_branch}.")
476
+ return
477
+ end
478
+ msg = "delete remote branch #{@repo.valid_repo}/#{@local_branch}"
479
+ else
480
+ msg = "delete branch #{@local_branch}"
481
+ end
482
+ rep = GitMaintain::confirm(opts, msg)
450
483
  if rep == "y" then
451
- @repo.runGit("branch -D #{@local_branch}")
484
+ return @local_branch
452
485
  else
453
486
  log(:INFO, "Skipping deletion")
454
487
  return
455
488
  end
456
489
  end
490
+ def self.delete_epilogue(opts, branches)
491
+ # Compact to remove empty entries
492
+ branches.compact!()
493
+
494
+ return if branches.length == 0
495
+ puts "Deleting #{opts[:delete_remote] == true ? "remote" : "local"} branches: #{branches.join(" ")}"
496
+ rep = GitMaintain::confirm(opts, "continue", true)
497
+ if rep != "y" then
498
+ log(:INFO, "Cancelling")
499
+ return
500
+ end
501
+ if opts[:delete_remote] == true then
502
+ opts[:repo].runGit("push #{opts[:repo].valid_repo} #{branches.map(){|x| ":" + x}.join(" ")}")
503
+ else
504
+ opts[:repo].runGit("branch -D #{branches.join(" ")}")
505
+ end
506
+ end
457
507
 
458
508
  private
459
509
  def add_blacklist(commit)
@@ -532,13 +582,15 @@ module GitMaintain
532
582
  end
533
583
 
534
584
  # Let's see if there's a version tag in this commit
535
- full=@repo.runGit("show #{commit} | grep -i 'stable@'").gsub(/.* /, "")
585
+ full=@repo.runGit("show #{commit} | grep -i 'stable@'").gsub(/.* #?/, "")
536
586
 
537
587
  # Sanity check our extraction
538
588
  if full =~ /stable/ then
539
589
  return false
540
590
  end
541
591
 
592
+ full = @repo.runGit("rev-parse #{full}^{commit}")
593
+
542
594
  # Make sure our branch contains this version
543
595
  if @repo.runGit("merge-base #{@head} #{full}") == full then
544
596
  return true
@@ -578,13 +630,18 @@ module GitMaintain
578
630
  puts @repo.getCommitHeadline(commit)
579
631
  while rep != "y" do
580
632
  puts "Do you want to steal this commit ? (y/n/b/?)"
581
- if opts[:no] == true then
633
+ case opts[:yn_default]
634
+ when :no
582
635
  log(:INFO, "Auto-replying no due to --no option")
583
636
  rep = 'n'
584
637
  break
638
+ when :yes
639
+ log(:INFO, "Auto-replying yes due to --yes option")
640
+ rep = 'y'
585
641
  else
586
642
  rep = STDIN.gets.chomp()
587
643
  end
644
+
588
645
  case rep
589
646
  when "n"
590
647
  log(:INFO, "Skip this commit")
@@ -607,17 +664,23 @@ module GitMaintain
607
664
  return do_cp
608
665
  end
609
666
 
610
- def steal_one(opts, commit)
611
- subj=@repo.getCommitSubj(commit)
612
- subj.gsub!(/"/, '\"')
667
+ def steal_one(opts, commit, mainline=false)
613
668
  msg=''
614
-
615
- # Let's grab the mainline commit id, this is useful if the version tag
616
- # doesn't exist in the commit we're looking at but exists upstream.
617
- orig_cmt=@repo.runGit("log --no-merges --format=\"%H\" -F --grep \"#{subj}\" " +
618
- "#{@stable_base}..origin/master | tail -n1")
619
-
620
- # If the commit doesn't apply for us, skip it
669
+ orig_cmt=commit
670
+
671
+ if mainline == false then
672
+ subj=@repo.getCommitSubj(commit)
673
+ subj.gsub!(/"/, '\"')
674
+ # Let's grab the mainline commit id, this is useful if the version tag
675
+ # doesn't exist in the commit we're looking at but exists upstream.
676
+ orig_cmt=@repo.runGit("log --no-merges --format=\"%H\" -F --grep \"#{subj}\" " +
677
+ "#{@stable_base}..origin/master | tail -n1")
678
+
679
+ if orig_cmt == "" then
680
+ log(:WARNING, "Could not find commit #{commit} in mainline")
681
+ end
682
+ end
683
+ # If the commit doesn't apply for us, skip it
621
684
  if is_relevant?(orig_cmt) != true
622
685
  return true
623
686
  end
@@ -663,10 +726,10 @@ module GitMaintain
663
726
  end
664
727
  end
665
728
 
666
- def steal_all(opts, range)
729
+ def steal_all(opts, range, mainline = false)
667
730
  res = true
668
731
  @repo.runGit("log --no-merges --format=\"%H\" #{range} | tac").split("\n").each(){|commit|
669
- res &= steal_one(opts, commit)
732
+ res &= steal_one(opts, commit, mainline)
670
733
  }
671
734
  return res
672
735
  end
data/lib/ci.rb ADDED
@@ -0,0 +1,88 @@
1
+ module GitMaintain
2
+ class CI
3
+
4
+ def self.load(repo)
5
+ repo_name = File.basename(repo.path)
6
+ return GitMaintain::loadClass(CI, repo_name, repo)
7
+ end
8
+
9
+ def initialize(repo)
10
+ GitMaintain::checkDirectConstructor(self.class)
11
+
12
+ @repo = repo
13
+ @cachedJson={}
14
+ end
15
+
16
+ private
17
+ def log(lvl, str)
18
+ GitMaintain::log(lvl, str)
19
+ end
20
+
21
+ def fetch(uri_str, limit = 10)
22
+ # You should choose a better exception.
23
+ raise ArgumentError, 'too many HTTP redirects' if limit == 0
24
+
25
+ response = Net::HTTP.get_response(URI(uri_str))
26
+
27
+ case response
28
+ when Net::HTTPSuccess then
29
+ response
30
+ when Net::HTTPRedirection then
31
+ location = response['location']
32
+ fetch(location, limit - 1)
33
+ else
34
+ response.value
35
+ end
36
+ end
37
+ def getJson(base_url, query_label, query, json=true)
38
+ return @cachedJson[query_label] if @cachedJson[query_label] != nil
39
+ url = base_url + query
40
+ uri = URI(url)
41
+ log(:INFO, "Querying CI...")
42
+ log(:DEBUG_CI, url)
43
+ response = fetch(uri)
44
+ raise("CI request failed '#{url}'") if response.code.to_s() != '200'
45
+
46
+ if json == true
47
+ @cachedJson[query_label] = JSON.parse(response.body)
48
+ else
49
+ @cachedJson[query_label] = response.body
50
+ end
51
+ return @cachedJson[query_label]
52
+ end
53
+
54
+ public
55
+ def getValidState(br, sha1)
56
+ raise("Unimplemented")
57
+ end
58
+ def checkValidState(br, sha1)
59
+ raise("Unimplemented")
60
+ end
61
+ def getValidLog(br, sha1)
62
+ raise("Unimplemented")
63
+ end
64
+ def getValidTS(br, sha1)
65
+ raise("Unimplemented")
66
+ end
67
+
68
+ def getStableState(br, sha1)
69
+ raise("Unimplemented")
70
+ end
71
+ def checkStableState(br, sha1)
72
+ raise("Unimplemented")
73
+ end
74
+ def getStableLog(br, sha1)
75
+ raise("Unimplemented")
76
+ end
77
+ def getStableTS(br, sha1)
78
+ raise("Unimplemented")
79
+ end
80
+ def emptyCache()
81
+ @cachedJson={}
82
+ end
83
+
84
+ def isErrored(br, status)
85
+ raise("Unimplemented")
86
+ end
87
+ end
88
+ end
data/lib/common.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  $LOAD_PATH.push(BACKPORT_LIB_DIR)
2
2
 
3
+ require 'ci'
3
4
  require 'travis'
5
+ require 'azure'
4
6
  require 'repo'
5
7
  require 'branch'
6
8
 
@@ -42,7 +44,7 @@ end
42
44
  module GitMaintain
43
45
  class Common
44
46
  ACTION_LIST = [ :list_actions ]
45
- ACTION_HELP = []
47
+ ACTION_HELP = {}
46
48
  def self.execAction(opts, action)
47
49
  puts GitMaintain::getActionAttr("ACTION_LIST").join("\n")
48
50
  end
@@ -50,7 +52,7 @@ module GitMaintain
50
52
 
51
53
  ACTION_CLASS = [ Common, Branch, Repo ]
52
54
  @@custom_classes = {}
53
-
55
+ @@load_class = []
54
56
  @@verbose_log = false
55
57
 
56
58
  def registerCustom(repo_name, classes)
@@ -72,25 +74,31 @@ module GitMaintain
72
74
  module_function :getClass
73
75
 
74
76
  def loadClass(default_class, repo_name, *more)
75
- return GitMaintain::getClass(default_class, repo_name).new(*more)
77
+ @@load_class.push(default_class)
78
+ obj = GitMaintain::getClass(default_class, repo_name).new(*more)
79
+ @@load_class.pop()
80
+ return obj
76
81
  end
77
82
  module_function :loadClass
78
83
 
79
84
  # Check that the constructor was called through loadClass
80
85
  def checkDirectConstructor(theClass)
81
- # Look for the "new" in the calling tree
82
- depth = 1
83
- while caller_locations(depth, 1)[0].label != "new"
84
- depth +=1
86
+ curLoad= @@load_class.last()
87
+ cl = theClass
88
+ while cl != Object
89
+ return if cl == curLoad
90
+ cl = cl.superclass
85
91
  end
86
- # The function that called the constructer is just one step below
87
- raise("Use GitMaintain::loadClass to construct a #{theClass} class") if
88
- caller_locations(depth + 1, 1)[0].label != "loadClass"
92
+ raise("Use GitMaintain::loadClass to construct a #{theClass} class")
89
93
  end
90
94
  module_function :checkDirectConstructor
91
95
 
92
96
  def getActionAttr(attr)
93
- return ACTION_CLASS.map(){|x| x.const_get(attr)}.flatten()
97
+ if Common.const_get(attr).class == Hash
98
+ return ACTION_CLASS.inject({}){|h, x| h.merge(x.const_get(attr))}
99
+ else
100
+ return ACTION_CLASS.map(){|x| x.const_get(attr)}.flatten()
101
+ end
94
102
  end
95
103
  module_function :getActionAttr
96
104
 
@@ -112,6 +120,7 @@ module GitMaintain
112
120
 
113
121
  def checkOpts(opts)
114
122
  ACTION_CLASS.each(){|x|
123
+ next if x::ACTION_LIST.index(opts[:action]) == nil
115
124
  next if x.singleton_methods().index(:check_opts) == nil
116
125
  x.check_opts(opts)
117
126
 
@@ -133,13 +142,17 @@ module GitMaintain
133
142
  end
134
143
  module_function :execAction
135
144
 
136
- def confirm(opts, msg)
145
+ def confirm(opts, msg, ignore_default=false)
137
146
  rep = 't'
138
147
  while rep != "y" && rep != "n" && rep != '' do
139
148
  puts "Do you wish to #{msg} ? (y/N): "
140
- if opts[:no] == true then
149
+ case (ignore_default == true ? nil : opts[:yn_default])
150
+ when :no
141
151
  puts "Auto-replying no due to --no option"
142
152
  rep = 'n'
153
+ when :yes
154
+ puts "Auto-replying yes due to --yes option"
155
+ rep = 'y'
143
156
  else
144
157
  rep = STDIN.gets.chomp()
145
158
  end
@@ -150,7 +163,7 @@ module GitMaintain
150
163
 
151
164
  def checkLog(opts, br1, br2, action_msg)
152
165
  puts "Diff between #{br1} and #{br2}"
153
- puts `git shortlog #{br1} ^#{br2}`
166
+ puts `git log --format=oneline #{br1} ^#{br2}`
154
167
  return "n" if action_msg.to_s() == ""
155
168
  rep = confirm(opts, "#{action_msg} this branch")
156
169
  return rep
@@ -173,8 +186,8 @@ module GitMaintain
173
186
  case lvl
174
187
  when :DEBUG
175
188
  _log("DEBUG".magenta(), str) if ENV["DEBUG"].to_s() != ""
176
- when :DEBUG_TRAVIS
177
- _log("DEBUG_TRAVIS".magenta(), str) if ENV["DEBUG_TRAVIS"].to_s() != ""
189
+ when :DEBUG_CI
190
+ _log("DEBUG_CI".magenta(), str) if ENV["DEBUG_CI"].to_s() != ""
178
191
  when :VERBOSE
179
192
  _log("INFO".blue(), str) if @@verbose_log == true
180
193
  when :INFO