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/repo.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'octokit'
2
+ require 'io/console'
3
+
1
4
  module GitMaintain
2
5
  class Repo
3
6
  @@VALID_REPO = "github"
@@ -10,10 +13,10 @@ module GitMaintain
10
13
  # Internal commands for completion
11
14
  :list_suffixes, :submit_release
12
15
  ]
13
- ACTION_HELP = [
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"
16
- ]
16
+ ACTION_HELP = {
17
+ :submit_release => "Push the tags to 'stable' remote and create the release packages",
18
+ :summary => "Displays a summary of the configuration and the branches git-maintain sees"
19
+ }
17
20
 
18
21
  def self.load(path=".")
19
22
  dir = Dir.pwd()
@@ -45,6 +48,7 @@ module GitMaintain
45
48
  @branch_list=nil
46
49
  @stable_branches=nil
47
50
  @suffix_list=nil
51
+ @config_cache={}
48
52
 
49
53
  if path == nil
50
54
  @path = Dir.pwd()
@@ -134,7 +138,7 @@ module GitMaintain
134
138
  fi; git --work-tree=#{@path} imap-send #{cmd}`
135
139
  end
136
140
  def getGitConfig(entry)
137
- return runGit("config #{entry} 2> /dev/null").chomp()
141
+ return @config_cache[entry] ||= runGit("config #{entry} 2> /dev/null").chomp()
138
142
  end
139
143
 
140
144
  def runBash()
@@ -194,7 +198,7 @@ module GitMaintain
194
198
  return @suffix_list
195
199
  end
196
200
 
