git-version-bump 0.17.2 → 0.18.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: cb5d7286ef401dcda5941cfe558c6c76a01f3643d3b64fbf4c39ef0e26df9e43
4
- data.tar.gz: c52065c4822f48411b645da6c9d1e864f9439ced6fc25a2b94cec3d8d743628d
3
+ metadata.gz: 80ff2d2ad4a6b5c8ea81891a9004d97507f4d9075081638034e319cd9ddccb81
4
+ data.tar.gz: ea24000b5f002ae3f3369cd41bff4b31c91c7dfd32a88d1ae45cfa6ce0648114
5
5
  SHA512:
6
- metadata.gz: c128a2fac14105f6703f4344658831392668ffe391460d90b404893d0d9373edc43ce5b25b7572d750f04c7fdb4c50b724b539b02095fd7b8dbe055c1b4d9fc9
7
- data.tar.gz: cd902acf61793e97f98de3139d04dbea2e1e907fc8ead518e6e607283fc79ea984097e1e27b61c73facd49a2039db48091c5c56dfac276f21c8a956126c32220
6
+ metadata.gz: 837115664720c3e410e3f07b9111a81bad5451fcf81ca76c4b6255d387a4ce802098c2fe178157eaddf01fb5d67cc62dd744027f73f8c5c387e34fb363ecb840
7
+ data.tar.gz: 1f9b8a018b2c8d54bd0eea72d65578d6fe28f799a32579e2397e22ffddcce2335c530d0db5ba96627e1987d0133407a58f9141477eb6e3cbe29b74ffc2ba8754
data/bin/git-version-bump CHANGED
@@ -1,14 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'git-version-bump'
4
-
5
3
  if ARGV[0].nil? or
6
4
  ARGV[0].empty? or
7
5
  (ARGV.length == 1 && (ARGV[0] == "-d" || ARGV[0] == "--dry-run")) or
8
6
  ARGV[0] == '-h' or
9
7
  ARGV[0] == '--help'
10
8
  $stderr.puts <<-EOF.gsub(/^\t\t/, '')
11
- Usage: git version-bump [-n|--notes] [-d|--dry-run] <major|minor|patch|show>
9
+ Usage: git version-bump [-n|--notes] [-l|--lite-tags] [-d|--dry-run] <major|minor|patch|show>
12
10
 
13
11
  'major': x.y.z -> x+1.0.0
14
12
  'minor': x.y.z -> x.y+1.0
@@ -32,24 +30,40 @@ elsif ARGV[0] == '-h' or ARGV[0] == '--help'
32
30
  exit 0
33
31
  end
34
32
 
35
- result = case ARGV[0].downcase
36
- when /^maj?o?r?$/
37
- "#{GVB.major_version(true) + 1}.0.0"
38
- when /^min?o?r?$/
39
- "#{GVB.major_version(true)}.#{GVB.minor_version(true)+1}.0"
40
- when /^pa?t?c?h?$/
41
- "#{GVB.major_version(true)}.#{GVB.minor_version(true)}.#{GVB.patch_version(true)+1}"
42
- when /^sh?o?w?$/
43
- puts GVB.version(true)
44
- exit 0
45
- else
46
- $stderr.puts "Unknown argument: #{ARGV[0]}. Try --help."
47
- exit 1
48
- end
33
+ begin
34
+ require 'git-version-bump'
35
+
36
+ result = case ARGV[0].downcase
37
+ when /^maj?o?r?$/
38
+ "#{GVB.major_version(true) + 1}.0.0"
39
+ when /^min?o?r?$/
40
+ "#{GVB.major_version(true)}.#{GVB.minor_version(true)+1}.0"
41
+ when /^pa?t?c?h?$/
42
+ "#{GVB.major_version(true)}.#{GVB.minor_version(true)}.#{GVB.patch_version(true)+1}"
43
+ when /^sh?o?w?$/
44
+ puts GVB.version(true)
45
+ exit 0
46
+ else
47
+ $stderr.puts "Unknown argument: #{ARGV[0]}. Try --help."
48
+ exit 1
49
+ end
49
50
 
50
- if dry_run
51
- puts result
52
- else
53
- GVB.tag_version result, release_notes, lite_tags
54
- puts "Version is now #{GVB.version(true)}."
51
+ if dry_run
52
+ puts result
53
+ else
54
+ unless GVB.tag_version result, release_notes, lite_tags
55
+ exit 1
56
+ end
57
+ puts "Version is now #{GVB.version(true)}."
58
+ end
59
+ rescue GVB::VersionUnobtainable => ex
60
+ $stderr.puts "Could not obtain version information. #{ex.message} (git available: #{GVB.git_available?.inspect})"
61
+ exit 1
62
+ rescue GVB::CommandFailure => ex
63
+ $stderr.puts "#{ex.message} (exit status: #{ex.exitstatus})"
64
+ $stderr.puts "command output was:"
65
+ $stderr.puts "----8<----"
66
+ $stderr.puts ex.output
67
+ $stderr.puts "---->8----"
68
+ exit 1
55
69
  end
