git-maintain 0.7.0 → 0.9.0rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +22 -0
- data/LICENSE +674 -22
- data/README.md +26 -5
- data/bin/git-maintain +8 -5
- data/lib/addons/RDMACore.rb +67 -7
- data/lib/addons/git-maintain.rb +66 -0
- data/lib/azure.rb +98 -0
- data/lib/branch.rb +141 -78
- data/lib/ci.rb +88 -0
- data/lib/common.rb +29 -16
- data/lib/repo.rb +143 -72
- data/lib/travis.rb +19 -62
- metadata +19 -10
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def self.load(repo, version,
|
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,
|
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[:
|
55
|
-
opts[:
|
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]
|
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
|
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-
|
97
|
-
|val| opts[:
|
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[:
|
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
|
-
|
136
|
+
ci = CI::load(repo)
|
125
137
|
opts[:repo] = repo
|
126
|
-
opts[:
|
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,
|
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],
|
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
|
-
|
193
|
+
ci.emptyCache()
|
182
194
|
end
|
183
195
|
end
|
184
196
|
|
185
|
-
def initialize(repo, version,
|
197
|
+
def initialize(repo, version, ci, branch_suff)
|
186
198
|
GitMaintain::checkDirectConstructor(self.class)
|
187
199
|
|
188
200
|
@repo = repo
|
189
|
-
@
|
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
|
-
|
227
|
-
return
|
228
|
-
|
229
|
-
return
|
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
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
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)
|
332
|
-
|
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
|
371
|
+
# Monitor the build status on CI
|
349
372
|
def monitor(opts)
|
350
|
-
st = @
|
373
|
+
st = @ci.getValidState(self, @head)
|
351
374
|
suff=""
|
352
375
|
case st
|
353
376
|
when "started"
|
354
|
-
suff= " started at #{@
|
377
|
+
suff= " started at #{@ci.getValidTS(self, @head)}"
|
355
378
|
end
|
356
379
|
log(:INFO, "Status for v#{@version}: " + st + suff)
|
357
|
-
if (
|
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 = @
|
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 (
|
379
|
-
|
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
|
385
|
-
|
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
|
434
|
+
# Monitor the build status of the stable branch on CI
|
412
435
|
def monitor_stable(opts)
|
413
|
-
st = @
|
436
|
+
st = @ci.getStableState(self, @stable_head)
|
414
437
|
suff=""
|
415
438
|
case st
|
416
439
|
when "started"
|
417
|
-
suff= " started at #{@
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
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
|
-
|
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
|
-
|
82
|
-
|
83
|
-
while
|
84
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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 :
|
177
|
-
_log("
|
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
|