197
- def submitReleases(opts)
201
+ def getUnreleasedTags(opts)
198
202
  remote_tags=runGit("ls-remote --tags #{@stable_repo} |
199
203
  egrep 'refs/tags/v[0-9.]*$'").split("\n").map(){
200
204
  |x| x.gsub(/.*refs\/tags\//, '')
@@ -202,75 +206,76 @@ module GitMaintain
202
206
  local_tags =runGit("tag -l | egrep '^v[0-9.]*$'").split("\n")
203
207
 
204
208
  new_tags = local_tags - remote_tags
205
- if new_tags.empty? then
206
- log(:INFO, "All tags are already submitted.")
207
- return
208
- end
209
-
210
- log(:WARNING, "This will officially release these tags: #{new_tags.join(", ")}")
211
- rep = GitMaintain::confirm(opts, "release them")
212
- if rep != 'y' then
213
- raise "Aborting.."
214
- end
215
-
216
- if @NOTIFY_RELEASE != false
217
- mail_path=`mktemp`.chomp()
218
- mail = File.open(mail_path, "w+")
219
- mail.puts "From " + runGit("rev-parse HEAD") + " " + `date`.chomp()
220
- mail.puts "From: " + getGitConfig("user.name") +
221
- " <" + getGitConfig("user.email") +">"
222
- mail.puts "To: " + getGitConfig("patch.target")
223
- mail.puts "Date: " + `date -R`.chomp()
224
-
225
- if new_tags.length > 4 then
226
- mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + ": new stable releases"
227
- mail.puts ""
228
- mail.puts "These version were tagged/released:\n * " +
229
- new_tags.join("\n * ")
230
- mail.puts ""
231
- else
232
- mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + " " +
233
- (new_tags.length > 1 ?
234
- (new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have") :
235
- (new_tags.join(" ") + " has")) +
236
- " been tagged/released"
237
- mail.puts ""
238
- end
239
- mail.puts "It's available at the normal places:"
209
+ return new_tags
210
+ end
211
+ def genReleaseNotif(opts, new_tags)
212
+ return if @NOTIFY_RELEASE == false
213
+
214
+ mail_path=`mktemp`.chomp()
215
+ mail = File.open(mail_path, "w+")
216
+ mail.puts "From " + runGit("rev-parse HEAD") + " " + `date`.chomp()
217
+ mail.puts "From: " + getGitConfig("user.name") +
218
+ " <" + getGitConfig("user.email") +">"
219
+ mail.puts "To: " + getGitConfig("patch.target")
220
+ mail.puts "Date: " + `date -R`.chomp()
221
+
222
+ if new_tags.length > 4 then
223
+ mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + ": new stable releases"
240
224
  mail.puts ""
241
- mail.puts "git://github.com/#{@remote_stable}"
242
- mail.puts "https://github.com/#{@remote_stable}/releases"
225
+ mail.puts "These version were tagged/released:\n * " +
226
+ new_tags.join("\n * ")
243
227
  mail.puts ""
244
- mail.puts "---"
228
+ else
229
+ mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + " " +
230
+ (new_tags.length > 1 ?
231
+ (new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have") :
232
+ (new_tags.join(" ") + " has")) +
233
+ " been tagged/released"
245
234
  mail.puts ""
246
- mail.puts "Here's the information from the tags:"
247
- new_tags.sort().each(){|tag|
248
- mail.puts `git show #{tag} --no-decorate -q | awk '!p;/^-----END PGP SIGNATURE-----/{p=1}'`
249
- mail.puts ""
250
- }
251
- mail.puts "It's available at the normal places:"
235
+ end
236
+ mail.puts "It's available at the normal places:"
237
+ mail.puts ""
238
+ mail.puts "git://github.com/#{@remote_stable}"
239
+ mail.puts "https://github.com/#{@remote_stable}/releases"
240
+ mail.puts ""
241
+ mail.puts "---"
242
+ mail.puts ""
243
+ mail.puts "Here's the information from the tags:"
244
+ new_tags.sort().each(){|tag|
245
+ mail.puts `git show #{tag} --no-decorate -q | awk '!p;/^-----END PGP SIGNATURE-----/{p=1}'`
252
246
  mail.puts ""
253
- mail.puts "git://github.com/#{@remote_stable}"
254
- mail.puts "https://github.com/#{@remote_stable}/releases"
255
- mail.close()
256
-
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}")
247
+ }
248
+ mail.close()
249
+
250
+ case @mail_format
251
+ when :imap_send
252
+ puts runGitImap("< #{mail_path}")
253
+ when :send_email
254
+ run("cp #{mail_path} announce-release.eml")
255
+ log(:INFO, "Generated annoucement email in #{@path}/announce-release.eml")
265
256
  end
257
+ run("rm -f #{mail_path}")
258
+ end
259
+ def submitReleases(opts, new_tags)
260
+ new_tags.each(){|tag|
261
+ createRelease(opts, tag)
262
+ }
263
+ end
266
264
 
267
- log(:WARNING, "Last chance to cancel before submitting")
268
- rep= GitMaintain::confirm(opts, "submit these releases")
269
- if rep != 'y' then
270
- raise "Aborting.."
265
+ def createRelease(opts, tag, github_rel=true)
266
+ log(:INFO, "Creating a release for #{tag}")
267
+ runGit("push #{@stable_repo} refs/tags/#{tag}")
268
+
269
+ if github_rel == true then
270
+ msg = runGit("tag -l -n1000 '#{tag}'") + "\n"
271
+
272
+ # Ye ghods is is a horrific format to parse
273
+ name, body = msg.split("\n", 2)
274
+ name = name.gsub(/^#{tag}/, '').strip
275
+ body = body.split("\n").map { |l| l.sub(/^ /, '') }.join("\n")
276
+ api.create_release(@remote_stable, tag, :name => name, :body => body)
271
277
  end
272
- puts `#{@@SUBMIT_BINARY}`
273
- end
278
+ end
274
279
 
275
280
  def versionToLocalBranch(version, suff)
276
281
  return @branch_format_raw.gsub(/\\\//, '/').
@@ -304,12 +309,33 @@ module GitMaintain
304
309
  puts getSuffixList()
305
310
  end
306
311
  def submit_release(opts)
307
- submitReleases(opts)
312
+ new_tags = getUnreleasedTags(opts)
313
+ if new_tags.empty? then
314
+ log(:INFO, "All tags are already submitted.")
315
+ return
316
+ end
317
+
318
+ log(:WARNING, "This will officially release these tags: #{new_tags.join(", ")}")
319
+ rep = GitMaintain::confirm(opts, "release them", true)
320
+ if rep != 'y' then
321
+ raise "Aborting.."
322
+ end
323
+
324
+ if @NOTIFY_RELEASE != false
325
+ genReleaseNotif(opts, new_tags)
326
+ end
327
+
328
+ log(:WARNING, "Last chance to cancel before submitting")
329
+ rep= GitMaintain::confirm(opts, "submit these releases", true)
330
+ if rep != 'y' then
331
+ raise "Aborting.."
332
+ end
333
+ submitReleases(opts, new_tags)
308
334
  end
309
335
  def summary(opts)
310
336
  log(:INFO, "Configuration summary:")
311
- log(:INFO, "Stable remote: #{@@STABLE_REPO}")
312
- log(:INFO, "Validation remote: #{@@VALID_REPO}")
337
+ log(:INFO, "Stable remote: #{@stable_repo}")
338
+ log(:INFO, "Validation remote: #{@valid_repo}")
313
339
  log(:INFO, "")
314
340
  log(:INFO, "Branch config:")
315
341
  log(:INFO, "Local branch format: /#{@branch_format_raw}/")
@@ -369,5 +395,50 @@ module GitMaintain
369
395
 
370
396
  return alts
371
397
  end
372
- end
398
+
399
+ #
400
+ # Github API stuff
401
+ #
402
+ def api
403
+ @api ||= Octokit::Client.new(:access_token => token, :auto_paginate => true)
404
+ end
405
+
406
+ def token
407
+ @token ||= begin
408
+ # We cannot use the 'defaults' functionality of git_config here,
409
+ # because get_new_token would be evaluated before git_config ran
410
+ tok = getGitConfig("maintain.api-token")
411
+ tok.to_s() == "" ? get_new_token : tok
412
+ end
413
+ end
414
+ def get_new_token
415
+ puts "Requesting a new OAuth token from Github..."
416
+ print "Github username: "
417
+ user = $stdin.gets.chomp
418
+ print "Github password: "
419
+ pass = $stdin.noecho(&:gets).chomp
420
+ puts
421
+
422
+ api = Octokit::Client.new(:login => user, :password => pass)
423
+
424
+ begin
425
+ res = api.create_authorization(:scopes => [:repo], :note => "git-maintain")
426
+ rescue Octokit::Unauthorized
427
+ puts "Username or password incorrect. Please try again."
428
+ return get_new_token
429
+ rescue Octokit::OneTimePasswordRequired
430
+ print "Github OTP: "
431
+ otp = $stdin.noecho(&:gets).chomp
432
+ res = api.create_authorization(:scopes => [:repo], :note => "git-maintain",
433
+ :headers => {"X-GitHub-OTP" => otp})
434
+ end
435
+
436
+ token = res[:token]
437
+ runGit("config --global maintain.api-token '#{token}'")
438
+
439
+ # Now reopen with the token so OTP does not bother us
440
+ @api=nil
441
+ token
442
+ end
443
+ end
373
444
  end
data/lib/travis.rb CHANGED
@@ -1,56 +1,13 @@
1
1
  module GitMaintain
2
- class TravisChecker
3
- TRAVIS_URL='https://api.travis-ci.org/'
4
-
5
- def self.load(repo)
6
- repo_name = File.basename(repo.path)
7
- return GitMaintain::loadClass(TravisChecker, repo_name, repo)
8
- end
2
+ class TravisCI < CI
3
+ TRAVIS_URL='https://api.travis-ci.com/'
9
4
 
10
5
  def initialize(repo)
11
- GitMaintain::checkDirectConstructor(self.class)
12
-
13
- @repo = repo
14
- @cachedJson={}
6
+ super(repo)
7
+ @url = TRAVIS_URL
15
8
  end
16
9
 
17
10
  private
18
- def log(lvl, str)
19
- GitMaintain::log(lvl, str)
20
- end
21
-
22
- def fetch(uri_str, limit = 10)
23
- # You should choose a better exception.
24
- raise ArgumentError, 'too many HTTP redirects' if limit == 0
25
-
26
- response = Net::HTTP.get_response(URI(uri_str))
27
-
28
- case response
29
- when Net::HTTPSuccess then
30
- response
31
- when Net::HTTPRedirection then
32
- location = response['location']
33
- fetch(location, limit - 1)
34
- else
35
- response.value
36
- end
37
- end
38
- def getJson(query_label, query, json=true)
39
- return @cachedJson[query_label] if @cachedJson[query_label] != nil
40
- url = TRAVIS_URL + query
41
- uri = URI(url)
42
- log(:INFO, "Querying travis...")
43
- log(:DEBUG_TRAVIS, url)
44
- response = fetch(uri)
45
- raise("Travis request failed '#{url}'") if response.code.to_s() != '200'
46
-
47
- if json == true
48
- @cachedJson[query_label] = JSON.parse(response.body)
49
- else
50
- @cachedJson[query_label] = response.body
51
- end
52
- return @cachedJson[query_label]
53
- end
54
11
  def getState(sha1, resp)
55
12
  br = findBranch(sha1, resp)
56
13
  return "not found" if br == nil
@@ -61,7 +18,7 @@ module GitMaintain
61
18
  br = findBranch(sha1, resp)
62
19
  raise("Travis build not found") if br == nil
63
20
  job_id = br["job_ids"].last().to_s()
64
- return getJson("log_" + job_id, 'jobs/' + job_id + '/log', false)
21
+ return getJson(@url, "travis_log_" + job_id, 'jobs/' + job_id + '/log', false)
65
22
  end
66
23
  def getTS(sha1, resp)
67
24
  br = findBranch(sha1, resp)
@@ -73,17 +30,17 @@ module GitMaintain
73
30
  end
74
31
 
75
32
  def getBrValidJson()
76
- return getJson(:br_valid, 'repos/' + @repo.remote_valid + '/branches')
33
+ return getJson(@url, :travis_br_valid, 'repos/' + @repo.remote_valid + '/branches')
77
34
  end
78
35
  def getBrStableJson()
79
- return getJson(:br_stable, 'repos/' + @repo.remote_stable + '/branches')
36
+ return getJson(@url, :travis_br_stable, 'repos/' + @repo.remote_stable + '/branches')
80
37
  end
81
38
  def findBranch(sha1, resp)
82
- log(:DEBUG_TRAVIS, "Looking for build for #{sha1}")
39
+ log(:DEBUG_CI, "Looking for build for #{sha1}")
83
40
  resp["branches"].each(){|br|
84
41
  commit=resp["commits"].select(){|e| e["id"] == br["commit_id"]}.first()
85
42
  raise("Incomplete JSON received from Travis") if commit == nil
86
- log(:DEBUG_TRAVIS, "Found entry for sha #{commit["sha"]}")
43
+ log(:DEBUG_CI, "Found entry for sha #{commit["sha"]}")
87
44
  next if commit["sha"] != sha1
88
45
  return br
89
46
  }
@@ -91,33 +48,33 @@ module GitMaintain
91
48
  end
92
49
 
93
50
  public
94
- def getValidState(sha1)
51
+ def getValidState(br, sha1)
95
52
  return getState(sha1, getBrValidJson())
96
53
  end
97
- def checkValidState(sha1)
54
+ def checkValidState(br, sha1)
98
55
  return checkState(sha1, getBrValidJson())
99
56
  end
100
- def getValidLog(sha1)
57
+ def getValidLog(br, sha1)
101
58
  return getLog(sha1, getBrValidJson())
102
59
  end
103
- def getValidTS(sha1)
60
+ def getValidTS(br, sha1)
104
61
  return getTS(sha1, getBrValidJson())
105
62
  end
106
63
 
107
- def getStableState(sha1)
64
+ def getStableState(br, sha1)
108
65
  return getState(sha1, getBrStableJson())
109
66
  end
110
- def checkStableState(sha1)
67
+ def checkStableState(br, sha1)
111
68
  return checkState(sha1, getBrStableJson())
112
69
  end
113
- def getStableLog(sha1)
70
+ def getStableLog(br, sha1)
114
71
  return getLog(sha1, getBrStableJson())
115
72
  end
116
- def getStableTS(sha1)
73
+ def getStableTS(br, sha1)
117
74
  return getTS(sha1, getBrStableJson())
118
75
  end
119
- def emptyCache()
120
- @cachedJson={}
76
+ def isErrored(br, status)
77
+ return status == "failed" || status == "errored"
121
78
  end
122
79
  end
123
80
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-maintain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0rc1
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-05-29 00:00:00.000000000 Z
11
+ date: 2022-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: github-release
14
+ name: octokit
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
27
33
  description: |-
28
34
  Be lazy and let git-maintain do all the heavy lifting for maintaining stable branches.
29
35
  Leaves you only with the essential: reviewing the selected patches and decide where they should go.
@@ -39,13 +45,16 @@ files:
39
45
  - bin/git-maintain
40
46
  - git-maintain-completion.sh
41
47
  - lib/addons/RDMACore.rb
48
+ - lib/addons/git-maintain.rb
49
+ - lib/azure.rb
42
50
  - lib/branch.rb
51
+ - lib/ci.rb
43
52
  - lib/common.rb
44
53
  - lib/repo.rb
45
54
  - lib/travis.rb
46
55
  homepage: https://github.com/nmorey/git-maintain
47
56
  licenses:
48
- - MIT
57
+ - GPL-3.0
49
58
  metadata: {}
50
59
  post_install_message:
51
60
  rdoc_options: []
@@ -58,12 +67,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
67
  version: '0'
59
68
  required_rubygems_version: !ruby/object:Gem::Requirement
60
69
  requirements:
61
- - - ">="
70
+ - - ">"
62
71
  - !ruby/object:Gem::Version
63
- version: '0'
72
+ version: 1.3.1
64
73
  requirements: []
65
- rubygems_version: 3.0.3
74
+ rubygems_version: 3.0.8
66
75
  signing_key:
67
76
  specification_version: 4
68
- summary: Your ultimate script for maintaining stable branches.
77
+ summary: Your ultimate script for maintaining stable branches and releasing your project.
69
78
  test_files: []