@@ -1,47 +1,43 @@
1
1
  require 'tempfile'
2
2
  require 'digest/sha1'
3
+ require 'open3'
3
4
  require 'pathname'
4
5
 
5
6
  module GitVersionBump
6
7
  class VersionUnobtainable < StandardError; end
8
+ class CommandFailure < StandardError
9
+ attr_accessor :output, :exitstatus
10
+
11
+ def initialize(m, output, exitstatus)
12
+ super(m)
13
+ @output, @exitstatus = output, exitstatus
14
+ end
15
+ end
7
16
 
8
17
  VERSION_TAG_GLOB = 'v[0-9]*.[0-9]*.*[0-9]'
9
18
 
10
19
  DEVNULL = Gem.win_platform? ? "NUL" : "/dev/null"
11
20
 
12
21
  def self.version(use_local_git=false, include_lite_tags=false)
13
- if use_local_git
14
- unless git_available?
15
- raise RuntimeError,
16
- "GVB.version(use_local_git=true) called, but git isn't installed"
17
- end
18
-
19
- sq_git_dir = shell_quoted_string(Dir.pwd)
20
- else
21
- sq_git_dir = shell_quoted_string((File.dirname(caller_file) rescue nil || Dir.pwd))
22
- end
22
+ git_cmd = ["git", "-C", git_dir(use_local_git), "describe", "--dirty=.1.dirty.#{Time.now.strftime("%Y%m%d.%H%M%S")}", "--match=#{VERSION_TAG_GLOB}"]
23
+ git_cmd << "--tags" if include_lite_tags
23
24
 
24
- git_cmd = "git -C #{sq_git_dir} describe --dirty='.1.dirty.#{Time.now.strftime("%Y%m%d.%H%M%S")}' --match='#{VERSION_TAG_GLOB}'"
25
- git_cmd << " --tags" if include_lite_tags
26
-
27
- git_ver = `#{git_cmd} 2> #{DEVNULL}`.
28
- strip.
29
- gsub(/^v/, '').
30
- gsub('-', '.')
31
-
32
- # If git returned success, then it gave us a described version.
33
- # Success!
34
- return git_ver if $? == 0
35
-
36
- # git failed us; we're either not in a git repo or else we've never
37
- # tagged anything before.
38
-
39
- # Are we in a git repo with no tags? If so, try to use the gemspec
40
- # and if that fails then abort
41
25
  begin
42
- return gem_version(use_local_git)
43
- rescue VersionUnobtainable
44
- return "0.0.0.1.ENOTAG"
26
+ run_command(git_cmd, "getting current version descriptor").
27
+ strip.
28
+ gsub(/^v/, '').
29
+ gsub('-', '.')
30
+ rescue CommandFailure
31
+ # git failed us; we're either not in a git repo or else we've never
32
+ # tagged anything before.
33
+
34
+ # Are we in a git repo with no tags? If so, try to use the gemspec
35
+ # and if that fails then abort
36
+ begin
37
+ gem_version(use_local_git)
38
+ rescue VersionUnobtainable
39
+ "0.0.0.1.ENOTAG"
40
+ end
45
41
  end
46
42
  end
47
43
 
@@ -86,56 +82,47 @@ module GitVersionBump
86
82
  end
87
83
 
88
84
  def self.date(use_local_git=false)
89
- if use_local_git
90
- unless git_available?
91
- raise RuntimeError,
92
- "GVB.date(use_local_git=true), but git is not installed"
93
- end
94
-
95
- sq_git_dir = shell_quoted_string(Dir.pwd)
96
- else
97
- sq_git_dir = shell_quoted_string((File.dirname(caller_file) rescue nil || Dir.pwd))
98
- end
99
-
100
85
  # Are we in a git tree?
101
- system("git -C #{sq_git_dir} status > #{DEVNULL} 2>&1")
102
- if $? == 0
103
- # Yes, we're in git.
86
+ begin
87
+ try_command(["git", "-C", git_dir(use_local_git), "status"])
104
88
 
105
- if dirty_tree?(sq_git_dir)
106
- return Time.now.strftime("%F")
89
+ if dirty_tree?(git_dir(use_local_git))
90
+ Time.now.strftime("%F")
107
91
  else
