git-maintain 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ccbf8e5307eaae5365b48a6ce99f026f020fa18acd0f34542cf8f4d8ecfbb51
4
- data.tar.gz: de7a34ab07001688472118280ed5db9bed9016148a50f5009af2e9da5f16722e
3
+ metadata.gz: 417458e3750d9bcd3c32ec5ee53927fbfea2cd699673f72d50ec31a9cc1bb432
4
+ data.tar.gz: f95702ebdc24c0978b29627cfde6742fcf9ffe817d26609e895c12001cdc194c
5
5
  SHA512:
6
- metadata.gz: 8ed529842a7c85ca7e13e969fe561edc671ddc5ef20a559484523a7b0643e01236205b7b9681eff7d123024771ea6037ceaa79cba388032dc2971dbf2938aa58
7
- data.tar.gz: 2bb5406a3a5d028a7dbde47a2ccdf6ae4b69e4b1ab379e428069af14088dce6a5289e0fe74eccf32e45f9927a94bde7143f86efb172d05c464092852f7edec12
6
+ metadata.gz: 7682468b42e62b9513ae9227bef2af4e1e01e9078a1c46648382efaa895f2152e5bbe18488e1c2e45b0fad524be09d77e953bfb48f6f49e2a34cd72e2590d0f4
7
+ data.tar.gz: 954f1f014760fa1c02b1ebead5f093115da8dada78bfea1d041d527a41d37727aad9ba06f0d94e4d926c2fb725da4dc2c61cd4b5cbafe2093c8510d2d54e820a
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ ------------------
2
+ 0.7.0 (2019-05-29)
3
+ ------------------
4
+
5
+ * Add summary command
6
+ * push and push_stable now push all the selected branch at once
7
+ * Add maintain.autofetch setting in gitconfig to enable/disable autofetch
8
+ * Support 'errored' status in travis
9
+ * Fix 'steal' command for commits containing double quotes
10
+ * Fixes for rdma-core release procedure
11
+ * Support send-email for release annoucenement
12
+ * Fix support for interactive editor (ie vim)
13
+ * Support repo specific action options
14
+
1
15
  ------------------
2
16
  0.6.0 (2019-03-21)
3
17
  ------------------
data/README.md CHANGED
@@ -30,10 +30,10 @@ The idea is to script most of the maintenance tasks so the maintainer can focus
30
30
  - Load git-maintain-completion.sh for shell completion
31
31
 
32
32
  ## Remote setup
33
- - the 'github' remote should be your own WIP github to test out branches before submitting to the official repo.
33
+ - the 'github' remote should be your own WIP github to test out branches before submitting to the official repo.
34
34
  Also know as the 'Validation' repo. It can be switched to another remote by setting maintain.valid-repo=xxx in your gitconfig
35
35
  - the 'origin' remote should be the official repo in read-only mode to avoid any accidental pushes
36
- - the 'stable' remote should be the official repo in RW mode
36
+ - the 'stable' remote should be the official repo in RW mode.
37
37
  Also know as the 'Stable' repo. It can be switched to another remote by setting maintain.stable-repo=xxx in your gitconfig
38
38
 
39
39
  ## Stealing commits
@@ -41,10 +41,10 @@ The idea is to script most of the maintenance tasks so the maintainer can focus
41
41
  The steal feature uses was shamelessly copied it from https://git.kernel.org/pub/scm/linux/kernel/git/sashal/stable-tools.git/tree/
42
42
 
43
43
  ## Making releases
44
- The release process being very specific to each project, the release command does nothing by default.
44
+ The release process being very specific to each project, the release command does nothing by default.
45
45
  However the behaviour can be overriden for specific repo (detected by repo name)
46
46
 
47
- Check the lib/addons/RDMACore.rb for an example.
47
+ Check the lib/addons/RDMACore.rb for an example.
48
48
  In this case, the release command bump the version in all the appropriate files (after computing the previous and next version numbers), commit and tags the commit.
49
49
 
50
50
 
@@ -119,9 +119,36 @@ v\1
119
119
 
120
120
  Note that this value can be overriden by the stable-base.XXX value if needed
121
121
 
