git-maintain 0.11.0 → 0.12.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +10 -0
- data/git-maintain-completion.sh +2 -2
- data/lib/addons/RDMACore.rb +19 -20
- data/lib/addons/git-maintain.rb +2 -10
- data/lib/branch.rb +232 -166
- data/lib/common.rb +7 -1
- data/lib/repo.rb +143 -112
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f55eb06d04154df930e2e69d85b4d0d3b882361681f2d70a2acc503dc9abfad
|
4
|
+
data.tar.gz: 6d4597f517459cf6304ca419ef7b4897b894c032200f311a1efd549524fc13ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9363ed5154f62cef4ac12ee4a1599c108f48bd192dcaea8154cbf4b0db3f80eda06baf8972f39986d8870b6cf5c812ad6877d0fd75c24eb594e4f9e96dc53731
|
7
|
+
data.tar.gz: 97d60ac6e78bec2d3c8c6233e99412f4941c1e9fed9f69f1ce9acc923e9f3060279c9a82d7dd6f50a66b6c50c6799c0d686e86aeaec984b8fe704e018497f3d9
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
------------------
|
2
|
+
0.12.0 (2025-09-11)
|
3
|
+
------------------
|
4
|
+
|
5
|
+
* Cleanup code for Addons releases
|
6
|
+
* Replace all egrep calls with grep -E
|
7
|
+
* Replace $? handling with Exceptions
|
8
|
+
* Various minor fixes
|
9
|
+
* Drop obsolete Travis CI code
|
10
|
+
|
1
11
|
------------------
|
2
12
|
0.11.0 (2025-04-15)
|
3
13
|
------------------
|
data/git-maintain-completion.sh
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
export _GIT_MAINTAIN_CMD_AWK=$(([ -f /bin/awk ] && echo "/bin/awk") || echo "/usr/bin/awk")
|
2
2
|
export _GIT_MAINTAIN_CMD_SORT=$(([ -f /bin/sort ] && echo "/bin/sort") || echo "/usr/bin/sort")
|
3
|
-
export
|
3
|
+
export _GIT_MAINTAIN_CMD_GREP=$(([ -f /bin/grep ] && echo "/bin/grep") || echo "/usr/bin/grep")
|
4
4
|
export _GIT_MAINTAIN_CMD_SED=$(([ -f /bin/sed ] && echo "/bin/sed") || echo "/usr/bin/sed")
|
5
5
|
|
6
6
|
_git_maintain_genoptlist(){
|
7
7
|
local COMMAND=$*
|
8
8
|
${COMMAND} --help 2>&1 | \
|
9
9
|
${_GIT_MAINTAIN_CMD_AWK} 'BEGIN { found = 0 } { if(found == 1) print $$0; if($$1 == "Options:") {found = 1}}' | \
|
10
|
-
${
|
10
|
+
${_GIT_MAINTAIN_CMD_GREP} -E -e "^[[:space:]]*--" -e "^[[:space:]]*-[a-zA-Z0-9]" | \
|
11
11
|
${_GIT_MAINTAIN_CMD_SED} -e 's/^[[:space:]]*//' -e 's/^-[^-], //' | \
|
12
12
|
${_GIT_MAINTAIN_CMD_AWK} '{ print $1}' | \
|
13
13
|
${_GIT_MAINTAIN_CMD_SED} -e 's/^\(.*\)\[no-\]\(.*$\)/\1\2\n\1no-\2/' | \
|
data/lib/addons/RDMACore.rb
CHANGED
@@ -32,7 +32,7 @@ module GitMaintain
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
def release(opts)
|
35
|
-
prev_ver=@repo.runGit("show HEAD:CMakeLists.txt |
|
35
|
+
prev_ver=@repo.runGit("show HEAD:CMakeLists.txt | grep -E \"[sS][eE][tT]\\\\(PACKAGE_VERSION\"").
|
36
36
|
chomp().gsub(/[sS][eE][tT]\(PACKAGE_VERSION\s*"([0-9.]*)".*$/, '\1')
|
37
37
|
ver_nums = prev_ver.split(".")
|
38
38
|
new_ver = (ver_nums[0 .. -2] + [ver_nums[-1].to_i() + 1 ]).join(".")
|
@@ -49,8 +49,9 @@ module GitMaintain
|
|
49
49
|
|
50
50
|
git_prev_ver = "v" + prev_ver
|
51
51
|
# Older tags might do have the terminal minor version (.0) for major releases
|
52
|
-
|
53
|
-
|
52
|
+
begin
|
53
|
+
@repo.ref_exist?(git_prev_ver)
|
54
|
+
rescue NoRefError
|
54
55
|
# Try without the minor version number
|
55
56
|
git_prev_ver = "v" + ver_nums[0 .. -2].join(".")
|
56
57
|
end
|
@@ -80,10 +81,7 @@ module GitMaintain
|
|
80
81
|
|
81
82
|
if opts[:rel_type] == :major
|
82
83
|
# For major, tag the current version first
|
83
|
-
|
84
|
-
if $? != 0 then
|
85
|
-
raise("Failed to tag branch #{local_branch}")
|
86
|
-
end
|
84
|
+
release_do_tag(opts, "v" + rel_ver, tag_path)
|
87
85
|
end
|
88
86
|
|
89
87
|
# Update version number in relevant files
|
@@ -107,23 +105,21 @@ mv debian/changelog.new debian/changelog")
|
|
107
105
|
end
|
108
106
|
|
109
107
|
# Add and commit
|
110
|
-
|
111
|
-
|
112
|
-
if $? != 0 then
|
113
|
-
raise("Failed to commit on branch #{local_branch}")
|
114
|
-
end
|
108
|
+
release_do_add_commit(opts, [ "*/*.spec", "CMakeLists.txt", "debian/changelog" ],
|
109
|
+
new_ver, nil, "#{commit_msg} #{new_ver}")
|
115
110
|
|
116
111
|
if opts[:rel_type] == :stable
|
117
|
-
|
118
|
-
if $? != 0 then
|
119
|
-
raise("Failed to tag branch #{local_branch}")
|
120
|
-
end
|
112
|
+
release_do_tag(opts, rel_ver, tag_path)
|
121
113
|
end
|
122
114
|
`rm -f #{tag_path}`
|
115
|
+
return 0
|
123
116
|
end
|
124
117
|
def validate(opts)
|
125
|
-
|
126
|
-
|
118
|
+
begin
|
119
|
+
@repo.runSystem("rm -Rf build/ && mkdir build/ && cd build/ && cmake .. && make -j")
|
120
|
+
rescue RuntimeError
|
121
|
+
raise("Validation failure")
|
122
|
+
end
|
127
123
|
end
|
128
124
|
end
|
129
125
|
class RDMACoreRepo < Repo
|
@@ -181,8 +177,11 @@ mv debian/changelog.new debian/changelog")
|
|
181
177
|
cmdList << "./buildlib/cbuild pkg azp"
|
182
178
|
|
183
179
|
toDo=cmdList.join("&&")
|
184
|
-
|
185
|
-
|
180
|
+
begin
|
181
|
+
runSystem(toDo)
|
182
|
+
rescue RuntimeError
|
183
|
+
raise("Fail to run stable creation code")
|
184
|
+
end
|
186
185
|
end
|
187
186
|
end
|
188
187
|
|
data/lib/addons/git-maintain.rb
CHANGED
@@ -69,17 +69,9 @@ $(cat CHANGELOG)
|
|
69
69
|
EOF
|
70
70
|
mv CHANGELOG.new CHANGELOG")
|
71
71
|
|
72
|
-
|
73
|
-
@repo.runGit("add CHANGELOG")
|
74
|
-
@repo.runGitInteractive("commit -F #{tag_path} --verbose --edit --signoff")
|
75
|
-
if $? != 0 then
|
76
|
-
raise("Failed to commit on branch #{local_branch}")
|
77
|
-
end
|
78
|
-
@repo.runGitInteractive("tag -a -s v#{new_ver} --edit -F #{tag_path}")
|
79
|
-
if $? != 0 then
|
80
|
-
raise("Failed to tag branch #{local_branch}")
|
81
|
-
end
|
72
|
+
release_do_add_commit_tag(opts, ["CHANGELOG"], "v" + new_ver, tag_path)
|
82
73
|
`rm -f #{tag_path}`
|
74
|
+
return 0
|
83
75
|
end
|
84
76
|
end
|
85
77
|
class GitMaintainRepo < Repo
|
data/lib/branch.rb
CHANGED
@@ -83,8 +83,8 @@ module GitMaintain
|
|
83
83
|
optsParser.on("--remote", "Delete the remote staging branch instead of the local ones.") {
|
84
84
|
|val| opts[:delete_remote] = true}
|
85
85
|
when :list
|
86
|
-
|
87
|
-
|
86
|
+
optsParser.on("--stable", "List unreleased commits in the upstream stable branch.") {
|
87
|
+
opts[:stable] = true }
|
88
88
|
when :merge
|
89
89
|
optsParser.banner += "-m <suffix>"
|
90
90
|
optsParser.on("-m", "--merge [SUFFIX]", "Merge branch with suffix.") {
|
@@ -93,17 +93,17 @@ module GitMaintain
|
|
93
93
|
optsParser.on("-w", "--watch <PERIOD>", Integer,
|
94
94
|
"Watch and refresh CI status every <PERIOD>.") {
|
95
95
|
|val| opts[:watch] = val}
|
96
|
-
|
97
|
-
|
96
|
+
optsParser.on("--stable", "Check CI status on stable repo.") {
|
97
|
+
opts[:stable] = true }
|
98
98
|
when :pull
|
99
|
-
|
100
|
-
|
99
|
+
optsParser.on("--stable", "List unreleased commits in the upstream stable branch.") {
|
100
|
+
opts[:stable] = true }
|
101
101
|
when :push
|
102
102
|
optsParser.banner += "[-f]"
|
103
103
|
optsParser.on("-f", "--force", "Add --force to git push (for 'push' action).") {
|
104
104
|
opts[:push_force] = true}
|
105
105
|
optsParser.on("--stable", "Push to stable repo.") {
|
106
|
-
|
106
|
+
opts[:stable] = true }
|
107
107
|
optsParser.banner += "[-T]"
|
108
108
|
optsParser.on("-T", "--no-ci", "Ignore CI build status and push anyway.") {
|
109
109
|
opts[:no_ci] = true}
|
@@ -115,16 +115,16 @@ module GitMaintain
|
|
115
115
|
when :steal
|
116
116
|
optsParser.banner += "[-a][-b <HEAD>]"
|
117
117
|
optsParser.on("-a", "--all", "Check all commits from master. "+
|
118
|
-
|
118
|
+
"By default only new commits (since last successful run) are considered.") {
|
119
119
|
|val| opts[:steal_base] = :all}
|
120
120
|
optsParser.on("-b", "--base <HEAD>", "Check all commits from this commit. "+
|
121
|
-
|
121
|
+
"By default only new commits (since last successful run) are considered.") {
|
122
122
|
|val| opts[:steal_base] = val}
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
126
|
def self.check_opts(opts)
|
127
|
-
|
127
|
+
if opts[:action] == :release then
|
128
128
|
if opts[:br_suff] != "master" then
|
129
129
|
raise "Action #{opts[:action]} can only be done on 'master' suffixed branches"
|
130
130
|
end
|
@@ -203,6 +203,8 @@ module GitMaintain
|
|
203
203
|
sleep(opts[:watch])
|
204
204
|
ci.emptyCache()
|
205
205
|
end
|
206
|
+
GitMaintain::log(:INFO, "Done working on selected branches")
|
207
|
+
|
206
208
|
end
|
207
209
|
|
208
210
|
def initialize(repo, version, ci, branch_suff)
|
@@ -224,10 +226,15 @@ module GitMaintain
|
|
224
226
|
@verbose_name = version
|
225
227
|
end
|
226
228
|
|
227
|
-
@head = @repo.
|
229
|
+
@head = @repo.ref_exist?(@local_branch)
|
228
230
|
@valid_ref = "#{@repo.valid_repo}/#{@local_branch}"
|
229
231
|
@remote_ref = "#{@repo.stable_repo}/#{@remote_branch}"
|
230
|
-
@stable_head =
|
232
|
+
@stable_head =
|
233
|
+
begin
|
234
|
+
@repo.ref_exist?(@remote_ref)
|
235
|
+
rescue
|
236
|
+
nil
|
237
|
+
end
|
231
238
|
case @branch_type
|
232
239
|
when :std
|
233
240
|
@stable_base = @repo.findStableBase(@local_branch)
|
@@ -255,9 +262,10 @@ module GitMaintain
|
|
255
262
|
|
256
263
|
# Checkout the repo to the given branch
|
257
264
|
def checkout()
|
258
|
-
|
259
|
-
|
260
|
-
|
265
|
+
begin
|
266
|
+
print @repo.runGit("checkout -q #{@local_branch}")
|
267
|
+
rescue RuntimeError => e
|
268
|
+
crit("Failed to checkout the branch #{@local_branch}")
|
261
269
|
end
|
262
270
|
end
|
263
271
|
|
@@ -266,15 +274,16 @@ module GitMaintain
|
|
266
274
|
opts[:commits].each(){|commit|
|
267
275
|
prev_head=@repo.runGit("rev-parse HEAD")
|
268
276
|
log(:INFO, "Applying #{@repo.getCommitHeadline(commit)}")
|
269
|
-
|
270
|
-
|
277
|
+
begin
|
278
|
+
@repo.runGitInteractive("cherry-pick #{commit}")
|
279
|
+
rescue RuntimeError
|
271
280
|
log(:WARNING, "Cherry pick failure. Starting bash for manual fixes. Exit shell to continue")
|
272
|
-
|
273
|
-
|
281
|
+
@repo.runBash("PS1_WARNING='CP FIX'")
|
282
|
+
end
|
274
283
|
new_head=@repo.runGit("rev-parse HEAD")
|
275
284
|
# Do not make commit pretty if it was not applied
|
276
285
|
if new_head != prev_head
|
277
|
-
|
286
|
+
make_pretty(commit)
|
278
287
|
end
|
279
288
|
}
|
280
289
|
end
|
@@ -286,22 +295,26 @@ module GitMaintain
|
|
286
295
|
# If we are not force checking everything,
|
287
296
|
# try to start from the last tag we steal upto
|
288
297
|
case opts[:steal_base]
|
289
|
-
|
298
|
+
when nil
|
299
|
+
begin
|
290
300
|
sha = @repo.runGit("rev-parse 'git-maintain/steal/last/#{@stable_base}' 2>&1")
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
301
|
+
base_ref=sha
|
302
|
+
log(:VERBOSE, "Starting from last successfull run:")
|
303
|
+
log(:VERBOSE, @repo.getCommitHeadline(base_ref))
|
304
|
+
rescue RuntimeError
|
305
|
+
# No matching tag found. Not an issue
|
306
|
+
end
|
307
|
+
when :all
|
308
|
+
base_ref=@stable_base
|
309
|
+
else
|
310
|
+
begin
|
299
311
|
sha = @repo.runGit("rev-parse #{opts[:steal_base]} 2>&1")
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
312
|
+
base_ref=sha
|
313
|
+
log(:VERBOSE, "Starting from base:")
|
314
|
+
log(:VERBOSE, @repo.getCommitHeadline(base_ref))
|
315
|
+
rescue RuntimeError
|
316
|
+
crit("Could not find specified base '#{opts[:steal_base]}'")
|
317
|
+
end
|
305
318
|
end
|
306
319
|
|
307
320
|
master_sha=@repo.runGit("rev-parse origin/master")
|
@@ -333,8 +346,9 @@ module GitMaintain
|
|
333
346
|
merge_branch = @repo.versionToLocalBranch(@version, opts[:do_merge])
|
334
347
|
|
335
348
|
# Make sure branch exists
|
336
|
-
|
337
|
-
|
349
|
+
begin
|
350
|
+
hash_to_merge = @repo.ref_exist?(merge_branch)
|
351
|
+
rescue NoRefError
|
338
352
|
log(:INFO, "Branch #{merge_branch} does not exists. Skipping...")
|
339
353
|
return
|
340
354
|
end
|
@@ -348,11 +362,12 @@ module GitMaintain
|
|
348
362
|
|
349
363
|
rep = GitMaintain::checkLog(opts, merge_branch, @local_branch, "merge")
|
350
364
|
if rep == "y" then
|
351
|
-
|
352
|
-
|
365
|
+
begin
|
366
|
+
@repo.runGitInteractive("merge #{merge_branch}")
|
367
|
+
rescue RuntimeError
|
353
368
|
log(:WARNING, "Merge failure. Starting bash for manual fixes. Exit shell to continue")
|
354
|
-
|
355
|
-
|
369
|
+
@repo.runBash("PS1_WARNING='MERGING'")
|
370
|
+
end
|
356
371
|
else
|
357
372
|
log(:INFO, "Skipping merge")
|
358
373
|
return
|
@@ -363,8 +378,9 @@ module GitMaintain
|
|
363
378
|
remoteRef = opts[:stable] == true ? @remote_ref : @valid_ref
|
364
379
|
|
365
380
|
# Make sure branch exists
|
366
|
-
|
367
|
-
|
381
|
+
begin
|
382
|
+
@repo.ref_exist?(remoteRef)
|
383
|
+
rescue NoRefError
|
368
384
|
log(:INFO, "Branch #{remoteRef} does not exists. Skipping...")
|
369
385
|
return
|
370
386
|
end
|
@@ -485,8 +501,9 @@ module GitMaintain
|
|
485
501
|
|
486
502
|
def delete(opts)
|
487
503
|
if opts[:delete_remote] == true then
|
488
|
-
|
489
|
-
|
504
|
+
begin
|
505
|
+
@repo.ref_exist?("#{@repo.valid_repo}/#{@local_branch}")
|
506
|
+
rescue NoRefError
|
490
507
|
log(:DEBUG, "Skipping non existing remote branch #{@local_branch}.")
|
491
508
|
return
|
492
509
|
end
|
@@ -522,13 +539,16 @@ module GitMaintain
|
|
522
539
|
|
523
540
|
private
|
524
541
|
def add_blacklist(commit)
|
525
|
-
|
542
|
+
@repo.runGit("notes append -m \"#{@local_branch}\" #{commit}")
|
526
543
|
end
|
527
544
|
|
528
545
|
def is_blacklisted?(commit)
|
529
|
-
|
530
|
-
|
531
|
-
|
546
|
+
begin
|
547
|
+
@repo.runGit("notes show #{commit} 2> /dev/null").split("\n").each(){|br|
|
548
|
+
return true if br == @local_branch
|
549
|
+
}
|
550
|
+
rescue
|
551
|
+
end
|
532
552
|
return false
|
533
553
|
end
|
534
554
|
|
@@ -538,113 +558,115 @@ module GitMaintain
|
|
538
558
|
|
539
559
|
msg_path=`mktemp`.chomp()
|
540
560
|
msg_file = File.open(msg_path, "w+")
|
541
|
-
|
561
|
+
msg_file.puts @repo.runGit("log -1 --format=\"%s%n%n[ Upstream commit #{msg_commit} ]%n%n%b\" #{orig_commit}")
|
542
562
|
msg_file.close()
|
543
|
-
|
563
|
+
@repo.runGit("commit -s --amend -F #{msg_path}")
|
544
564
|
`rm -f #{msg_path}`
|
545
565
|
end
|
546
566
|
|
547
567
|
def is_in_tree?(commit, src_commit=commit)
|
548
|
-
|
568
|
+
fullhash=nil
|
569
|
+
begin
|
570
|
+
fullhash=@repo.ref_exist?(commit)
|
571
|
+
rescue NoRefError
|
549
572
|
# This might happen if someone pointed to a commit that doesn't exist in our
|
550
573
|
# tree.
|
551
|
-
if $? != 0 then
|
552
574
|
log(:WARNING, "Commit #{src_commit} points to a SHA #{commit} not in tree")
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
# Try and find if there's a commit with given subject the hard way
|
569
|
-
@repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj.gsub("\"", '\\"')}\" "+
|
575
|
+
return false
|
576
|
+
end
|
577
|
+
|
578
|
+
# Hope for the best, same commit is/isn't in the current branch
|
579
|
+
if @repo.runGit("merge-base #{fullhash} HEAD") == fullhash then
|
580
|
+
return true
|
581
|
+
end
|
582
|
+
|
583
|
+
# Grab the subject, since commit sha1 is different between branches we
|
584
|
+
# have to look it up based on subject.
|
585
|
+
subj=@repo.getCommitSubj(commit)
|
586
|
+
|
587
|
+
# Try and find if there's a commit with given subject the hard way
|
588
|
+
@repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj.gsub("\"", '\\"')}\" "+
|
570
589
|
"#{@stable_base}..HEAD").split("\n").each(){|cmt|
|
571
590
|
cursubj=@repo.runGit("log -1 --format=\"%s\" #{cmt}")
|
572
591
|
if cursubj = subj then
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
592
|
+
return true
|
593
|
+
end
|
594
|
+
}
|
595
|
+
return false
|
577
596
|
end
|
578
597
|
|
579
598
|
def is_relevant?(commit)
|
580
|
-
|
581
|
-
|
599
|
+
# Let's grab the commit that this commit fixes (if exists (based on the "Fixes:" tag)).
|
600
|
+
fixescmt=@repo.runGit("log -1 #{commit} | grep -i \"fixes:\" | head -n 1 | "+
|
582
601
|
"sed -e 's/^[ \\t]*//' | cut -f 2 -d ':' | "+
|
583
602
|
"sed -e 's/^[ \\t]*//' -e 's/\\([0-9a-f]\\+\\)(/\\1 (/' | cut -f 1 -d ' '")
|
584
603
|
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
604
|
+
# If this commit fixes anything, but the broken commit isn't in our branch we don't
|
605
|
+
# need this commit either.
|
606
|
+
if fixescmt != "" then
|
607
|
+
if is_in_tree?(fixescmt, commit) then
|
608
|
+
return true
|
609
|
+
else
|
610
|
+
return false
|
611
|
+
end
|
593
612
|
end
|
594
613
|
|
595
|
-
|
596
|
-
|
597
|
-
|
614
|
+
if @repo.runGit("show #{commit} | grep -i 'stable@' | wc -l") == "0" then
|
615
|
+
return false
|
616
|
+
end
|
598
617
|
|
599
|
-
|
600
|
-
|
618
|
+
# Let's see if there's a version tag in this commit
|
619
|
+
full=@repo.runGit("show #{commit} | grep -i 'stable@'").gsub(/.* #?/, "")
|
601
620
|
|
602
|
-
|
621
|
+
# Sanity check our extraction
|
603
622
|
if full =~ /stable/ then
|
604
623
|
return false
|
605
624
|
end
|
606
625
|
|
607
626
|
full = @repo.runGit("rev-parse #{full}^{commit}")
|
608
627
|
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
628
|
+
# Make sure our branch contains this version
|
629
|
+
if @repo.runGit("merge-base #{@head} #{full}") == full then
|
630
|
+
return true
|
631
|
+
end
|
613
632
|
|
614
|
-
|
615
|
-
|
633
|
+
# Tag is not in history, ignore
|
634
|
+
return false
|
616
635
|
end
|
617
636
|
|
618
637
|
def pick_one(commit)
|
619
|
-
|
620
|
-
|
638
|
+
cpCmd="cherry-pick --strategy=recursive -Xpatience -x"
|
639
|
+
@repo.runGitInteractive("#{cpCmd} #{commit} &> /dev/null", :check_err => false)
|
640
|
+
return if $? == 0
|
641
|
+
|
621
642
|
if @repo.runGit("status -uno --porcelain | wc -l") == "0" then
|
622
|
-
|
643
|
+
@repo.runGit("reset --hard")
|
623
644
|
raise CherryPickErrorException.new("Failed to cherry pick commit #{commit}", commit)
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
645
|
+
end
|
646
|
+
@repo.runGit("reset --hard")
|
647
|
+
|
648
|
+
# That didn't work? Let's try that with every variation of the commit
|
649
|
+
# in other stable trees.
|
628
650
|
@repo.find_alts(commit).each(){|alt_commit|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
651
|
+
@repo.runGitInteractive("#{cpCmd} #{alt_commit} &> /dev/null", :check_err => false)
|
652
|
+
if $? == 0 then
|
653
|
+
return
|
654
|
+
end
|
655
|
+
@repo.runGit("reset --hard")
|
634
656
|
}
|
635
|
-
|
636
|
-
|
637
|
-
|
657
|
+
|
658
|
+
# Still no? Let's go back to the original commit and hand it off to
|
659
|
+
# the user.
|
660
|
+
@repo.runGitInteractive("#{cpCmd} #{commit} &> /dev/null", :check_err => false)
|
638
661
|
raise CherryPickErrorException.new("Failed to cherry pick commit #{commit}", commit)
|
639
|
-
return false
|
640
662
|
end
|
641
663
|
|
642
664
|
def confirm_one(opts, commit)
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
665
|
+
rep=""
|
666
|
+
do_cp=false
|
667
|
+
puts @repo.getCommitHeadline(commit)
|
668
|
+
while rep != "y" do
|
669
|
+
puts "Do you want to steal this commit ? (y/n/b/?)"
|
648
670
|
case opts[:yn_default]
|
649
671
|
when :no
|
650
672
|
log(:INFO, "Auto-replying no due to --no option")
|
@@ -657,38 +679,38 @@ module GitMaintain
|
|
657
679
|
rep = STDIN.gets.chomp()
|
658
680
|
end
|
659
681
|
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
682
|
+
case rep
|
683
|
+
when "n"
|
684
|
+
log(:INFO, "Skip this commit")
|
685
|
+
break
|
686
|
+
when "b"
|
687
|
+
log(:INFO, "Blacklisting this commit for the current branch")
|
688
|
+
add_blacklist(commit)
|
689
|
+
break
|
690
|
+
when "y"
|
691
|
+
rep="y"
|
692
|
+
do_cp=true
|
693
|
+
break
|
694
|
+
when "?"
|
695
|
+
puts @repo.runGit("show #{commit}")
|
674
696
|
else
|
675
|
-
|
676
|
-
|
697
|
+
log(:ERROR, "Invalid answer $rep")
|
698
|
+
puts @repo.runGit("show --format=oneline --no-patch --no-decorate #{commit}")
|
677
699
|
end
|
678
|
-
|
700
|
+
end
|
679
701
|
return do_cp
|
680
702
|
end
|
681
703
|
|
682
704
|
def steal_one(opts, commit, mainline=false)
|
683
|
-
|
705
|
+
msg=''
|
684
706
|
orig_cmt=commit
|
685
707
|
|
686
708
|
if mainline == false then
|
687
|
-
|
709
|
+
subj=@repo.getCommitSubj(commit)
|
688
710
|
subj.gsub!(/"/, '\"')
|
689
|
-
|
690
|
-
|
691
|
-
|
711
|
+
# Let's grab the mainline commit id, this is useful if the version tag
|
712
|
+
# doesn't exist in the commit we're looking at but exists upstream.
|
713
|
+
orig_cmt=@repo.runGit("log --no-merges --format=\"%H\" -F --grep \"#{subj}\" " +
|
692
714
|
"#{@stable_base}..origin/master | tail -n1")
|
693
715
|
|
694
716
|
if orig_cmt == "" then
|
@@ -696,24 +718,24 @@ module GitMaintain
|
|
696
718
|
end
|
697
719
|
end
|
698
720
|
# If the commit doesn't apply for us, skip it
|
699
|
-
|
721
|
+
if is_relevant?(orig_cmt) != true
|
700
722
|
return true
|
701
|
-
|
723
|
+
end
|
702
724
|
|
703
725
|
log(:VERBOSE, "Found relevant commit #{@repo.getCommitHeadline(commit)}")
|
704
|
-
|
705
|
-
|
726
|
+
if is_in_tree?(orig_cmt) == true
|
727
|
+
# Commit is already in the stable branch, skip
|
706
728
|
log(:VERBOSE, "Commit is already in tree")
|
707
729
|
return true
|
708
|
-
|
730
|
+
end
|
709
731
|
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
732
|
+
# Check if it's not blacklisted by a git-notes
|
733
|
+
if is_blacklisted?(orig_cmt) == true then
|
734
|
+
# Commit is blacklisted
|
735
|
+
log(:INFO, "Skipping 'blacklisted' commit " +
|
736
|
+
@repo.getCommitHeadline(orig_cmt))
|
715
737
|
return true
|
716
|
-
|
738
|
+
end
|
717
739
|
|
718
740
|
do_cp = confirm_one(opts, orig_cmt)
|
719
741
|
return false if do_cp != true
|
@@ -721,39 +743,83 @@ module GitMaintain
|
|
721
743
|
prev_head=@repo.runGit("rev-parse HEAD")
|
722
744
|
|
723
745
|
begin
|
724
|
-
|
746
|
+
pick_one(commit)
|
725
747
|
rescue CherryPickErrorException => e
|
726
|
-
|
727
|
-
|
748
|
+
log(:WARNING, "Cherry pick failed. Fix, commit (or reset) and exit.")
|
749
|
+
@repo.runBash("PS1_WARNING='CP FIX'")
|
728
750
|
end
|
729
751
|
new_head=@repo.runGit("rev-parse HEAD")
|
730
752
|
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
753
|
+
# If we didn't find the commit upstream then this must be a custom commit
|
754
|
+
# in the given tree - make sure the user checks this commit.
|
755
|
+
if orig_cmt == "" then
|
756
|
+
msg="Custom"
|
757
|
+
orig_cmt=@repo.runGit("rev-parse HEAD")
|
758
|
+
log(:WARNING, "Custom commit, please double-check!")
|
759
|
+
@repo.runBash("PS1_WARNING='CHECK'")
|
760
|
+
end
|
739
761
|
if new_head != prev_head
|
740
|
-
|
762
|
+
make_pretty(orig_cmt, msg)
|
741
763
|
end
|
742
764
|
end
|
743
765
|
|
744
766
|
def steal_all(opts, range, mainline = false)
|
745
767
|
res = true
|
746
|
-
|
768
|
+
@repo.runGit("log --no-merges --format=\"%H\" #{range} | tac").split("\n").each(){|commit|
|
747
769
|
res &= steal_one(opts, commit, mainline)
|
748
770
|
}
|
749
771
|
return res
|
750
|
-
|
772
|
+
end
|
751
773
|
|
752
774
|
def same_sha?(ref1, ref2)
|
753
|
-
|
754
|
-
|
755
|
-
|
775
|
+
begin
|
776
|
+
c1=@repo.ref_exist?(ref1)
|
777
|
+
c2=@repo.ref_exist?(ref2)
|
778
|
+
return c1 == c2
|
779
|
+
rescue
|
780
|
+
return false
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
784
|
+
|
785
|
+
def release_do_add_commit(opts, filelist, commit_path, commit_msg=nil)
|
786
|
+
edit_flag = ""
|
787
|
+
edit_flag = "--edit" if opts[:no_edit] == false
|
756
788
|
|
789
|
+
raise("No commit message provided") if commit_path == nil && commit_msg == nil
|
790
|
+
commit_flag=""
|
791
|
+
if commit_msg != nil
|
792
|
+
commit_flag = "-m '#{commit_msg}'"
|
793
|
+
else
|
794
|
+
commit_flag = "-F '#{commit_path}'"
|
795
|
+
end
|
796
|
+
|
797
|
+
# Add and commit
|
798
|
+
begin
|
799
|
+
@repo.runGit("add " + filelist.join(" "))
|
800
|
+
@repo.runGitInteractive("commit #{commit_flag} --verbose #{edit_flag} --signoff")
|
801
|
+
rescue RuntimeError
|
802
|
+
raise("Failed to commit on branch #{@local_branch}")
|
803
|
+
end
|
804
|
+
return 0
|
805
|
+
end
|
806
|
+
|
807
|
+
def release_do_tag(opts, version, tag_path)
|
808
|
+
edit_flag = ""
|
809
|
+
edit_flag = "--edit" if opts[:no_edit] == false
|
810
|
+
begin
|
811
|
+
@repo.runGitInteractive("tag -a -s #{version} #{edit_flag} -F #{tag_path}")
|
812
|
+
rescue RuntimeError
|
813
|
+
raise("Failed to tag branch #{@local_branch}")
|
814
|
+
end
|
815
|
+
return 0
|
757
816
|
end
|
817
|
+
|
818
|
+
def release_do_add_commit_tag(opts, filelist, version, message_path)
|
819
|
+
release_do_add_commit(opts, filelist, message_path)
|
820
|
+
release_do_tag(opts, version, message_path)
|
821
|
+
return 0
|
822
|
+
end
|
823
|
+
|
758
824
|
end
|
759
825
|
end
|
data/lib/common.rb
CHANGED
@@ -223,6 +223,12 @@ module GitMaintain
|
|
223
223
|
end
|
224
224
|
module_function :log
|
225
225
|
|
226
|
+
def crit(msg)
|
227
|
+
log(:ERROR, msg)
|
228
|
+
raise msg
|
229
|
+
end
|
230
|
+
module_function :crit
|
231
|
+
|
226
232
|
def setVerbose(val)
|
227
233
|
@@verbose_log = val
|
228
234
|
end
|
@@ -241,7 +247,7 @@ $LOAD_PATH.pop()
|
|
241
247
|
|
242
248
|
if ENV["GIT_MAINTAIN_ADDON_DIR"].to_s() != "" then
|
243
249
|
ADDON_DIR=ENV["GIT_MAINTAIN_ADDON_DIR"].to_s()
|
244
|
-
if Dir.
|
250
|
+
if Dir.exist?(ADDON_DIR) then
|
245
251
|
$LOAD_PATH.push(ADDON_DIR)
|
246
252
|
Dir.entries(ADDON_DIR).each(){|entry|
|
247
253
|
next if (!File.file?(ADDON_DIR + "/" + entry) || entry !~ /\.rb$/ );
|
data/lib/repo.rb
CHANGED
@@ -2,6 +2,11 @@ require 'octokit'
|
|
2
2
|
require 'io/console'
|
3
3
|
|
4
4
|
module GitMaintain
|
5
|
+
class NoRefError < RuntimeError
|
6
|
+
def initialize(ref)
|
7
|
+
super("Reference '#{ref}' was not found")
|
8
|
+
end
|
9
|
+
end
|
5
10
|
class Repo
|
6
11
|
@@VALID_REPO = "github"
|
7
12
|
@@STABLE_REPO = "stable"
|
@@ -19,7 +24,7 @@ module GitMaintain
|
|
19
24
|
}
|
20
25
|
|
21
26
|
def self.load(path=".")
|
22
|
-
dir =
|
27
|
+
dir = File.realdirpath(path)
|
23
28
|
repo_name = File.basename(dir)
|
24
29
|
return GitMaintain::loadClass(Repo, repo_name, dir)
|
25
30
|
end
|
@@ -60,9 +65,9 @@ module GitMaintain
|
|
60
65
|
@stable_repo = getGitConfig("maintain.stable-repo")
|
61
66
|
@stable_repo = @@STABLE_REPO if @stable_repo == ""
|
62
67
|
|
63
|
-
@remote_valid=runGit("remote -v |
|
68
|
+
@remote_valid=runGit("remote -v | grep -E '^#{@valid_repo}' | grep fetch |
|
64
69
|
awk '{ print $2}' | sed -e 's/.*://' -e 's/\\.git//'")
|
65
|
-
@remote_stable=runGit("remote -v |
|
70
|
+
@remote_stable=runGit("remote -v | grep -E '^#{@stable_repo}' | grep fetch |
|
66
71
|
awk '{ print $2}' | sed -e 's/.*://' -e 's/\\.git//'")
|
67
72
|
|
68
73
|
@auto_fetch = getGitConfig("maintain.autofetch")
|
@@ -83,7 +88,7 @@ module GitMaintain
|
|
83
88
|
@stable_base_format = getGitConfig("maintain.stable-base-format")
|
84
89
|
|
85
90
|
@stable_base_patterns=
|
86
|
-
runGit("config --get-regexp stable-base |
|
91
|
+
runGit("config --get-regexp stable-base | grep -E '^stable-base\.' | "+
|
87
92
|
"sed -e 's/stable-base\.//' -e 's/---/\\//g'").split("\n").inject({}){ |m, x|
|
88
93
|
y=x.split(" ");
|
89
94
|
m[y[0]] = y[1]
|
@@ -110,22 +115,41 @@ module GitMaintain
|
|
110
115
|
GitMaintain::log(lvl, str)
|
111
116
|
end
|
112
117
|
|
113
|
-
def
|
114
|
-
|
118
|
+
def _run_check_ret(ret, opts)
|
119
|
+
raise(RuntimeError.new(ret)) if $?.exitstatus != 0 && opts.fetch(:check_err, true) == true
|
115
120
|
end
|
116
|
-
def
|
117
|
-
|
121
|
+
def run(cmd, opts = {})
|
122
|
+
ret = `cd #{@path} && #{cmd}`
|
123
|
+
_run_check_ret(ret, opts)
|
124
|
+
return ret
|
118
125
|
end
|
126
|
+
def runSystem(cmd, opts = {})
|
127
|
+
ret = system("cd #{@path} && #{cmd}")
|
128
|
+
_run_check_ret(nil, opts)
|
129
|
+
return ret
|
119
130
|
|
120
|
-
|
131
|
+
end
|
132
|
+
def runGit(cmd, opts = {})
|
121
133
|
log(:DEBUG, "Called from #{caller[1]}")
|
122
134
|
log(:DEBUG, "Running git command '#{cmd}'")
|
123
|
-
|
135
|
+
ret = `git --work-tree=#{@path} #{cmd}`.chomp()
|
136
|
+
_run_check_ret(ret, opts)
|
137
|
+
return ret
|
124
138
|
end
|
125
|
-
def runGitInteractive(cmd)
|
139
|
+
def runGitInteractive(cmd, opts = {})
|
126
140
|
log(:DEBUG, "Called from #{caller[1]}")
|
127
141
|
log(:DEBUG, "Running interactive git command '#{cmd}'")
|
128
|
-
|
142
|
+
ret = system("git --work-tree=#{@path} #{cmd}")
|
143
|
+
_run_check_ret(nil, opts)
|
144
|
+
return ret
|
145
|
+
|
146
|
+
end
|
147
|
+
def ref_exist?(ref)
|
148
|
+
begin
|
149
|
+
return runGit("rev-parse --verify --quiet '#{ref}'")
|
150
|
+
rescue RuntimeError
|
151
|
+
raise(NoRefError.new(ref))
|
152
|
+
end
|
129
153
|
end
|
130
154
|
|
131
155
|
def runGitImap(cmd)
|
@@ -138,17 +162,18 @@ module GitMaintain
|
|
138
162
|
fi; git --work-tree=#{@path} imap-send #{cmd}`
|
139
163
|
end
|
140
164
|
def getGitConfig(entry)
|
141
|
-
return @config_cache[entry] ||= runGit("config #{entry} 2> /dev/null").chomp()
|
165
|
+
return @config_cache[entry] ||= runGit("config #{entry} 2> /dev/null", :check_err => false).chomp()
|
142
166
|
end
|
143
167
|
|
144
168
|
def runBash(env="")
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
else
|
169
|
+
begin
|
170
|
+
runSystem(env + " bash")
|
171
|
+
rescue RuntimeError
|
149
172
|
log(:ERROR, "Shell exited with code #{$?}. Exiting")
|
150
173
|
raise("Cancelled by user")
|
151
174
|
end
|
175
|
+
log(:INFO, "Continuing...")
|
176
|
+
|
152
177
|
end
|
153
178
|
|
154
179
|
def getCommitHeadline(sha)
|
@@ -200,10 +225,10 @@ module GitMaintain
|
|
200
225
|
|
201
226
|
def getUnreleasedTags(opts)
|
202
227
|
remote_tags=runGit("ls-remote --tags #{@stable_repo} |
|
203
|
-
|
228
|
+
grep -E 'refs/tags/v[0-9.]*$'").split("\n").map(){
|
204
229
|
|x| x.gsub(/.*refs\/tags\//, '')
|
205
230
|
}
|
206
|
-
local_tags =runGit("tag -l |
|
231
|
+
local_tags =runGit("tag -l | grep -E '^v[0-9.]*$'").split("\n")
|
207
232
|
|
208
233
|
new_tags = local_tags - remote_tags
|
209
234
|
return new_tags
|
@@ -264,22 +289,22 @@ module GitMaintain
|
|
264
289
|
|
265
290
|
def createRelease(opts, tag, github_rel=true)
|
266
291
|
log(:INFO, "Creating a release for #{tag}")
|
267
|
-
|
292
|
+
runGit("push #{@stable_repo} refs/tags/#{tag}")
|
268
293
|
|
269
294
|
if github_rel == true then
|
270
|
-
|
295
|
+
msg = runGit("tag -l -n1000 '#{tag}'") + "\n"
|
271
296
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
297
|
+
# Ye ghods is is a horrific format to parse
|
298
|
+
name, body = msg.split("\n", 2)
|
299
|
+
name = name.gsub(/^#{tag}/, '').strip
|
300
|
+
body = body.split("\n").map { |l| l.sub(/^ /, '') }.join("\n")
|
301
|
+
api.create_release(@remote_stable, tag, :name => name, :body => body)
|
277
302
|
end
|
278
|
-
|
303
|
+
end
|
279
304
|
|
280
305
|
def versionToLocalBranch(version, suff)
|
281
306
|
return @branch_format_raw.gsub(/\\\//, '/').
|
282
|
-
|
307
|
+
gsub(/\(.*\)/, version) + "/#{suff}"
|
283
308
|
end
|
284
309
|
|
285
310
|
def versionToStableBranch(version)
|
@@ -333,59 +358,65 @@ module GitMaintain
|
|
333
358
|
submitReleases(opts, new_tags)
|
334
359
|
end
|
335
360
|
def summary(opts)
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
361
|
+
log(:INFO, "Configuration summary:")
|
362
|
+
if self.class != GitMaintain::Repo then
|
363
|
+
log(:INFO, "Using custom repo class: #{self.class.to_s()}")
|
364
|
+
end
|
365
|
+
log(:INFO, "Stable remote: #{@stable_repo}")
|
366
|
+
log(:INFO, "Validation remote: #{@valid_repo}")
|
367
|
+
log(:INFO, "")
|
368
|
+
log(:INFO, "Branch config:")
|
369
|
+
log(:INFO, "Local branch format: /#{@branch_format_raw}/")
|
370
|
+
log(:INFO, "Remote stable branch format: #{@stable_branch_format}")
|
371
|
+
log(:INFO, "Remote stable base format: #{@stable_base_format}")
|
372
|
+
|
373
|
+
if @stable_base_patterns.length > 0 then
|
374
|
+
log(:INFO, "")
|
375
|
+
log(:INFO, "Stable base rules:")
|
376
|
+
@stable_base_patterns.each(){|name, base|
|
377
|
+
log(:INFO, "\t#{name} -> #{base}")
|
378
|
+
}
|
379
|
+
end
|
380
|
+
brList = getBranchList(opts[:br_suff])
|
381
|
+
brStList = getStableBranchList()
|
382
|
+
|
383
|
+
if brList.length > 0 then
|
384
|
+
log(:INFO, "")
|
385
|
+
log(:INFO, "Local branches:")
|
386
|
+
brList.each(){|br|
|
387
|
+
branch = Branch.load(self, br, nil, opts[:br_suff])
|
388
|
+
localBr = branch.local_branch
|
389
|
+
stableBr = @@STABLE_REPO + "/" + branch.remote_branch
|
390
|
+
stableBase = branch.stable_base
|
391
|
+
begin
|
392
|
+
ref_exist?(stableBr)
|
393
|
+
rescue NoRefError
|
394
|
+
stableBr = "<MISSING>"
|
395
|
+
end
|
396
|
+
log(:INFO, "\t#{localBr} -> #{stableBr} (#{stableBase})")
|
397
|
+
brStList.delete(br)
|
398
|
+
}
|
399
|
+
end
|
400
|
+
|
401
|
+
if brStList.length > 0 then
|
402
|
+
log(:INFO, "")
|
403
|
+
log(:INFO, "Upstream branches:")
|
404
|
+
brStList.each(){|br|
|
405
|
+
branch = Branch.load(self, br, nil, opts[:branch_suff])
|
406
|
+
stableBr = @@STABLE_REPO + "/" + branch.remote_branch
|
407
|
+
stableBase = branch.stable_base
|
408
|
+
log(:INFO, "\t<MISSING> -> #{stableBr} (#{stableBase})")
|
409
|
+
}
|
410
|
+
end
|
411
|
+
end
|
384
412
|
def find_alts(commit)
|
385
413
|
alts=[]
|
386
414
|
|
387
|
-
|
388
|
-
|
415
|
+
begin
|
416
|
+
subj=runGit("log -1 --pretty='%s' #{commit}")
|
417
|
+
rescue RuntimeError
|
418
|
+
return []
|
419
|
+
end
|
389
420
|
|
390
421
|
branches = getStableBranchList().map(){|v| @@STABLE_REPO + "/" + versionToStableBranch(v)}
|
391
422
|
|
@@ -402,46 +433,46 @@ module GitMaintain
|
|
402
433
|
#
|
403
434
|
# Github API stuff
|
404
435
|
#
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
436
|
+
def api
|
437
|
+
@api ||= Octokit::Client.new(:access_token => token, :auto_paginate => true)
|
438
|
+
end
|
439
|
+
|
440
|
+
def token
|
441
|
+
@token ||= begin
|
442
|
+
# We cannot use the 'defaults' functionality of git_config here,
|
443
|
+
# because get_new_token would be evaluated before git_config ran
|
444
|
+
tok = getGitConfig("maintain.api-token")
|
414
445
|
tok.to_s() == "" ? get_new_token : tok
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
446
|
+
end
|
447
|
+
end
|
448
|
+
def get_new_token
|
449
|
+
puts "Requesting a new OAuth token from Github..."
|
450
|
+
print "Github username: "
|
451
|
+
user = $stdin.gets.chomp
|
452
|
+
print "Github password: "
|
453
|
+
pass = $stdin.noecho(&:gets).chomp
|
454
|
+
puts
|
455
|
+
|
456
|
+
api = Octokit::Client.new(:login => user, :password => pass)
|
457
|
+
|
458
|
+
begin
|
459
|
+
res = api.create_authorization(:scopes => [:repo], :note => "git-maintain")
|
460
|
+
rescue Octokit::Unauthorized
|
461
|
+
puts "Username or password incorrect. Please try again."
|
462
|
+
return get_new_token
|
432
463
|
rescue Octokit::OneTimePasswordRequired
|
433
|
-
|
434
|
-
|
435
|
-
|
464
|
+
print "Github OTP: "
|
465
|
+
otp = $stdin.noecho(&:gets).chomp
|
466
|
+
res = api.create_authorization(:scopes => [:repo], :note => "git-maintain",
|
436
467
|
:headers => {"X-GitHub-OTP" => otp})
|
437
|
-
|
468
|
+
end
|
438
469
|
|
439
|
-
|
440
|
-
|
470
|
+
token = res[:token]
|
471
|
+
runGit("config --global maintain.api-token '#{token}'")
|
441
472
|
|
442
473
|
# Now reopen with the token so OTP does not bother us
|
443
474
|
@api=nil
|
444
475
|
token
|
445
|
-
|
446
|
-
|
476
|
+
end
|
477
|
+
end
|
447
478
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-maintain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Morey-Chaisemartin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|