108
92
  # Clean tree. Date of last commit is needed.
109
- return (`git -C #{sq_git_dir} show --no-show-signature --format=format:%cd --date=short`.lines.first || "").strip
93
+ (run_command(["git", "-C", git_dir(use_local_git), "show", "--no-show-signature", "--format=format:%cd", "--date=short"], "getting date of last commit").lines.first || "").strip
110
94
  end
111
- else
95
+ rescue CommandFailure
96
+ # Presumably not in a git tree
112
97
  if use_local_git
113
98
  raise RuntimeError,
114
99
  "GVB.date(use_local_git=true) called from non-git location"
115
100
  end
116
101
 
117
- # Not in git; time to hit the gemspecs
118
102
  if spec = caller_gemspec
119
- return spec.date.strftime("%F")
103
+ spec.date.strftime("%F")
104
+ else
105
+ raise RuntimeError,
106
+ "GVB.date called from mysterious, non-gem location."
120
107
  end
121
-
122
- raise RuntimeError,
123
- "GVB.date called from mysterious, non-gem location."
124
108
  end
125
109
  end
126
110
 
127
111
  def self.tag_version(v, release_notes = false, include_lite_tags=false)
128
112
  if dirty_tree?
129
113
  puts "You have uncommitted files. Refusing to tag a dirty tree."
130
- else
131
- if release_notes
114
+ return false
115
+ end
116
+ if release_notes
117
+ log_file = Tempfile.new('gvb')
118
+
119
+ begin
132
120
  # We need to find the tag before this one, so we can list all the commits
133
121
  # between the two. This is not a trivial operation.
134
- git_cmd = "git describe --match='#{VERSION_TAG_GLOB}' --always"
135
- git_cmd << ' --tags' if include_lite_tags
136
- prev_tag = `#{git_cmd}`.strip.gsub(/-\d+-g[0-9a-f]+$/, '')
122
+ git_cmd = ["git", "describe", "--match=#{VERSION_TAG_GLOB}", "--always"]
123
+ git_cmd << "--tags" if include_lite_tags
137
124
 
138
- log_file = Tempfile.new('gvb')
125
+ prev_tag = run_command(git_cmd, "getting previous release tag").strip.gsub(/-\d+-g[0-9a-f]+$/, '')
139
126
 
140
127
  log_file.puts <<-EOF.gsub(/^\t\t\t\t\t/, '')
141
128
 
@@ -146,29 +133,30 @@ module GitVersionBump
146
133
  # are listed below. This will become v#{v}
147
134
  #
148
135
  EOF
136
+ log_file.puts run_command(["git", "log", "--no-show-signature", "--format=# %h %s", "#{prev_tag}..HEAD"], "getting commit range of release")
149
137
 
150
138
  log_file.close
151
- system("git log --no-show-signature --format='# %h %s' #{prev_tag}..HEAD >>#{log_file.path}")
152
139
 
153
140
  pre_hash = Digest::SHA1.hexdigest(File.read(log_file.path))
154
- system("git config -e -f #{log_file.path}")
141
+ run_command(["git", "config", "-e", "-f", log_file.path], "editing release notes")
155
142
  if Digest::SHA1.hexdigest(File.read(log_file.path)) == pre_hash
156
- puts "Release notes not edited; aborting"
143
+ puts "Release notes not edited; not making release"
157
144
  log_file.unlink
158
145
  return
159
146
  end
160
147
 
161
148
  puts "Tagging version #{v}..."
162
- system("git tag -a -F #{log_file.path} v#{v}")
149
+ run_command(["git", "tag", "-a", "-F", log_file.path, "v#{v}"], "tagging release with annotations")
150
+ ensure
163
151
  log_file.unlink
164
- else
165
- # Crikey this is a lot simpler
166
- system("git tag -a -m 'Version v#{v}' v#{v}")
167
152
  end
168
-
169
- system("git push > #{DEVNULL} 2>&1")
170
- system("git push --tags > #{DEVNULL} 2>&1")
153
+ else
154
+ # Crikey this is a lot simpler
155
+ run_command(["git", "tag", "-a", "-m", "Version v#{v}", "v#{v}"], "tagging release")
171
156
  end
157
+
158
+ run_command(["git", "push"], "pushing commits to the default remote repository")
159
+ run_command(["git", "push", "--tags"], "pushing tags to the default remote repository")
172
160
  end
173
161
 
174
162
  # Calculate a version number based on the date of the most recent git commit.
@@ -199,18 +187,7 @@ module GitVersionBump
199
187
  # make builds off a branch, basically.
200
188
  #
201
189
  def self.commit_date_version(use_local_git = false)