122
+ To verify your setup, you can run 'git maintain summary' which will show you your configured values and the matching local and upstrema branches that git-maintain sees
123
+ ```
124
+ $ git maintain summary
125
+ # INFO: Configuration summary:
126
+ # INFO: Stable remote: stable
127
+ # INFO: Validation remote: github
128
+ # INFO:
129
+ # INFO: Branch config:
130
+ # INFO: Local branch format: /dev\/stable-v([0-9]*)/
131
+ # INFO: Remote stable branch format: stable-v\1
132
+ # INFO: Remote stable base format: v\1
133
+ # INFO:
134
+ # INFO: Local branches:
135
+ # INFO: dev/stable-v15/master -> stable/stable-v15
136
+ # INFO: dev/stable-v16/master -> stable/stable-v16
137
+ # INFO: dev/stable-v17/master -> stable/stable-v17
138
+ # INFO: dev/stable-v18/master -> stable/stable-v18
139
+ # INFO: dev/stable-v19/master -> stable/stable-v19
140
+ # INFO: dev/stable-v20/master -> stable/stable-v20
141
+ # INFO: dev/stable-v21/master -> stable/stable-v21
142
+ # INFO: dev/stable-v22/master -> stable/stable-v22
143
+ # INFO:
144
+ # INFO: Upstream branches:
145
+ # INFO: <MISSING> -> stable/stable-v23
146
+ ```
147
+
122
148
  Also, once you set these parameters, you can have git-maintain create all branches for you by running
123
- ``
149
+ ```
124
150
  $ git maintain create
151
+ # INFO: Creating missing dev/stable-v23/master from stable/stable-v23
125
152
  ```
126
153
  ## Day-to-day workflow
127
154
 
@@ -227,3 +254,23 @@ Review your email, send it and your day is over !
227
254
 
228
255
  Enjoy, and feel free to report bugs, missing features and/or send patches
229
256
 
257
+ ## Git config settings
258
+
259
+ This is a summary of all the settings that can be set in the git config:
260
+
261
+ - `maintain.autofetch`: Enable/Disable auto fetching.
262
+ Can be overriden by the --[no-]fetch option on the CLI.
263
+ If unset, autofetch is enabled
264
+ - `maintain.branch-format`: Local branch name space that also extracts the version.
265
+ Example: dev\/stable-v([0-9]*) will allow all branch names dev/stable-vXXX/foo to be used against stable branch with version XXX
266
+ - `maintain.stable-branch-format`: Name of the stable branch generated with the version extracted by the `maintain.branch-format` regexp.
267
+ Example: stable-v\1 will track dev/stable-vXXX/foo against <STABLE_REPO>/stable-vXXX
268
+ - `maintain.stable-base-format`: Name of the tag from which the stable branch was forked from generated with the version extracted by the `maintain.branch-format` regexp.
269
+ Example: v\1 will be mark vXXX has the fork tag for branch <STABLE_REPO>/stable-vXXX and local branch dev/stable-vXXX/foo
270
+ This settings is only needed when using `git maintain steal` command
271
+ This rule can be overriden by a specific entry in gitconfig:
272
+ `stable-base.dev---stable-vXXX vYY-ZZ`
273
+ As git does not allow `/` in gitconfig they are to be replaced by `---`
274
+ - `maintain.mail-format`: Specify how release annoucement emails are sent. Can be:
275
+ - `imap_send`: Store prepared email in an IMAP folder. See `main git-imap-send` for more infos. This is the default value.
276
+ - `send_email`: Generates a file which is compatible with git send-email
@@ -20,7 +20,7 @@ actionParser.separator ""
20
20
  actionParser.separator "Options:"
21
21
  actionParser.on("-h", "--help", "Display usage.") { |val| puts actionParser.to_s; exit 0 }
22
22
  actionParser.separator "Possible actions:"
