semverify 0.3.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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +26 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +36 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +116 -0
- data/Rakefile +85 -0
- data/exe/semverify +6 -0
- data/lib/semverify/command_line.rb +475 -0
- data/lib/semverify/incrementable_semver.rb +190 -0
- data/lib/semverify/regexp.rb +38 -0
- data/lib/semverify/semver.rb +372 -0
- data/lib/semverify/version.rb +6 -0
- data/lib/semverify/version_file.rb +101 -0
- data/lib/semverify/version_file_factory.rb +38 -0
- data/lib/semverify/version_file_sources/base.rb +54 -0
- data/lib/semverify/version_file_sources/gemspec.rb +37 -0
- data/lib/semverify/version_file_sources/version.rb +34 -0
- data/lib/semverify/version_file_sources/version_rb.rb +37 -0
- data/lib/semverify/version_file_sources.rb +11 -0
- data/lib/semverify.rb +18 -0
- data/semverify.gemspec +51 -0
- data/sig/semversion.rbs +4 -0
- metadata +235 -0
@@ -0,0 +1,475 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Semverify
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
7
|
+
|
8
|
+
# The semverify cli
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# require 'semverify'
|
12
|
+
#
|
13
|
+
# Semverify::CommandLine.start(ARGV)
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
class CommandLine < Thor
|
18
|
+
# Tell Thor to exit with a non-zero status code if a command fails
|
19
|
+
def self.exit_on_failure? = true
|
20
|
+
|
21
|
+
desc 'current [-q]', 'Show the current gem version'
|
22
|
+
|
23
|
+
long_desc <<-LONG_DESC
|
24
|
+
Output the current gem version from the file that stores the gem version.
|
25
|
+
|
26
|
+
The command fails if the gem version could not be found or is invalid.
|
27
|
+
|
28
|
+
Use `--quiet` to ensure that a gem version could be found and is valid without producing any output.
|
29
|
+
LONG_DESC
|
30
|
+
|
31
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the current version to stdout'
|
32
|
+
|
33
|
+
# Show the current gem version
|
34
|
+
# @return [void]
|
35
|
+
def current
|
36
|
+
version_file = Semverify::VersionFileFactory.find
|
37
|
+
|
38
|
+
if version_file.nil?
|
39
|
+
warn 'version file not found or is not valid' unless options[:quiet]
|
40
|
+
exit 1
|
41
|
+
end
|
42
|
+
|
43
|
+
puts version_file.version unless options[:quiet]
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'file [-q]', 'Show the path to the file containing the gem version'
|
47
|
+
|
48
|
+
long_desc <<-LONG_DESC
|
49
|
+
Output the relative path to the file that stores the gem version.
|
50
|
+
|
51
|
+
The command fails if the gem version could not be found.
|
52
|
+
|
53
|
+
Use `--quiet` to ensure that a gem version could be found without producing any output.
|
54
|
+
LONG_DESC
|
55
|
+
|
56
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the version file path to stdout'
|
57
|
+
|
58
|
+
# Show the gem's version file
|
59
|
+
# @return [void]
|
60
|
+
def file
|
61
|
+
version_file = Semverify::VersionFileFactory.find
|
62
|
+
|
63
|
+
if version_file.nil?
|
64
|
+
warn 'version file not found or is not valid' unless options[:quiet]
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
|
68
|
+
puts version_file.path unless options[:quiet]
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'next-major [VERSION] [-p [-t TYPE]] [-b BUILD] [-n] [-q]', "Increment the version's major part"
|
72
|
+
|
73
|
+
long_desc <<-LONG_DESC
|
74
|
+
Increase the current gem version to the next major version, update the
|
75
|
+
file that stores the version, and output the resulting version to stdout.
|
76
|
+
|
77
|
+
Increments 1.x.y to 2.0.0.
|
78
|
+
|
79
|
+
The command fails if the current gem version file could not be found or
|
80
|
+
if the version is not valid.
|
81
|
+
|
82
|
+
If VERSION is given, use that instead of the current gem version. Giving
|
83
|
+
VERSION implies --dry-run. The command fails if VERSION is not valid.
|
84
|
+
|
85
|
+
--pre can be used to specify that the version should be incremented AND
|
86
|
+
given a pre-release part. For instance:
|
87
|
+
|
88
|
+
/x5 $ semverify next-major --pre
|
89
|
+
|
90
|
+
increments '1.2.3' to '2.0.0-pre.1'.
|
91
|
+
|
92
|
+
By default, the pre-release type is 'pre'. --pre-type=TYPE can be used with
|
93
|
+
--pre to specify a different pre-release type such as alpha, beta, rc, etc.
|
94
|
+
For instance:
|
95
|
+
|
96
|
+
/x5 $ semverify next-major --pre --pre-type=alpha
|
97
|
+
|
98
|
+
increments '1.2.3' to '2.0.0-alpha.1'.
|
99
|
+
|
100
|
+
The command fails if the existing pre-release type is not lexically less than or
|
101
|
+
equal to TYPE. For example, it the current version is '1.2.3-beta.1' and TYPE
|
102
|
+
is 'alpha', the the command will fail since the new version would sort before the
|
103
|
+
existing version ('beta' is not less than or equal to 'alpha').
|
104
|
+
|
105
|
+
Use --build=BUILD to set the build metadata for the new version (See
|
106
|
+
[Build Metadata in the Semantic Versioning Specification](https://semver.org/spec/v2.0.0.html#spec-item-10)).
|
107
|
+
If --build is not given, the incremented version retain the previous build
|
108
|
+
metadata. Pass an empty string to remove the build metadata (--build="")
|
109
|
+
|
110
|
+
Use --dry-run to run this command without updating the version file.
|
111
|
+
|
112
|
+
Use --quiet to increment the version without producing any output.
|
113
|
+
LONG_DESC
|
114
|
+
|
115
|
+
option :pre, type: :boolean, aliases: '-p', desc: 'Create a pre-release version'
|
116
|
+
option :'pre-type', type: :string, aliases: '-t', default: 'pre', banner: 'TYPE',
|
117
|
+
desc: 'The type of pre-release version (alpha, beta, etc.)'
|
118
|
+
option :build, type: :string, aliases: '-b', desc: 'The build metadata to add to the version'
|
119
|
+
option :'dry-run', type: :boolean, aliases: '-n', desc: 'Do not write the new version to the version file'
|
120
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the new version to stdout'
|
121
|
+
|
122
|
+
# Increment the gem version's major part
|
123
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
124
|
+
# from the gem's version file
|
125
|
+
# @return [void]
|
126
|
+
def next_major(version = nil)
|
127
|
+
increment_core_version(:next_major, version)
|
128
|
+
end
|
129
|
+
|
130
|
+
desc 'next-minor [VERSION] [-p [-t TYPE]] [-b BUILD] [-n] [-q]', "Increment the version's minor part"
|
131
|
+
|
132
|
+
long_desc <<-LONG_DESC
|
133
|
+
Increase the current gem version to the next minor version, update the
|
134
|
+
file that stores the version, and output the resulting version to stdout.
|
135
|
+
|
136
|
+
Increments 1.2.y to 1.3.0.
|
137
|
+
|
138
|
+
The command fails if the current gem version file could not be found or
|
139
|
+
if the version is not valid.
|
140
|
+
|
141
|
+
If VERSION is given, use that instead of the current gem version. Giving
|
142
|
+
VERSION implies --dry-run. The command fails if VERSION is not valid.
|
143
|
+
|
144
|
+
--pre can be used to specify that the version should be incremented AND
|
145
|
+
given a pre-release part. For instance:
|
146
|
+
|
147
|
+
/x5 $ semverify next-minor --pre
|
148
|
+
|
149
|
+
increments '1.2.3' to '2.0.0-pre.1'.
|
150
|
+
|
151
|
+
By default, the pre-release type is 'pre'. --pre-type=TYPE can be used with
|
152
|
+
--pre to specify a different pre-release type such as alpha, beta, rc, etc.
|
153
|
+
For instance:
|
154
|
+
|
155
|
+
/x5 $ semverify next-patch --pre --pre-type=alpha
|
156
|
+
|
157
|
+
increments '1.2.3' to '1.2.4-alpha.1'.
|
158
|
+
|
159
|
+
The command fails if the existing pre-release type is not lexically less than or
|
160
|
+
equal to TYPE. For example, it the current version is '1.2.3-beta.1' and TYPE
|
161
|
+
is 'alpha', the the command will fail since the new version would sort before the
|
162
|
+
existing version ('beta' is not less than or equal to 'alpha').
|
163
|
+
|
164
|
+
Use --build=BUILD to set the build metadata for the new version (See
|
165
|
+
[Build Metadata in the Semantic Versioning Specification](https://semver.org/spec/v2.0.0.html#spec-item-10)).
|
166
|
+
If --build is not given, the incremented version retain the previous build
|
167
|
+
metadata. Pass an empty string to remove the build metadata (--build="")
|
168
|
+
|
169
|
+
Use --dry-run to run this command without updating the version file.
|
170
|
+
|
171
|
+
Use --quiet to increment the version without producing any output.
|
172
|
+
LONG_DESC
|
173
|
+
|
174
|
+
option :pre, type: :boolean, aliases: '-p', desc: 'Create a pre-release version'
|
175
|
+
option :'pre-type', type: :string, aliases: '-t', default: 'pre', banner: 'TYPE',
|
176
|
+
desc: 'The type of pre-release version (alpha, beta, etc.)'
|
177
|
+
option :build, type: :string, aliases: '-b', desc: 'The build metadata to add to the version'
|
178
|
+
option :'dry-run', type: :boolean, aliases: '-n', desc: 'Do not write the new version to the version file'
|
179
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the new version to stdout'
|
180
|
+
|
181
|
+
# Increment the gem version's minor part
|
182
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
183
|
+
# from the gem's version file
|
184
|
+
# @return [void]
|
185
|
+
def next_minor(version = nil)
|
186
|
+
increment_core_version(:next_minor, version)
|
187
|
+
end
|
188
|
+
|
189
|
+
desc 'next-patch [VERSION] [-p [-t TYPE]] [-b BUILD] [-n] [-q]', "Increment the version's patch part"
|
190
|
+
|
191
|
+
long_desc <<-LONG_DESC
|
192
|
+
Increase the current gem version to the next patch version, update the
|
193
|
+
file that stores the version, and output the resulting version to stdout.
|
194
|
+
|
195
|
+
Increments 1.2.3 to 1.2.4.
|
196
|
+
|
197
|
+
The command fails if the current gem version file could not be found or
|
198
|
+
if the version is not valid.
|
199
|
+
|
200
|
+
If VERSION is given, use that instead of the current gem version. Giving
|
201
|
+
VERSION implies --dry-run. The command fails if VERSION is not valid.
|
202
|
+
|
203
|
+
--pre can be used to specify that the version should be incremented AND
|
204
|
+
given a pre-release part. For instance:
|
205
|
+
|
206
|
+
/x5 $ semverify next-patch --pre
|
207
|
+
|
208
|
+
increments '1.2.3' to '1.2.4-pre.1'.
|
209
|
+
|
210
|
+
By default, the pre-release type is 'pre'. --pre-type=TYPE can be used with
|
211
|
+
--pre to specify a different pre-release type such as alpha, beta, rc, etc.
|
212
|
+
For instance:
|
213
|
+
|
214
|
+
/x5 $ semverify next-patch --pre --pre-type=alpha
|
215
|
+
|
216
|
+
increments '1.2.3' to '1.2.4-alpha.1'.
|
217
|
+
|
218
|
+
The command fails if the existing pre-release type is not lexically less than or
|
219
|
+
equal to TYPE. For example, it the current version is '1.2.3-beta.1' and TYPE
|
220
|
+
is 'alpha', the the command will fail since the new version would sort before the
|
221
|
+
existing version ('beta' is not less than or equal to 'alpha').
|
222
|
+
|
223
|
+
Use --build=BUILD to set the build metadata for the new version (See
|
224
|
+
[Build Metadata in the Semantic Versioning Specification](https://semver.org/spec/v2.0.0.html#spec-item-10)).
|
225
|
+
If --build is not given, the incremented version retain the previous build
|
226
|
+
metadata. Pass an empty string to remove the build metadata (--build="")
|
227
|
+
|
228
|
+
Use --dry-run to run this command without updating the version file.
|
229
|
+
|
230
|
+
Use --quiet to increment the version without producing any output.
|
231
|
+
LONG_DESC
|
232
|
+
|
233
|
+
option :pre, type: :boolean, aliases: '-p', desc: 'Create a pre-release version'
|
234
|
+
option :'pre-type', type: :string, aliases: '-t', default: 'pre', banner: 'TYPE',
|
235
|
+
desc: 'The type of pre-release version (alpha, beta, etc.)'
|
236
|
+
option :build, type: :string, aliases: '-b', desc: 'The build metadata to add to the version'
|
237
|
+
option :'dry-run', type: :boolean, aliases: '-n', desc: 'Do not write the new version to the version file'
|
238
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the new version to stdout'
|
239
|
+
|
240
|
+
# Increment the gem version's patch part
|
241
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
242
|
+
# from the gem's version file
|
243
|
+
# @return [void]
|
244
|
+
def next_patch(version = nil)
|
245
|
+
increment_core_version(:next_patch, version)
|
246
|
+
end
|
247
|
+
|
248
|
+
desc 'next-pre [VERSION] [-t TYPE] [-b BUILD] [-n] [-q]', "Increment the version's pre-release part"
|
249
|
+
|
250
|
+
long_desc <<-LONG_DESC
|
251
|
+
Increase the current gem version to the next pre-release version, update the
|
252
|
+
file that stores the version, and output the resulting version to stdout.
|
253
|
+
|
254
|
+
The command fails if the current gem version file could not be found or
|
255
|
+
the version is not a valid pre-release version.
|
256
|
+
|
257
|
+
If VERSION is given, use that instead of the current gem version. Giving
|
258
|
+
VERSION implies --dry-run. The command fails if VERSION is not a valid
|
259
|
+
pre-release version.
|
260
|
+
|
261
|
+
By default, the existing pre-release type is preserved. For instance:
|
262
|
+
|
263
|
+
/x5 $ semverify next-pre
|
264
|
+
|
265
|
+
Increments 1.2.3-alpha.1 to 1.2.3-alpha.2.
|
266
|
+
|
267
|
+
--pre-type=TYPE can be used to change the pre-release type to TYPE (typical
|
268
|
+
examples include alpha, beta, rc, etc.). If the pre-release type is changed,
|
269
|
+
the pre-release number is reset to 1.
|
270
|
+
|
271
|
+
For example, if the version starts as 1.2.3-alpha.4, then:
|
272
|
+
|
273
|
+
/x5 $ semverify current
|
274
|
+
/x5 1.2.3-alpha.4
|
275
|
+
/x5 $ semver next-pre --pre-type=beta
|
276
|
+
/x5 1.2.3-beta.1
|
277
|
+
/x5 $ semver next-pre --pre-type=beta
|
278
|
+
/x5 1.2.3-beta.2
|
279
|
+
/x5 $ semver next-pre --pre-type=rc
|
280
|
+
/x5 1.2.3-rc.1
|
281
|
+
/x5 $ semverify next-release
|
282
|
+
/x5 1.2.3
|
283
|
+
|
284
|
+
The command fails if the existing pre-release type is not lexically less than or
|
285
|
+
equal to TYPE. For example, it the current version is '1.2.3-beta.1' and the TYPE
|
286
|
+
given type is 'alpha', then the command will fail since the new version would sort
|
287
|
+
before the existing version (since 'beta' is not <= 'alpha').
|
288
|
+
|
289
|
+
Use --build=BUILD to set the build metadata for the new version (See
|
290
|
+
[Build Metadata in the Semantic Versioning Specification](https://semver.org/spec/v2.0.0.html#spec-item-10)).
|
291
|
+
If --build is not given, the incremented version retain the previous build
|
292
|
+
metadata. Pass an empty string to remove the build metadata (--build="")
|
293
|
+
|
294
|
+
Use --dry-run to run this command without updating the version file.
|
295
|
+
|
296
|
+
Use --quiet to increment the version without producing any output.
|
297
|
+
LONG_DESC
|
298
|
+
|
299
|
+
option :'pre-type', type: :string, aliases: '-t', banner: 'TYPE',
|
300
|
+
desc: 'The type of pre-release version (alpha, beta, etc.)'
|
301
|
+
option :build, type: :string, aliases: '-b', desc: 'The build metadata to add to the version'
|
302
|
+
option :'dry-run', type: :boolean, aliases: '-n', desc: 'Do not write the new version to the version file'
|
303
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the new version to stdout'
|
304
|
+
|
305
|
+
# Increment the gem version's pre-release part
|
306
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
307
|
+
# from the gem's version file
|
308
|
+
# @return [void]
|
309
|
+
def next_pre(version = nil)
|
310
|
+
args = {}
|
311
|
+
args[:pre_type] = options[:'pre-type'] if options[:'pre-type']
|
312
|
+
args[:build_metadata] = options[:build] if options[:build]
|
313
|
+
|
314
|
+
new_version = increment_version(:next_pre, args, version)
|
315
|
+
|
316
|
+
puts new_version unless options[:quiet]
|
317
|
+
end
|
318
|
+
|
319
|
+
desc 'next-release [VERSION] [-b BUILD] [-n] [-q]', 'Increment a pre-release version to the release version'
|
320
|
+
|
321
|
+
long_desc <<-LONG_DESC
|
322
|
+
Increase the current gem version to the next release version, update the
|
323
|
+
file that stores the version, and output the resulting version to stdout.
|
324
|
+
|
325
|
+
Increments 1.2.3-rc.4 to 1.2.3.
|
326
|
+
|
327
|
+
The command fails if the current gem version file could not be found or
|
328
|
+
the version is not a valid pre-release version.
|
329
|
+
|
330
|
+
If VERSION is given, use that instead of the current gem version. Giving
|
331
|
+
VERSION implies --dry-run. The command fails if VERSION is not a valid
|
332
|
+
pre-release version.
|
333
|
+
|
334
|
+
Use --build=BUILD to set the build metadata for the new version (See
|
335
|
+
[Build Metadata in the Semantic Versioning Specification](https://semver.org/spec/v2.0.0.html#spec-item-10)).
|
336
|
+
If --build is not given, the incremented version retain the previous build
|
337
|
+
metadata. Pass an empty string to remove the build metadata (--build="")
|
338
|
+
|
339
|
+
Use --dry-run to run this command without updating the version file.
|
340
|
+
|
341
|
+
Use --quiet to increment the version without producing any output.
|
342
|
+
LONG_DESC
|
343
|
+
|
344
|
+
option :build, type: :string, aliases: '-b', desc: 'The build metadata to add to the version'
|
345
|
+
option :'dry-run', type: :boolean, aliases: '-n', desc: 'Do not write the new version to the version file'
|
346
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the new version to stdout'
|
347
|
+
|
348
|
+
# Increment the gem's pre-release version to a release version
|
349
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
350
|
+
# from the gem's version file
|
351
|
+
# @return [void]
|
352
|
+
def next_release(version = nil)
|
353
|
+
args = {}
|
354
|
+
args[:build_metadata] = options[:build] if options[:build]
|
355
|
+
|
356
|
+
new_version = increment_version(:next_release, args, version)
|
357
|
+
|
358
|
+
puts new_version unless options[:quiet]
|
359
|
+
end
|
360
|
+
|
361
|
+
desc 'validate VERSION [-q]', 'Validate the given version'
|
362
|
+
|
363
|
+
long_desc <<-LONG_DESC
|
364
|
+
Validate and output the given gem version.
|
365
|
+
|
366
|
+
The command fails if the gem version is not valid.
|
367
|
+
|
368
|
+
Use `--quiet` to validate the gem version without producing any output.
|
369
|
+
LONG_DESC
|
370
|
+
|
371
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Do not print the given version to stdout'
|
372
|
+
|
373
|
+
# Validate that the give version is a valid IncrementableSemver version
|
374
|
+
# @param version [String] The version to validate
|
375
|
+
# @return [void]
|
376
|
+
#
|
377
|
+
def validate(version)
|
378
|
+
Semverify::IncrementableSemver.new(version)
|
379
|
+
rescue Semverify::Error => e
|
380
|
+
warn e.message unless options[:quiet]
|
381
|
+
exit 1
|
382
|
+
else
|
383
|
+
puts version unless options[:quiet]
|
384
|
+
end
|
385
|
+
|
386
|
+
private
|
387
|
+
|
388
|
+
# Build a hash of arguments to pass to the IncrementableSemver methods
|
389
|
+
#
|
390
|
+
# These arguments are specificly for the #next_major, #next_minor, and
|
391
|
+
# #next_patch method.
|
392
|
+
#
|
393
|
+
# @return [Hash]
|
394
|
+
#
|
395
|
+
def core_args
|
396
|
+
{}.tap do |args|
|
397
|
+
args[:pre] = options[:pre] if options[:pre]
|
398
|
+
args[:pre_type] = options[:'pre-type'] if options[:'pre-type']
|
399
|
+
args[:build_metadata] = options[:build] if options[:build]
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
# Increment the gem's major, minor, or patch version
|
404
|
+
#
|
405
|
+
# @param method [Symbol] The method to call on the IncrementableSemver object
|
406
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
407
|
+
# from the gem's version file
|
408
|
+
#
|
409
|
+
# @return [Void]
|
410
|
+
#
|
411
|
+
def increment_core_version(method, version)
|
412
|
+
new_version = increment_version(method, core_args, version)
|
413
|
+
|
414
|
+
puts new_version unless options[:quiet]
|
415
|
+
end
|
416
|
+
|
417
|
+
# Increment the gem's version
|
418
|
+
#
|
419
|
+
# @param method [Symbol] The method to call on the IncrementableSemver object
|
420
|
+
#
|
421
|
+
# The method can bee one of: :next_major, :next_minor, :next_patch, :next_pre, :next_release
|
422
|
+
#
|
423
|
+
# @param args [Hash] The arguments to pass to the method
|
424
|
+
#
|
425
|
+
# @param version [String, nil] The version to increment or nil to use the version
|
426
|
+
#
|
427
|
+
# @return [Void]
|
428
|
+
#
|
429
|
+
def increment_version(method, args, version)
|
430
|
+
if version
|
431
|
+
increment_literal_version(method, args, version)
|
432
|
+
else
|
433
|
+
increment_gem_version(method, args)
|
434
|
+
end
|
435
|
+
rescue Semverify::Error => e
|
436
|
+
warn e.message unless options[:quiet]
|
437
|
+
exit 1
|
438
|
+
end
|
439
|
+
|
440
|
+
# Increment a literal version from a string
|
441
|
+
#
|
442
|
+
# @param method [Symbol] The method to call on the IncrementableSemver object
|
443
|
+
# @param args [Hash] The arguments to pass to the method
|
444
|
+
# @param version [String] The version to increment
|
445
|
+
#
|
446
|
+
# @return [Semverify::IncrementableSemver] the incremented version
|
447
|
+
# @raise [Semverify::Error] if the version is not a valid IncrementableSemver version
|
448
|
+
#
|
449
|
+
def increment_literal_version(method, args, version)
|
450
|
+
Semverify::IncrementableSemver.new(version).send(method, **args)
|
451
|
+
end
|
452
|
+
|
453
|
+
# Increment the gem's version from the gem's version file
|
454
|
+
#
|
455
|
+
# @param method [Symbol] The method to call on the IncrementableSemver object
|
456
|
+
# @param args [Hash] The arguments to pass to the method
|
457
|
+
#
|
458
|
+
# @return [Semverify::IncrementableSemver] the incremented version
|
459
|
+
# @raise [Semverify::Error] if the version is not a valid IncrementableSemver version
|
460
|
+
#
|
461
|
+
def increment_gem_version(method, args)
|
462
|
+
version_file = Semverify::VersionFileFactory.find
|
463
|
+
|
464
|
+
if version_file.nil?
|
465
|
+
warn 'version file not found or is not valid' unless options[:quiet]
|
466
|
+
exit 1
|
467
|
+
end
|
468
|
+
|
469
|
+
version_file&.version.send(method, **args).tap do |new_version|
|
470
|
+
version_file.version = new_version unless options[:'dry-run']
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
# rubocop:enable Metrics/ClassLength
|
475
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'semverify/semver'
|
4
|
+
|
5
|
+
module Semverify
|
6
|
+
# A Semverify::Semver with additional constraints on the pre-release part of the version
|
7
|
+
#
|
8
|
+
# A IncrementableSemver is valid if one of the two following conditions is met:
|
9
|
+
# 1. The pre-release part is empty
|
10
|
+
# 2. The pre-release part is composed of two dot-separated identifiers:
|
11
|
+
# * the first being a String representing the pre-release type (e.g. 'alpha',
|
12
|
+
# 'beta', etc.). The default pre-release type is 'pre'
|
13
|
+
# * the second being an Integer representing the pre-release sequence number
|
14
|
+
# (starting at 1)
|
15
|
+
#
|
16
|
+
# Valid versions with pre-release parts: `1.2.3-alpha.1`, `1.2.3-beta.2`, `1.2.3-pre.3`
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
#
|
20
|
+
class IncrementableSemver < Semver
|
21
|
+
# Create a new IncrementableSemver object
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# Semverify::Semver.new('1.2.3').valid? # => true
|
25
|
+
# Semverify::Semver.new('1.2.3-alpha.1+build.001').valid? # => true
|
26
|
+
# Semverify::Semver.new('1.2.3-alpha').valid? # => raise Semverify::Error
|
27
|
+
# Semverify::Semver.new('1.2.3-alpha.1.2').valid? # => raise Semverify::Error
|
28
|
+
# Semverify::Semver.new('1.2.3-alpha.one').valid? # => raise Semverify::Error
|
29
|
+
#
|
30
|
+
# @return [Boolean] true if the version string is a valid semver and meets the conditions above
|
31
|
+
#
|
32
|
+
def valid?
|
33
|
+
super && (
|
34
|
+
pre_release.empty? ||
|
35
|
+
(
|
36
|
+
pre_release_identifiers.size == 2 &&
|
37
|
+
pre_type.is_a?(String) &&
|
38
|
+
pre_number.is_a?(Integer)
|
39
|
+
)
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
# The default pre-release identifier
|
44
|
+
DEFAULT_PRE_TYPE = 'pre'
|
45
|
+
|
46
|
+
# Increment the major version
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# IncrementableSemverify::Semver.new('1.2.3').next_major # => IncrementableSemverify::Semver.new('2.0.0')
|
50
|
+
#
|
51
|
+
# @return [IncrementableSemver] a new IncrementableSemver object with the major version incremented
|
52
|
+
#
|
53
|
+
def next_major(pre: false, pre_type: DEFAULT_PRE_TYPE, build_metadata: nil)
|
54
|
+
version_string = "#{major.to_i + 1}.0.0"
|
55
|
+
version_string += "-#{pre_type}.1" if pre
|
56
|
+
build_metadata = self.build_metadata if build_metadata.nil?
|
57
|
+
version_string += "+#{build_metadata}" unless build_metadata.empty?
|
58
|
+
IncrementableSemver.new(version_string)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Increment the minor version
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# IncrementableSemverify::Semver.new('1.2.3').next_minor # => IncrementableSemverify::Semver.new('1.3.0')
|
65
|
+
#
|
66
|
+
# @return [IncrementableSemver] a new IncrementableSemver object with the major version incremented
|
67
|
+
#
|
68
|
+
def next_minor(pre: false, pre_type: DEFAULT_PRE_TYPE, build_metadata: nil)
|
69
|
+
version_string = "#{major}.#{minor.to_i + 1}.0"
|
70
|
+
version_string += "-#{pre_type}.1" if pre
|
71
|
+
build_metadata = self.build_metadata if build_metadata.nil?
|
72
|
+
version_string += "+#{build_metadata}" unless build_metadata.empty?
|
73
|
+
IncrementableSemver.new(version_string)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Increment the patch version
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# IncrementableSemverify::Semver.new('1.2.3').next_patch # => IncrementableSemverify::Semver.new('1.2.1')
|
80
|
+
#
|
81
|
+
# @return [IncrementableSemver] a new IncrementableSemver object with the patch part incremented
|
82
|
+
#
|
83
|
+
def next_patch(pre: false, pre_type: DEFAULT_PRE_TYPE, build_metadata: nil)
|
84
|
+
version_string = "#{major}.#{minor}.#{patch.to_i + 1}"
|
85
|
+
version_string += "-#{pre_type}.1" if pre
|
86
|
+
build_metadata = self.build_metadata if build_metadata.nil?
|
87
|
+
version_string += "+#{build_metadata}" unless build_metadata.empty?
|
88
|
+
IncrementableSemver.new(version_string)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Increment the pre_release part of the version
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# IncrementableSemverify::Semver.new('1.2.3-pre.1').next_patch.to_s # => '1.2.3-pre.2'
|
95
|
+
#
|
96
|
+
# @return [IncrementableSemver] a new IncrementableSemver object with the pre_release part incremented
|
97
|
+
#
|
98
|
+
def next_pre(pre_type: nil, build_metadata: nil)
|
99
|
+
assert_is_a_pre_release_version
|
100
|
+
version_string = "#{major}.#{minor}.#{patch}"
|
101
|
+
version_string += next_pre_part(pre_type)
|
102
|
+
build_metadata ||= self.build_metadata
|
103
|
+
version_string += "+#{build_metadata}" unless build_metadata.empty?
|
104
|
+
IncrementableSemver.new(version_string)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Drop the pre-release part of the version
|
108
|
+
#
|
109
|
+
# @example
|
110
|
+
# IncrementableSemverify::Semver.new('1.2.3-pre.1').next_release.to_s # => '1.2.3'
|
111
|
+
#
|
112
|
+
# @return [IncrementableSemver] a new IncrementableSemver object with the pre_release part dropped
|
113
|
+
# @raise [Semverify::Error] if the version is not a pre-release version
|
114
|
+
#
|
115
|
+
def next_release(build_metadata: nil)
|
116
|
+
assert_is_a_pre_release_version
|
117
|
+
version_string = "#{major}.#{minor}.#{patch}"
|
118
|
+
build_metadata ||= self.build_metadata
|
119
|
+
version_string += "+#{build_metadata}" unless build_metadata.empty?
|
120
|
+
IncrementableSemver.new(version_string)
|
121
|
+
end
|
122
|
+
|
123
|
+
# The pre-release type (for example, 'alpha', 'beta', 'pre', etc.)
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# IncrementableSemverify::Semver.new('1.2.3-pre.1').pre_type # => 'pre'
|
127
|
+
#
|
128
|
+
# @return [String]
|
129
|
+
#
|
130
|
+
def pre_type
|
131
|
+
pre_release_identifiers[0]
|
132
|
+
end
|
133
|
+
|
134
|
+
# The pre-release sequence number
|
135
|
+
#
|
136
|
+
# The pre-release sequence number starts at 1 for each pre-release type.
|
137
|
+
#
|
138
|
+
# @example
|
139
|
+
# IncrementableSemverify::Semver.new('1.2.3-pre.1').pre_number # => 1
|
140
|
+
#
|
141
|
+
# @return [Integer]
|
142
|
+
#
|
143
|
+
def pre_number
|
144
|
+
pre_release_identifiers[1]
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
# Raise an error if the version is not a pre-release version
|
150
|
+
#
|
151
|
+
# @return [void]
|
152
|
+
# @raise [Semverify::Error] if the version is not a pre-release version
|
153
|
+
# @api private
|
154
|
+
def assert_is_a_pre_release_version
|
155
|
+
return unless pre_release.empty?
|
156
|
+
|
157
|
+
raise Semverify::Error, 'Cannot increment the pre-release part of a release version'
|
158
|
+
end
|
159
|
+
|
160
|
+
# Raise an error if new pre-release type is less than the old pre-release type
|
161
|
+
#
|
162
|
+
# If the new pre-release type is lexically less than the old pre-release type,
|
163
|
+
# then raise an error because the resulting error would sort before the existing
|
164
|
+
# version.
|
165
|
+
#
|
166
|
+
# @return [void]
|
167
|
+
# @raise [Semverify::Error] if the pre-release type is not valid
|
168
|
+
# @api private
|
169
|
+
def assert_pre_type_is_valid(pre_type)
|
170
|
+
return if self.pre_type <= pre_type
|
171
|
+
|
172
|
+
message = 'Cannot increment the pre-release identifier ' \
|
173
|
+
"from '#{self.pre_type}' to '#{pre_type}' " \
|
174
|
+
"because '#{self.pre_type}' is lexically less than '#{pre_type}'"
|
175
|
+
|
176
|
+
raise Semverify::Error, message
|
177
|
+
end
|
178
|
+
|
179
|
+
# Return the next pre-release part
|
180
|
+
# @param pre_type [String, nil] the given pre-release type or nil to use the existing pre-release type
|
181
|
+
# @return [String]
|
182
|
+
# @api private
|
183
|
+
def next_pre_part(pre_type)
|
184
|
+
pre_type ||= self.pre_type
|
185
|
+
assert_pre_type_is_valid(pre_type)
|
186
|
+
next_pre_number = self.pre_type == pre_type ? (pre_number + 1) : 1
|
187
|
+
"-#{pre_type}.#{next_pre_number}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|