git-version-bump 0.17.2 → 0.18.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 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