23
- GitMaintain::getActionAttr("ACTION_HELP").each(){|x|
23
+ GitMaintain::getActionAttr("ACTION_HELP").sort.each(){|x|
24
24
  actionParser.separator "\t " + x
25
25
  }
26
26
  rest = actionParser.order!(ARGV);
@@ -2,14 +2,49 @@ module GitMaintain
2
2
  class RDMACoreBranch < Branch
3
3
  REPO_NAME = "rdma-core"
4
4
 
5
+ def self.set_opts(action, optsParser, opts)
6
+ opts[:rel_type] = nil
7
+
8
+ case action
9
+ when :release
10
+ optsParser.on("--major", "Release a major version.") {
11
+ opts[:rel_type] = :major }
12
+ optsParser.on("--stable", "Release a stable version.") {
13
+ opts[:rel_type] = :stable }
14
+ end
15
+ end
16
+ def self.check_opts(opts)
17
+ if opts[:action] == :release then
18
+ if opts[:rel_type] == nil then
19
+ raise "No release type specified use --stable or --major"
20
+ end
21
+ end
22
+ end
5
23
  def release(opts)
6
24
  prev_ver=@repo.runGit("show HEAD:CMakeLists.txt | egrep \"[sS][eE][tT]\\\\(PACKAGE_VERSION\"").
7
25
  chomp().gsub(/[sS][eE][tT]\(PACKAGE_VERSION\s*"([0-9.]*)".*$/, '\1')
8
26
  ver_nums = prev_ver.split(".")
9
27
  new_ver = (ver_nums[0 .. -2] + [ver_nums[-1].to_i() + 1 ]).join(".")
10
- git_prev_ver = "v" + (ver_nums[-1] == "0" ? ver_nums[0 .. -2].join(".") : prev_ver)
28
+ rel_ver = new_ver
29
+ commit_msg = "Bump to version"
11
30
 
12
- puts "Preparing release #{prev_ver} => #{new_ver}"
31
+ if opts[:rel_type] == :major
32
+ new_ver = ([ ver_nums[0].to_i() + 1] + ver_nums[1 .. -1]).join(".")
33
+ rel_ver = prev_ver
34
+ prev_ver = ([ ver_nums[0].to_i() - 1] + ver_nums[1 .. -1]).join(".")
35
+ ver_nums = prev_ver.split(".")
36
+ commit_msg ="Update library version to be"
37
+ end
38
+
39
+ git_prev_ver = "v" + prev_ver
40
+ # Older tags might do have the terminal minor version (.0) for major releases
41
+ @repo.runGit("rev-parse --verify --quiet #{git_prev_ver}")
42
+ if $? != 0 then
43
+ # Try without the minor version number
44
+ git_prev_ver = "v" + ver_nums[0 .. -2].join(".")
45
+ end
46
+
47
+ puts "Preparing #{opts[:rel_type].to_s} release #{prev_ver} => #{rel_ver}"
13
48
  rep = GitMaintain::checkLog(opts, @local_branch, git_prev_ver, "release")
14
49
  if rep != "y" then
15
50
  puts "Skipping release"
@@ -20,18 +55,30 @@ module GitMaintain
20
55
  tag_path=`mktemp`.chomp()
21
56
  puts tag_path
22
57
  tag_file = File.open(tag_path, "w+")
23
- tag_file.puts "rdma-core-#{new_ver}:"
58
+ tag_file.puts "rdma-core-#{rel_ver}:"
24
59
  tag_file.puts ""
25
60
  tag_file.puts "Updates from version #{prev_ver}"
26
- tag_file.puts " * Backport fixes:"
27
- tag_file.puts `git log HEAD ^#{git_prev_ver} --format=' * %s'`
61
+ if opts[:rel_type] == :stable then
62
+ tag_file.puts " * Backport fixes:"
63
+ end
64
+ tag_file.puts `git log HEAD ^#{git_prev_ver} --no-merges --format=' * %s'`
28
65
  tag_file.close()
29
66
 
67
+ if opts[:rel_type] == :major
68
+ # For major, tag the current version first
69
+ @repo.runGitInteractive("tag -a -s v#{rel_ver} --edit -F #{tag_path}")
70
+ if $? != 0 then
71
+ raise("Failed to tag branch #{local_branch}")
72
+ end
73
+ end
74
+
30
75
  # Update version number in relevant files
31
- @repo.run("sed -i -e 's/\\(Version:[[:space:]]*\\)[0-9.]*/\\1#{new_ver}/g' redhat/rdma-core.spec suse/rdma-core.spec")
76
+ @repo.run("sed -i -e 's/\\(Version:[[:space:]]*\\)[0-9.]\\+/\\1#{new_ver}/g' redhat/rdma-core.spec suse/rdma-core.spec")
32
77
  @repo.run("sed -i -e 's/\\([sS][eE][tT](PACKAGE_VERSION[[:space:]]*\"\\)[0-9.]*\"/\\1#{new_ver}\"/g' CMakeLists.txt")
33
78
 
34
- @repo.run("cat <<EOF > debian/changelog.new
79
+ case opts[:rel_type]
80
+ when :stable
81
+ @repo.run("cat <<EOF > debian/changelog.new
35
82
  rdma-core (#{new_ver}-1) unstable; urgency=low
36
83
 
37
84
  * New upstream release.
@@ -41,16 +88,22 @@ rdma-core (#{new_ver}-1) unstable; urgency=low
41
88
  $(cat debian/changelog)
42
89
  EOF
43
90
  mv debian/changelog.new debian/changelog")
91
+ when :major
92
+ @repo.run("sed -i -e 's/^rdma-core (#{rel_ver}-1)/rdma-core (#{new_ver}-1)/' debian/changelog")
93
+ end
44
94
 
45
95
  # Add and commit
46
96
  @repo.runGit("add redhat/rdma-core.spec suse/rdma-core.spec CMakeLists.txt debian/changelog")
47
- @repo.runGit("commit -m 'Bump to version #{new_ver}' --verbose --edit --signoff")
97
+ @repo.runGitInteractive("commit -m '#{commit_msg} #{new_ver}' --verbose --edit --signoff")
48
98
  if $? != 0 then
49
99
  raise("Failed to commit on branch #{local_branch}")
50
100
  end
51
- @repo.runGit("tag -a -s v#{new_ver} --edit -F #{tag_path}")
52
- if $? != 0 then
53
- raise("Failed to tag branch #{local_branch}")
101
+
102
+ if opts[:rel_type] == :stable
103
+ @repo.runGitInteractive("tag -a -s v#{rel_ver} --edit -F #{tag_path}")
104
+ if $? != 0 then
105
+ raise("Failed to tag branch #{local_branch}")
106
+ end
54
107
  end
55
108
  `rm -f #{tag_path}`
56
109
  end
@@ -54,7 +54,7 @@ module GitMaintain
54
54
  opts[:no_travis] = false
55
55
  opts[:all] = false
56
56
  opts[:check_only] = false
57
- opts[:no_fetch] = false
57
+ opts[:fetch] = nil
58
58
  opts[:watch] = false
59
59
 
60
60
  optsParser.on("-v", "--base-version [MIN_VER]", Integer, "Older release to consider.") {
@@ -70,8 +70,8 @@ module GitMaintain
70
70
  end
71
71
 
72
72
  if NO_FETCH_ACTIONS.index(action) == nil
73
- optsParser.on("--no-fetch", "Skip fetch of stable repo.") {
74
- |val| opts[:no_fetch] = true}
73
+ optsParser.on("--[no-]fetch", "Enable/Disable fetch of stable repo.") {
74
+ |val| opts[:fetch] = val}
75
75
  end
76
76
 
77
77
  case action
@@ -122,9 +122,13 @@ module GitMaintain
122
122
  def self.execAction(opts, action)
123
123
  repo = Repo::load()
124
124
  travis = TravisChecker::load(repo)
125
+ opts[:repo] = repo
126
+ opts[:travis] = travis
127
+ brClass = GitMaintain::getClass(self, repo.name)
125
128
 
126
- if NO_FETCH_ACTIONS.index(action) == nil && opts[:no_fetch] == false then
127
- repo.stableUpdate()
129
+ if NO_FETCH_ACTIONS.index(action) == nil && opts[:fetch] != false then
130
+ GitMaintain::log(:INFO, "Fetching stable repo")
131
+ repo.stableUpdate(opts[:fetch])
128
132
  end
129
133
 
130
134
  branchList=[]
@@ -154,13 +158,24 @@ module GitMaintain
154
158
 
155
159
  loop do
156
160
  system("clear; date") if opts[:watch] != false
161
+
162
+ res=[]
163
+
164
+ # Iterate concerned on all branches
157
165
  branchList.each(){|branch|
158
166
  if NO_CHECKOUT_ACTIONS.index(action) == nil then
159
167
  GitMaintain::log(:INFO, "Working on #{branch.verbose_name}")
160
168
  branch.checkout()
161
169
  end
162
- branch.send(action, opts)
170
+ res << branch.send(action, opts)
163
171
  }
172
+
173
+ # Run epilogue (if it exists)
174
+ begin
175
+ brClass.send(action.to_s() + "_epilogue", opts, res)
176
+ rescue NoMethodError => e
177
+ end
178
+
164
179
  break if opts[:watch] == false
165
180
  sleep(opts[:watch])
166
181
  travis.emptyCache()
@@ -189,10 +204,15 @@ module GitMaintain
189
204
  @head = @repo.runGit("rev-parse --verify --quiet #{@local_branch}")
190
205
  @remote_ref = "#{@repo.stable_repo}/#{@remote_branch}"
191
206
  @stable_head = @repo.runGit("rev-parse --verify --quiet #{@remote_ref}")
192
- @stable_base = @repo.findStableBase(@local_branch)
207
+ case @branch_type
208
+ when :std
209
+ @stable_base = @repo.findStableBase(@local_branch)
210
+ when :user_specified
211
+ @stable_base = @remote_ref
212
+ end
193
213
  end
194
214
  attr_reader :version, :local_branch, :head, :remote_branch, :remote_ref, :stable_head,
195
- :verbose_name, :exists
215
+ :verbose_name, :exists, :stable_base
196
216
 
197
217
  def log(lvl, str)
198
218
  GitMaintain::log(lvl, str)
@@ -222,7 +242,7 @@ module GitMaintain
222
242
  opts[:commits].each(){|commit|
223
243
  prev_head=@repo.runGit("rev-parse HEAD")
224
244
  log(:INFO, "Applying #{@repo.getCommitHeadline(commit)}")
225
- @repo.runGit("cherry-pick #{commit}")
245
+ @repo.runGitInteractive("cherry-pick #{commit}")
226
246
  if $? != 0 then
227
247
  log(:WARNING, "Cherry pick failure. Starting bash for manual fixes. Exit shell to continue")
228
248
  @repo.runBash()
@@ -295,7 +315,7 @@ module GitMaintain
295
315
 
296
316
  rep = GitMaintain::checkLog(opts, merge_branch, @local_branch, "merge")
297
317
  if rep == "y" then
298
- @repo.runGit("merge #{merge_branch}")
318
+ @repo.runGitInteractive("merge #{merge_branch}")
299
319
  if $? != 0 then
300
320
  log(:WARNING, "Merge failure. Starting bash for manual fixes. Exit shell to continue")
301
321
  @repo.runBash()
@@ -312,8 +332,17 @@ module GitMaintain
312
332
  log(:INFO, "Nothing to push")
313
333
  return
314
334
  end
335
+ return "#{@local_branch}:#{@local_branch}"
336
+ end
337
+
338
+ def self.push_epilogue(opts, branches)
339
+ # Compact to remove empty entries
340
+ branches.compact!()
341
+
342
+ return if branches.length == 0
315
343
 
316
- @repo.runGit("push #{opts[:push_force] == true ? "-f" : ""} #{@repo.valid_repo} #{@local_branch}")
344
+ opts[:repo].runGit("push #{opts[:push_force] == true ? "-f" : ""} "+
345
+ "#{opts[:repo].valid_repo} #{branches.join(" ")}")
317
346
  end
318
347
 
319
348
  # Monitor the build status on Travis
@@ -325,7 +354,7 @@ module GitMaintain
325
354
  suff= " started at #{@travis.getValidTS(head)}"
326
355
  end
327
356
  log(:INFO, "Status for v#{@version}: " + st + suff)
328
- if st == "failed" && opts[:watch] == false
357
+ if (st == "failed" || st == "errored") && opts[:watch] == false
329
358
  rep = "y"
330
359
  suff=""
331
360
  while rep == "y"
@@ -364,13 +393,21 @@ module GitMaintain
364
393
 
365
394
  rep = GitMaintain::checkLog(opts, @local_branch, @remote_ref, "submit")
366
395
  if rep == "y" then
367
- @repo.runGit("push #{@repo.stable_repo} #{@local_branch}:#{@remote_branch}")
396
+ return "#{@local_branch}:#{@remote_branch}"
368
397
  else
369
398
  log(:INFO, "Skipping push to stable")
370
399
  return
371
400
  end
372
401
  end
373
402
 
403
+
404
+ def self.push_stable_epilogue(opts, branches)
405
+ # Compact to remove empty entries
406
+ branches.compact!()
407
+
408
+ return if branches.length == 0
409
+ opts[:repo].runGit("push #{opts[:repo].stable_repo} #{branches.join(" ")}")
410
+ end
374
411
  # Monitor the build status of the stable branch on Travis
375
412
  def monitor_stable(opts)
376
413
  st = @travis.getStableState(@stable_head)
@@ -458,13 +495,13 @@ module GitMaintain
458
495
 
459
496
  # Grab the subject, since commit sha1 is different between branches we
460
497
  # have to look it up based on subject.
461
- subj=@repo.runGit("log -1 --pretty=\"%s\" #{commit}")
498
+ subj=@repo.getCommitSubj(commit)
462
499
  if $? != 0 then
463
500
  return false
464
501
  end
465
502
 
466
503
  # Try and find if there's a commit with given subject the hard way
467
- @repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj}\" "+
504
+ @repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj.gsub("\"", '\\"')}\" "+
468
505
  "#{@stable_base}..HEAD").split("\n").each(){|cmt|
469
506
  cursubj=@repo.runGit("log -1 --format=\"%s\" #{cmt}")
470
507
  if cursubj = subj then
@@ -512,7 +549,7 @@ module GitMaintain
512
549
  end
513
550
 
514
551
  def pick_one(commit)
515
- @repo.runGit("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
552
+ @repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
516
553
  return if $? == 0
517
554
  if @repo.runGit("status -uno --porcelain | wc -l") == "0" then
518
555
  @repo.runGit("reset --hard")
@@ -522,7 +559,7 @@ module GitMaintain
522
559
  # That didn't work? Let's try that with every variation of the commit
523
560
  # in other stable trees.
524
561
  @repo.find_alts(commit).each(){|alt_commit|
525
- @repo.runGit("cherry-pick --strategy=recursive -Xpatience -x #{alt_commit} &> /dev/null")
562
+ @repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{alt_commit} &> /dev/null")
526
563
  if $? == 0 then
527
564
  return
528
565
  end
@@ -530,7 +567,7 @@ module GitMaintain
530
567
  }
531
568
  # Still no? Let's go back to the original commit and hand it off to
532
569
  # the user.
533
- @repo.runGit("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
570
+ @repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
534
571
  raise CherryPickErrorException.new("Failed to cherry pick commit #{commit}", commit)
535
572
  return false
536
573
  end
@@ -571,7 +608,7 @@ module GitMaintain
571
608
  end
572
609
 
573
610
  def steal_one(opts, commit)
574
- subj=@repo.runGit("log -1 --format=\"%s\" #{commit}")
611
+ subj=@repo.getCommitSubj(commit)
575
612
  subj.gsub!(/"/, '\"')
576
613
  msg=''
577
614
 
@@ -585,8 +622,10 @@ module GitMaintain
585
622
  return true
586
623
  end
587
624
 
625
+ log(:VERBOSE, "Found relevant commit #{@repo.getCommitHeadline(commit)}")
588
626
  if is_in_tree?(orig_cmt) == true
589
627
  # Commit is already in the stable branch, skip
628
+ log(:VERBOSE, "Commit is already in tree")
590
629
  return true
591
630
  end
592
631
 
@@ -59,21 +59,21 @@ module GitMaintain
59
59
  end
60
60
  module_function :registerCustom
61
61
 
62
- def getCustom(repo_name)
63
- return @@custom_classes[repo_name]
64
- end
65
- module_function :getCustom
66
-
67
- def loadClass(default_class, repo_name, *more)
62
+ def getClass(default_class, repo_name = File.basename(Dir.pwd()))
68
63
  custom = @@custom_classes[repo_name]
69
64
  if custom != nil && custom[default_class] != nil then
70
65
  log(:DEBUG,"Detected custom #{default_class} class for repo '#{repo_name}'")
71
- return custom[default_class].new(*more)
66
+ return custom[default_class]
72
67
  else
73
68
  log(:DEBUG,"Detected NO custom #{default_class} classes for repo '#{repo_name}'")
74
- return default_class.new(*more)
69
+ return default_class
75
70
  end
76
71
  end
72
+ module_function :getClass
73
+
74
+ def loadClass(default_class, repo_name, *more)
75
+ return GitMaintain::getClass(default_class, repo_name).new(*more)
76
+ end
77
77
  module_function :loadClass
78
78
 
79
79
  # Check that the constructor was called through loadClass
@@ -97,8 +97,14 @@ module GitMaintain
97
97
  def setOpts(action, optsParser, opts)
98
98
  ACTION_CLASS.each(){|x|
99
99
  next if x::ACTION_LIST.index(action) == nil
100
- next if x.singleton_methods().index(:set_opts) == nil
101
- x.set_opts(action, optsParser, opts)
100
+ if x.singleton_methods().index(:set_opts) != nil then
101
+ x.set_opts(action, optsParser, opts)
102
+ end
103
+ # Try to add repo specific opts
104
+ y = getClass(x)
105
+ if x != y && y.singleton_methods().index(:set_opts) != nil then
106
+ y.set_opts(action, optsParser, opts)
107
+ end
102
108
  break
103
109
  }
104
110
  end
@@ -108,6 +114,12 @@ module GitMaintain
108
114
  ACTION_CLASS.each(){|x|
109
115
  next if x.singleton_methods().index(:check_opts) == nil
110
116
  x.check_opts(opts)
117
+
118
+ # Try to add repo specific opts
119
+ y = getClass(x)
120
+ if x != y && y.singleton_methods().index(:check_opts) != nil then
121
+ y.check_opts(opts)
122
+ end
111
123
  }
112
124
  end
113
125
  module_function :checkOpts
@@ -6,11 +6,13 @@ module GitMaintain
6
6
 
7
7
  ACTION_LIST = [
8
8
  :list_branches,
9
+ :summary,
9
10
  # Internal commands for completion
10
11
  :list_suffixes, :submit_release
11
12
  ]
12
13
  ACTION_HELP = [
13
14
  "* submit_release: Push the to stable and create the release packages",
15
+ "* summary: Displays a summary of the configuration and the branches git-maintain sees"
14
16
  ]
15
17
 
16
18
  def self.load(path=".")
@@ -47,10 +49,11 @@ module GitMaintain
47
49
  if path == nil
48
50
  @path = Dir.pwd()
49
51
  end
52
+ @name = File.basename(@path)
50
53
 
51
- @valid_repo = runGit("config maintain.valid-repo 2> /dev/null").chomp()
54
+ @valid_repo = getGitConfig("maintain.valid-repo")
52
55
  @valid_repo = @@VALID_REPO if @valid_repo == ""
53
- @stable_repo = runGit("config maintain.stable-repo 2>/dev/null").chomp()
56
+ @stable_repo = getGitConfig("maintain.stable-repo")
54
57
  @stable_repo = @@STABLE_REPO if @stable_repo == ""
55
58
 
56
59
  @remote_valid=runGit("remote -v | egrep '^#{@valid_repo}' | grep fetch |
@@ -58,10 +61,22 @@ module GitMaintain
58
61
  @remote_stable=runGit("remote -v | egrep '^#{@stable_repo}' | grep fetch |
59
62
  awk '{ print $2}' | sed -e 's/.*://' -e 's/\\.git//'")
60
63
 
61
- @branch_format_raw = runGit("config maintain.branch-format 2> /dev/null").chomp()
64
+ @auto_fetch = getGitConfig("maintain.autofetch")
65
+ case @auto_fetch
66
+ when ""
67
+ @auto_fetch = nil
68
+ when "true", "yes", "on"
69
+ @auto_fetch = true
70
+ when "false", "no", "off"
71
+ @auto_fetch = false
72
+ else
73
+ raise("Invalid value '#{@auto_fetch}' in git config for maintain.autofetch")
74
+ end
75
+
76
+ @branch_format_raw = getGitConfig("maintain.branch-format")
62
77
  @branch_format = Regexp.new(/#{@branch_format_raw}/)
63
- @stable_branch_format = runGit("config maintain.stable-branch-format 2> /dev/null").chomp()
64
- @stable_base_format = runGit("config maintain.stable-base-format 2> /dev/null").chomp()
78
+ @stable_branch_format = getGitConfig("maintain.stable-branch-format")
79
+ @stable_base_format = getGitConfig("maintain.stable-base-format")
65
80
 
66
81
  @stable_base_patterns=
67
82
  runGit("config --get-regexp stable-base | egrep '^stable-base\.' | "+
@@ -70,8 +85,22 @@ module GitMaintain
70
85
  m[y[0]] = y[1]
71
86
  m
72
87
  }
88
+
89
+ @mail_format = getGitConfig("maintain.mail-format")
90
+ if @mail_format == "" then
91
+ @mail_format = :imap_send
92
+ else
93
+ # Check that the format is valid
94
+ case @mail_format
95
+ when "imap_send", "send_email"
96
+ else
97
+ raise("Invalid mail-format #{@mail_format}")
98
+ end
99
+
100
+ @mail_format = @mail_format.to_sym()
101
+ end
73
102
  end
74
- attr_reader :path, :remote_valid, :remote_stable, :valid_repo, :stable_repo
103
+ attr_reader :path, :name, :remote_valid, :remote_stable, :valid_repo, :stable_repo
75
104
 
76
105
  def log(lvl, str)
77
106
  GitMaintain::log(lvl, str)
@@ -83,11 +112,18 @@ module GitMaintain
83
112
  def runSystem(cmd)
84
113
  return system("cd #{@path} && #{cmd}")
85
114
  end
115
+
86
116
  def runGit(cmd)
87
117
  log(:DEBUG, "Called from #{caller[1]}")
88
118
  log(:DEBUG, "Running git command '#{cmd}'")
89
119
  return `git --work-tree=#{@path} #{cmd}`.chomp()
90
120
  end
121
+ def runGitInteractive(cmd)
122
+ log(:DEBUG, "Called from #{caller[1]}")
123
+ log(:DEBUG, "Running interactive git command '#{cmd}'")
124
+ return system("git --work-tree=#{@path} #{cmd}")
125
+ end
126
+
91
127
  def runGitImap(cmd)
92
128
  return `export GIT_ASKPASS=$(dirname $(dirname $(which git)))/lib/git-core/git-gui--askpass;
93
129
  if [ ! -f $GIT_ASKPASS ]; then
@@ -97,6 +133,9 @@ module GitMaintain
97
133
  export GIT_ASKPASS=/usr/lib/ssh/ssh-askpass;
98
134
  fi; git --work-tree=#{@path} imap-send #{cmd}`
99
135
  end
136
+ def getGitConfig(entry)
137
+ return runGit("config #{entry} 2> /dev/null").chomp()
138
+ end
100
139
 
101
140
  def runBash()
102
141
  runSystem("bash")
@@ -111,8 +150,13 @@ module GitMaintain
111
150
  def getCommitHeadline(sha)
112
151
  return runGit("show --format=oneline --no-patch --no-decorate #{sha}")
113
152
  end
153
+ def getCommitSubj(sha)
154
+ return runGit("log -1 --pretty=\"%s\" #{sha}")
155
+ end
114
156
 
115
- def stableUpdate()
157
+ def stableUpdate(fetch=nil)
158
+ fetch = @auto_fetch if fetch == nil
159
+ return if fetch == false
116
160
  log(:VERBOSE, "Fetching stable updates...")
117
161
  runGit("fetch #{@stable_repo}")
118
162
  end
@@ -173,9 +217,9 @@ module GitMaintain
173
217
  mail_path=`mktemp`.chomp()
174
218
  mail = File.open(mail_path, "w+")
175
219
  mail.puts "From " + runGit("rev-parse HEAD") + " " + `date`.chomp()
176
- mail.puts "From: " + runGit("config user.name") +
177
- " <" + runGit("config user.email") +">"
178
- mail.puts "To: " + runGit("config patch.target")
220
+ mail.puts "From: " + getGitConfig("user.name") +
221
+ " <" + getGitConfig("user.email") +">"
222
+ mail.puts "To: " + getGitConfig("patch.target")
179
223
  mail.puts "Date: " + `date -R`.chomp()
180
224
 
181
225
  if new_tags.length > 4 then
@@ -187,8 +231,8 @@ module GitMaintain
187
231
  else
188
232
  mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + " " +
189
233
  (new_tags.length > 1 ?
190
- (new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have ") :
191
- (new_tags.join(" ") + " has ")) +
234
+ (new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have") :
235
+ (new_tags.join(" ") + " has")) +
192
236
  " been tagged/released"
193
237
  mail.puts ""
194
238
  end
@@ -210,7 +254,14 @@ module GitMaintain
210
254
  mail.puts "https://github.com/#{@remote_stable}/releases"
211
255
  mail.close()
212
256
 
213
- puts runGitImap("< #{mail_path}; rm -f #{mail_path}")
257
+ case @mail_format
258
+ when :imap_send
259
+ puts runGitImap("< #{mail_path}")
260
+ when :send_email
261
+ run("cp #{mail_path} announce-release.eml")
262
+ log(:INFO, "Generated annoucement email in #{@path}/announce-release.eml")
263
+ end
264
+ run("rm -f #{mail_path}")
214
265
  end
215
266
 
216
267
  log(:WARNING, "Last chance to cancel before submitting")
@@ -255,7 +306,52 @@ module GitMaintain
255
306
  def submit_release(opts)
256
307
  submitReleases(opts)
257
308
  end
258
-
309
+ def summary(opts)
310
+ log(:INFO, "Configuration summary:")
311
+ log(:INFO, "Stable remote: #{@@STABLE_REPO}")
312
+ log(:INFO, "Validation remote: #{@@VALID_REPO}")
313
+ log(:INFO, "")
314
+ log(:INFO, "Branch config:")
315
+ log(:INFO, "Local branch format: /#{@branch_format_raw}/")
316
+ log(:INFO, "Remote stable branch format: #{@stable_branch_format}")
317
+ log(:INFO, "Remote stable base format: #{@stable_base_format}")
318
+
319
+ if @stable_base_patterns.length > 0 then
320
+ log(:INFO, "")
321
+ log(:INFO, "Stable base rules:")
322
+ @stable_base_patterns.each(){|name, base|
323
+ log(:INFO, "\t#{name} -> #{base}")
324
+ }
325
+ end
326
+ brList = getBranchList(opts[:br_suff])
327
+ brStList = getStableBranchList()
328
+
329
+ if brList.length > 0 then
330
+ log(:INFO, "")
331
+ log(:INFO, "Local branches:")
332
+ brList.each(){|br|
333
+ branch = Branch.load(self, br, nil, opts[:branch_suff])
334
+ localBr = branch.local_branch
335
+ stableBr = @@STABLE_REPO + "/" + branch.remote_branch
336
+ stableBase = branch.stable_base
337
+ runGit("rev-parse --verify --quiet #{stableBr}")
338
+ stableBr = "<MISSING>" if $? != 0
339
+ log(:INFO, "\t#{localBr} -> #{stableBr} (#{stableBase})")
340
+ brStList.delete(br)
341
+ }
342
+ end
343
+
344
+ if brStList.length > 0 then
345
+ log(:INFO, "")
346
+ log(:INFO, "Upstream branches:")
347
+ brStList.each(){|br|
348
+ branch = Branch.load(self, br, nil, opts[:branch_suff])
349
+ stableBr = @@STABLE_REPO + "/" + branch.remote_branch
350
+ stableBase = branch.stable_base
351
+ log(:INFO, "\t<MISSING> -> #{stableBr} (#{stableBase})")
352
+ }
353
+ end
354
+ end
259
355
  def find_alts(commit)
260
356
  alts=[]
261
357
 
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.6.0
4
+ version: 0.7.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: 2019-03-21 00:00:00.000000000 Z
11
+ date: 2019-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: github-release