202
- if use_local_git
203
- unless git_available?
204
- raise RuntimeError,
205
- "GVB.commit_date_version(use_local_git=true) called, but git isn't installed"
206
- end
207
-
208
- sq_git_dir = shell_quoted_string(Dir.pwd)
209
- else
210
- sq_git_dir = shell_quoted_string((File.dirname(caller_file) rescue nil || Dir.pwd))
211
- end
212
-
213
- commit_dates = `git -C #{sq_git_dir} log --no-show-signature --format=%at`.
190
+ commit_dates = run_command(["git", "-C", git_dir(use_local_git), "log", "--no-show-signature", "--format=%at"], "getting dates of all commits").
214
191
  split("\n").
215
192
  map { |l| Time.at(Integer(l)).strftime("%Y%m%d") }
216
193
 
@@ -242,14 +219,50 @@ module GitVersionBump
242
219
  private
243
220
 
244
221
  def self.git_available?
245
- system("git --version > #{DEVNULL} 2>&1")
246
-
247
- $? == 0
222
+ try_command(["git", "--version"])
248
223
  end
249
224
 
250
- def self.dirty_tree?(sq_git_dir='.')
225
+ def self.dirty_tree?(dir='.')
251
226
  # Are we in a dirty, dirty tree?
252
- ! `git -C #{sq_git_dir} status --porcelain 2> #{DEVNULL}`.empty?
227
+ ! run_command(["git", "-C", dir, "status", "--porcelain"], "checking for tree cleanliness").empty?
228
+ end
229
+
230
+ # Execute a command, specified as an array.
231
+ #
232
+ # On success, the full output of the command (stdout+stderr, interleaved) is returned.
233
+ # On error, a `CommandFailure` exception is raised.
234
+ #
235
+ def self.run_command(cmd, desc)
236
+ unless cmd.is_a?(Array)
237
+ raise ArgumentError, "Must pass command line arguments in an array"
238
+ end
239
+
240
+ unless cmd.all? { |s| s.is_a?(String) }
241
+ raise ArgumentError, "Command line arguments must be strings"
242
+ end
243
+
244
+ if debug?
245
+ p :GVB_CMD, desc, cmd
246
+ end
247
+
248
+ out, status = Open3.capture2e(*cmd)
249
+
250
+ if status.exitstatus != 0
251
+ raise CommandFailure.new("Failed while #{desc}", out, status.exitstatus)
252
+ else
253
+ out
254
+ end
255
+ end
256
+
257
+ # Execute a command, and return whether it succeeded or failed.
258
+ #
259
+ def self.try_command(cmd)
260
+ begin
261
+ run_command(cmd, "try_command")
262
+ true
263
+ rescue CommandFailure
264
+ false
265
+ end
253
266
  end
254
267
 
255
268
  def self.caller_file
@@ -260,6 +273,7 @@ module GitVersionBump
260
273
  Pathname(
261
274
  caller_locations.
262
275
  map(&:path).
276
+ tap { |c| p :CALLER_LOCATIONS, c if debug? }.
263
277
  find { |l| l != __FILE__ }
264
278
  ).realpath.to_s rescue nil
265
279
  end
@@ -319,17 +333,23 @@ module GitVersionBump
319
333
  end
320
334
  end
321
335
 
322
- def self.shell_quoted_string(dir_string)
323
- if Gem.win_platform?
324
- return "\"#{dir_string}\""
336
+ def self.git_dir(use_local_git = false)
337
+ if use_local_git
338
+ unless git_available?
339
+ raise RuntimeError,
340
+ "Cannot use git-version-bump with use_local_git, as git is not installed"
341
+ end
342
+
343
+ Dir.pwd
325
344
  else
326
- # Shell Quoted, for your convenience
327
- return "'#{dir_string.gsub("'", "'\\''")}'"
328
- end
345
+ File.dirname(caller_file) rescue nil || Dir.pwd
346
+ end.tap { |d| p :GVB_GIT_DIR, use_local_git, d if debug? }
329
347
  end
348
+ private_class_method :git_dir
330
349
 
331
- private_class_method :shell_quoted_string
332
-
350
+ def self.debug?
351
+ ENV.key?("GVB_DEBUG")
352
+ end
333
353
  end
334
354
 
335
355
  GVB = GitVersionBump unless defined? GVB
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-version-bump
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.2
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Palmer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-01 00:00:00.000000000 Z
11
+ date: 2023-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: github-release
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  requirements: []
105
- rubygems_version: 3.1.6
105
+ rubygems_version: 3.2.5
106
106
  signing_key:
107
107
  specification_version: 4
108
108
  summary: Manage your app version entirely via git tags