version_boss 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'version'
4
+
5
+ module VersionBoss
6
+ module Semver
7
+ # A Semver Version with additional constraints on the pre-release part of the version
8
+ #
9
+ # An IncrementableVersion is valid if one of the two following conditions is met:
10
+ # 1. The pre-release part is empty
11
+ # 2. The pre-release part is composed of two dot-separated identifiers:
12
+ # * the first being a String representing the pre-release type (e.g. 'alpha',
13
+ # 'beta', etc.). The default pre-release type is 'pre'
14
+ # * the second being an Integer representing the pre-release sequence number
15
+ # (starting at 1)
16
+ #
17
+ # Valid versions with pre-release parts: `1.2.3-alpha.1`, `1.2.3-beta.2`, `1.2.3-pre.3`
18
+ #
19
+ # @api public
20
+ #
21
+ class IncrementableVersion < Version
22
+ # Create a new IncrementableVersion object
23
+ #
24
+ # @example
25
+ # IncrementableVersion.new('1.2.3').valid? # => true
26
+ # IncrementableVersion.new('1.2.3-alpha.1+build.001').valid? # => true
27
+ # IncrementableVersion.new('1.2.3-alpha').valid? # => raise VersionBoss::Error
28
+ # IncrementableVersion.new('1.2.3-alpha.1.2').valid? # => raise VersionBoss::Error
29
+ # IncrementableVersion.new('1.2.3-alpha.one').valid? # => raise VersionBoss::Error
30
+ #
31
+ # @return [Boolean] true if the version string is a valid semver and meets the conditions above
32
+ #
33
+ def valid?
34
+ super && (
35
+ pre_release.empty? ||
36
+ (
37
+ pre_release_identifiers.size == 2 &&
38
+ pre_type.is_a?(String) &&
39
+ pre_number.is_a?(Integer)
40
+ )
41
+ )
42
+ end
43
+
44
+ # The default pre-release identifier
45
+ DEFAULT_PRE_TYPE = 'pre'
46
+
47
+ # Increment the major version
48
+ #
49
+ # @example
50
+ # IncrementableVersionify::Semver.new('1.2.3').next_major # => IncrementableVersionify::Semver.new('2.0.0')
51
+ #
52
+ # @return [IncrementableVersion] a new IncrementableVersion object with the major version incremented
53
+ #
54
+ def next_major(pre: false, pre_type: DEFAULT_PRE_TYPE, build_metadata: nil)
55
+ version_string = "#{major.to_i + 1}.0.0"
56
+ version_string += "-#{pre_type}.1" if pre
57
+ build_metadata = self.build_metadata if build_metadata.nil?
58
+ version_string += "+#{build_metadata}" unless build_metadata.empty?
59
+ IncrementableVersion.new(version_string)
60
+ end
61
+
62
+ # Increment the minor version
63
+ #
64
+ # @example
65
+ # IncrementableVersionify::Semver.new('1.2.3').next_minor # => IncrementableVersionify::Semver.new('1.3.0')
66
+ #
67
+ # @return [IncrementableVersion] a new IncrementableVersion object with the major version incremented
68
+ #
69
+ def next_minor(pre: false, pre_type: DEFAULT_PRE_TYPE, build_metadata: nil)
70
+ version_string = "#{major}.#{minor.to_i + 1}.0"
71
+ version_string += "-#{pre_type}.1" if pre
72
+ build_metadata = self.build_metadata if build_metadata.nil?
73
+ version_string += "+#{build_metadata}" unless build_metadata.empty?
74
+ IncrementableVersion.new(version_string)
75
+ end
76
+
77
+ # Increment the patch version
78
+ #
79
+ # @example
80
+ # IncrementableVersionify::Semver.new('1.2.3').next_patch # => IncrementableVersionify::Semver.new('1.2.1')
81
+ #
82
+ # @return [IncrementableVersion] a new IncrementableVersion object with the patch part incremented
83
+ #
84
+ def next_patch(pre: false, pre_type: DEFAULT_PRE_TYPE, build_metadata: nil)
85
+ version_string = "#{major}.#{minor}.#{patch.to_i + 1}"
86
+ version_string += "-#{pre_type}.1" if pre
87
+ build_metadata = self.build_metadata if build_metadata.nil?
88
+ version_string += "+#{build_metadata}" unless build_metadata.empty?
89
+ IncrementableVersion.new(version_string)
90
+ end
91
+
92
+ # Increment the pre_release part of the version
93
+ #
94
+ # @example
95
+ # IncrementableVersionify::Semver.new('1.2.3-pre.1').next_patch.to_s # => '1.2.3-pre.2'
96
+ #
97
+ # @return [IncrementableVersion] a new IncrementableVersion object with the pre_release part incremented
98
+ #
99
+ def next_pre(pre_type: nil, build_metadata: nil)
100
+ assert_is_a_pre_release_version
101
+ version_string = "#{major}.#{minor}.#{patch}"
102
+ version_string += next_pre_part(pre_type)
103
+ build_metadata ||= self.build_metadata
104
+ version_string += "+#{build_metadata}" unless build_metadata.empty?
105
+ IncrementableVersion.new(version_string)
106
+ end
107
+
108
+ # Drop the pre-release part of the version
109
+ #
110
+ # @example
111
+ # IncrementableVersionify::Semver.new('1.2.3-pre.1').next_release.to_s # => '1.2.3'
112
+ #
113
+ # @return [IncrementableVersion] a new IncrementableVersion object with the pre_release part dropped
114
+ # @raise [VersionBoss::Error] if the version is not a pre-release version
115
+ #
116
+ def next_release(build_metadata: nil)
117
+ assert_is_a_pre_release_version
118
+ version_string = "#{major}.#{minor}.#{patch}"
119
+ build_metadata ||= self.build_metadata
120
+ version_string += "+#{build_metadata}" unless build_metadata.empty?
121
+ IncrementableVersion.new(version_string)
122
+ end
123
+
124
+ # The pre-release type (for example, 'alpha', 'beta', 'pre', etc.)
125
+ #
126
+ # @example
127
+ # IncrementableVersionify::Semver.new('1.2.3-pre.1').pre_type # => 'pre'
128
+ #
129
+ # @return [String]
130
+ #
131
+ def pre_type
132
+ pre_release_identifiers[0]
133
+ end
134
+
135
+ # The pre-release sequence number
136
+ #
137
+ # The pre-release sequence number starts at 1 for each pre-release type.
138
+ #
139
+ # @example
140
+ # IncrementableVersionify::Semver.new('1.2.3-pre.1').pre_number # => 1
141
+ #
142
+ # @return [Integer]
143
+ #
144
+ def pre_number
145
+ pre_release_identifiers[1]
146
+ end
147
+
148
+ private
149
+
150
+ # Raise an error if the version is not a pre-release version
151
+ #
152
+ # @return [void]
153
+ # @raise [VersionBoss::Error] if the version is not a pre-release version
154
+ # @api private
155
+ def assert_is_a_pre_release_version
156
+ return unless pre_release.empty?
157
+
158
+ raise VersionBoss::Error, 'Cannot increment the pre-release part of a release version'
159
+ end
160
+
161
+ # Raise an error if new pre-release type is less than the old pre-release type
162
+ #
163
+ # If the new pre-release type is lexically less than the old pre-release type,
164
+ # then raise an error because the resulting error would sort before the existing
165
+ # version.
166
+ #
167
+ # @return [void]
168
+ # @raise [VersionBoss::Error] if the pre-release type is not valid
169
+ # @api private
170
+ def assert_pre_type_is_valid(pre_type)
171
+ return if self.pre_type <= pre_type
172
+
173
+ message = 'Cannot increment the pre-release identifier ' \
174
+ "from '#{self.pre_type}' to '#{pre_type}' " \
175
+ "because '#{self.pre_type}' is lexically less than '#{pre_type}'"
176
+
177
+ raise VersionBoss::Error, message
178
+ end
179
+
180
+ # Return the next pre-release part
181
+ # @param pre_type [String, nil] the given pre-release type or nil to use the existing pre-release type
182
+ # @return [String]
183
+ # @api private
184
+ def next_pre_part(pre_type)
185
+ pre_type ||= self.pre_type
186
+ assert_pre_type_is_valid(pre_type)
187
+ next_pre_number = self.pre_type == pre_type ? (pre_number + 1) : 1
188
+ "-#{pre_type}.#{next_pre_number}"
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VersionBoss
4
+ module Semver
5
+ # Match a semver within a string
6
+ REGEXP = /
7
+ (?<semver>
8
+ (?<major>0|[1-9]\d*)
9
+ \.
10
+ (?<minor>0|[1-9]\d*)
11
+ \.
12
+ (?<patch>0|[1-9]\d*)
13
+ (?:-
14
+ (?<pre_release>
15
+ (?:
16
+ 0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*
17
+ )
18
+ (?:
19
+ \.
20
+ (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
21
+ )*
22
+ )
23
+ )?
24
+ (?:
25
+ \+
26
+ (?<build_metadata>
27
+ [0-9a-zA-Z-]+
28
+ (?:
29
+ \.
30
+ [0-9a-zA-Z-]+
31
+ )*
32
+ )
33
+ )?
34
+ )
35
+ /x
36
+
37
+ # Match a semver to the full string
38
+ REGEXP_FULL = /\A#{REGEXP.source}\z/x
39
+ end
40
+ end
@@ -0,0 +1,374 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'regexp'
4
+
5
+ module VersionBoss
6
+ module Semver
7
+ # Parse and compare semver version strings
8
+ #
9
+ # This class will parse a semver version string that complies to Semantic
10
+ # Versioning 2.0.0.
11
+ #
12
+ # Two Semver objects can be compared using the spaceship operator (<=>)
13
+ # according to the rules of Semantic Versioning 2.0.0.
14
+ #
15
+ # @example Basic version parsing
16
+ # semver = VersionBoss::Semver.new('1.2.3')
17
+ # semver.major # => '1'
18
+ # semver.minor # => '2'
19
+ # semver.patch # => '3'
20
+ #
21
+ # @example Parsing a version with a pre-release identifier
22
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1')
23
+ # semver.pre_release # => 'alpha.1'
24
+ # semver.pre_release_identifiers # => ['alpha', '1']
25
+ #
26
+ # @example A version with build metadata
27
+ # semver = VersionBoss::Semver.new('1.2.3+build.1')
28
+ # semver.build_metadata # => 'build.1'
29
+ #
30
+ # @example Comparing versions
31
+ # semver1 = VersionBoss::Semver.new('1.2.3')
32
+ # semver2 = VersionBoss::Semver.new('1.2.4')
33
+ # semver1 <=> semver2 # => true
34
+ #
35
+ # See the Semantic Versioning 2.0.0 specification for more details.
36
+ #
37
+ # @see https://semver.org/spec/v2.0.0.html Semantic Versioning 2.0.0
38
+ #
39
+ # @api public
40
+ #
41
+ class Version
42
+ include Comparable
43
+
44
+ # Create a new Semver object
45
+ #
46
+ # @example
47
+ # version = VersionBoss::Semver.new('1.2.3-alpha.1')
48
+ #
49
+ # @param version [String] The version string to parse
50
+ #
51
+ # @raise [VersionBoss::Error] version is not a string or not a valid semver version
52
+ #
53
+ def initialize(version)
54
+ assert_version_must_be_a_string(version)
55
+ @version = version
56
+ parse
57
+ assert_valid_version
58
+ end
59
+
60
+ # @!attribute version [r]
61
+ #
62
+ # The complete version string
63
+ #
64
+ # @example
65
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
66
+ # semver.version #=> '1.2.3-alpha.1+build.001'
67
+ #
68
+ # @return [String]
69
+ #
70
+ # @api public
71
+ #
72
+ attr_reader :version
73
+
74
+ # @attribute major [r]
75
+ #
76
+ # The major part of the version
77
+ #
78
+ # @example
79
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
80
+ # semver.major #=> '1'
81
+ #
82
+ # @return [String]
83
+ #
84
+ # @api public
85
+ #
86
+ attr_reader :major
87
+
88
+ # @attribute minor [r]
89
+ #
90
+ # The minor part of the version
91
+ #
92
+ # @example
93
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
94
+ # semver.minor #=> '2'
95
+ #
96
+ # @return [String]
97
+ #
98
+ # @api public
99
+ #
100
+ attr_reader :minor
101
+
102
+ # @attribute patch [r]
103
+ #
104
+ # The patch part of the version
105
+ #
106
+ # @example
107
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
108
+ # semver.patch #=> '3'
109
+ #
110
+ # @return [String]
111
+ #
112
+ # @api public
113
+ #
114
+ attr_reader :patch
115
+
116
+ # @attribute pre_release [r]
117
+ #
118
+ # The pre_release part of the version
119
+ #
120
+ # Will be an empty string if the version has no pre_release part.
121
+ #
122
+ # @example
123
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
124
+ # semver.pre_release #=> 'alpha.1'
125
+ #
126
+ # @example When the version has no pre_release part
127
+ # semver = VersionBoss::Semver.new('1.2.3')
128
+ # semver.pre_release #=> ''
129
+ #
130
+ # @return [String]
131
+ #
132
+ # @api public
133
+ #
134
+ attr_reader :pre_release
135
+
136
+ # @attribute pre_release_identifiers [r]
137
+ #
138
+ # The pre_release identifiers of the version
139
+ #
140
+ # @example
141
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
142
+ # semver.pre_release_identifiers #=> ['alpha', '1']
143
+ #
144
+ # @example When the version has no pre_release part
145
+ # semver = VersionBoss::Semver.new('1.2.3')
146
+ # semver.pre_release_identifiers #=> []
147
+ #
148
+ # @return [Array<String>]
149
+ #
150
+ # @api public
151
+ #
152
+ attr_reader :pre_release_identifiers
153
+
154
+ # @attribute build_metadata [r]
155
+ #
156
+ # The build_metadata part of the version
157
+ #
158
+ # Will be an empty string if the version has no build_metadata part.
159
+ #
160
+ # @example
161
+ # semver = VersionBoss::Semver.new('1.2.3-alpha.1+build.001')
162
+ # semver.build_metadata #=> 'build.001'
163
+ #
164
+ # @example When the version has no build_metadata part
165
+ # semver = VersionBoss::Semver.new('1.2.3')
166
+ # semver.build_metadata #=> ''
167
+ #
168
+ # @return [String]
169
+ #
170
+ # @api public
171
+ #
172
+ attr_reader :build_metadata
173
+
174
+ # Compare two Semver objects
175
+ #
176
+ # See the [Precedence Rules](https://semver.org/spec/v2.0.0.html#spec-item-11)
177
+ # in the Semantic Versioning 2.0.0 Specification for more details.
178
+ #
179
+ # @example
180
+ # semver1 = VersionBoss::Semver.new('1.2.3')
181
+ # semver2 = VersionBoss::Semver.new('1.2.4')
182
+ # semver1 <=> semver2 # => -1
183
+ # semver2 <=> semver1 # => 1
184
+ #
185
+ # @example A Semver is equal to itself
186
+ # semver1 = VersionBoss::Semver.new('1.2.3')
187
+ # semver1 <=> semver1 # => 0
188
+ #
189
+ # @example A pre-release version is always older than a normal version
190
+ # semver1 = VersionBoss::Semver.new('1.2.3-alpha.1')
191
+ # semver2 = VersionBoss::Semver.new('1.2.3')
192
+ # semver1 <=> semver2 # => -1
193
+ #
194
+ # @example Pre-releases are compared by the parts of the pre-release version
195
+ # semver1 = VersionBoss::Semver.new('1.2.3-alpha.1')
196
+ # semver2 = VersionBoss::Semver.new('1.2.3-alpha.2')
197
+ # semver1 <=> semver2 # => -1
198
+ #
199
+ # @example Build metadata is ignored when comparing versions
200
+ # semver1 = VersionBoss::Semver.new('1.2.3+build.100')
201
+ # semver2 = VersionBoss::Semver.new('1.2.3+build.101')
202
+ # semver1 <=> semver2 # => 0
203
+ #
204
+ # @param other [Semver] the other Semver to compare to
205
+ #
206
+ # @return [Integer] -1 if self < other, 0 if self == other, or 1 if self > other
207
+ #
208
+ # @raise [VersionBoss::Error] other is not a semver
209
+ #
210
+ def <=>(other)
211
+ assert_other_is_a_semver(other)
212
+
213
+ result = compare_core_parts(other)
214
+
215
+ return result unless result.zero? && pre_release != other.pre_release
216
+ return 1 if pre_release.empty?
217
+ return -1 if other.pre_release.empty?
218
+
219
+ compare_pre_release_part(other)
220
+ end
221
+
222
+ # Determine if the version string is a valid semver
223
+ #
224
+ # Override this method in a subclass to provide extra or custom validation.
225
+ #
226
+ # @example
227
+ # VersionBoss::Semver.new('1.2.3').valid? # => true
228
+ # VersionBoss::Semver.new('1.2.3-alpha.1+build.001').valid? # => true
229
+ # VersionBoss::Semver.new('bogus').valid? # => raises VersionBoss::Error
230
+ #
231
+ # @return [Boolean] true if the version string is a valid semver
232
+ #
233
+ def valid?
234
+ # If major is set, then so is everything else
235
+ !major.nil?
236
+ end
237
+
238
+ # Two versions are equal if their version strings are equal
239
+ #
240
+ # @example
241
+ # VersionBoss::Semver.new('1.2.3') == '1.2.3' # => true
242
+ #
243
+ # @param other [Semver] the other Semver to compare to
244
+ #
245
+ # @return [Boolean] true if the version strings are equal
246
+ #
247
+ def ==(other)
248
+ version == other.to_s
249
+ end
250
+
251
+ # The string representation of a Semver is its version string
252
+ #
253
+ # @example
254
+ # VersionBoss::Semver.new('1.2.3').to_s # => '1.2.3'
255
+ #
256
+ # @return [String] the version string
257
+ #
258
+ def to_s
259
+ version
260
+ end
261
+
262
+ private
263
+
264
+ # Parse @version into its parts
265
+ # @return [void]
266
+ # @api private
267
+ def parse
268
+ return unless (match_data = version.match(REGEXP_FULL))
269
+
270
+ core_parts(match_data)
271
+ pre_release_part(match_data)
272
+ build_metadata_part(match_data)
273
+ end
274
+
275
+ # Compare the major, minor, and patch parts of this Semver to other
276
+ # @param other [Semver] the other Semver to compare to
277
+ # @return [Integer] -1 if self < other, 0 if self == other, or 1 if self > other
278
+ # @api private
279
+ def compare_core_parts(other)
280
+ identifiers = [major.to_i, minor.to_i, patch.to_i]
281
+ other_identifiers = [other.major.to_i, other.minor.to_i, other.patch.to_i]
282
+
283
+ identifiers <=> other_identifiers
284
+ end
285
+
286
+ # Compare two pre-release identifiers
287
+ #
288
+ # Implements the rules for precedence for comparing two pre-release identifiers
289
+ # from the Semantic Versioning 2.0.0 Specification.
290
+ #
291
+ # @param identifier [String, Integer] the identifier to compare
292
+ # @param other_identifier [String, Integer] the other identifier to compare
293
+ # @return [Integer] -1, 0, or 1
294
+ # @api private
295
+ def compare_identifiers(identifier, other_identifier)
296
+ return 1 if other_identifier.nil?
297
+ return -1 if identifier.is_a?(Integer) && other_identifier.is_a?(String)
298
+ return 1 if other_identifier.is_a?(Integer) && identifier.is_a?(String)
299
+
300
+ identifier <=> other_identifier
301
+ end
302
+
303
+ # Compare two pre-release version parts
304
+ #
305
+ # Implements the rules for precedence for comparing the pre-release part of
306
+ # one version with the pre-release part of another version from the Semantic
307
+ # Versioning 2.0.0 Specification.
308
+ #
309
+ # @param other [Semver] the other Semver to compare to
310
+ # @return [Integer] -1, 0, or 1
311
+ # @api private
312
+ def compare_pre_release_part(other)
313
+ pre_release_identifiers.zip(other.pre_release_identifiers).each do |field, other_field|
314
+ result = compare_identifiers(field, other_field)
315
+ return result unless result.zero?
316
+ end
317
+ pre_release_identifiers.size < other.pre_release_identifiers.size ? -1 : 0
318
+ end
319
+
320
+ # Raise a error if other is not a valid Semver
321
+ # @param other [Semver] the other to check
322
+ # @return [void]
323
+ # @raise [VersionBoss::Error] if other is not a valid Semver
324
+ # @api private
325
+ def assert_other_is_a_semver(other)
326
+ raise VersionBoss::Error, 'other must be a Semver' unless other.is_a?(VersionBoss::Semver::Version)
327
+ end
328
+
329
+ # Raise a error if the given version is not a string
330
+ # @param version [Semver] the version to check
331
+ # @return [void]
332
+ # @raise [VersionBoss::Error] if the given version is not a string
333
+ # @api private
334
+ def assert_version_must_be_a_string(version)
335
+ raise VersionBoss::Error, 'Version must be a string' unless version.is_a?(String)
336
+ end
337
+
338
+ # Raise a error if this version object is not a valid Semver
339
+ # @return [void]
340
+ # @raise [VersionBoss::Error] if other is not a valid Semver
341
+ # @api private
342
+ def assert_valid_version
343
+ raise VersionBoss::Error, "Not a valid version string: #{version}" unless valid?
344
+ end
345
+
346
+ # Set the major, minor, and patch parts of this Semver
347
+ # @param match_data [MatchData] the match data from the version string
348
+ # @return [void]
349
+ # @api private
350
+ def core_parts(match_data)
351
+ @major = match_data[:major]
352
+ @minor = match_data[:minor]
353
+ @patch = match_data[:patch]
354
+ end
355
+
356
+ # Set the pre-release of this Semver
357
+ # @param match_data [MatchData] the match data from the version string
358
+ # @return [void]
359
+ # @api private
360
+ def pre_release_part(match_data)
361
+ @pre_release = match_data[:pre_release] || ''
362
+ @pre_release_identifiers = @pre_release.split('.').map { |f| f =~ /\A\d+\z/ ? f.to_i : f }
363
+ end
364
+
365
+ # Set the build_metadata of this Semver
366
+ # @param match_data [MatchData] the match data from the version string
367
+ # @return [void]
368
+ # @api private
369
+ def build_metadata_part(match_data)
370
+ @build_metadata = match_data[:build_metadata] || ''
371
+ end
372
+ end
373
+ end
374
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VersionBoss
4
+ # Classes for working with Gem versions
5
+ module Semver; end
6
+ end
7
+
8
+ require_relative 'semver/incrementable_version'
9
+ require_relative 'semver/version'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VersionBoss
4
+ # The current version of this gem
5
+ VERSION = '0.1.0'
6
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'version_boss/gem'
4
+ require_relative 'version_boss/semver'
5
+
6
+ # Parse, compare, and increment versions according to the SemVer 2.0.0
7
+ module VersionBoss
8
+ # Errors reported by the VersionBoss gem
9
+ class Error < StandardError; end
10
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/version_boss/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'version_boss'
7
+ spec.version = VersionBoss::VERSION
8
+ spec.authors = ['James Couball']
9
+ spec.email = ['jcouball@yahoo.com']
10
+
11
+ spec.summary = 'A Gem to parse and compare SemVer versions AND increment versions for Ruby Gems'
12
+ spec.description = <<~DESC
13
+ Parse, compare, and increment RubyGem versions with the 'gem-version' CLI
14
+ command or the 'VersionBoss::Gem::Version' class.
15
+ DESC
16
+
17
+ spec.homepage = 'http://github.com/main-branch/version_boss'
18
+ spec.license = 'MIT'
19
+ spec.required_ruby_version = '>= 3.0.0'
20
+
21
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
22
+
23
+ spec.metadata['homepage_uri'] = spec.homepage
24
+ spec.metadata['source_code_uri'] = spec.homepage
25
+ spec.metadata['changelog_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}/file/CHANGELOG.md"
26
+ spec.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}"
27
+
28
+ # Specify which files should be added to the gem when it is released.
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ spec.files = Dir.chdir(__dir__) do
31
+ `git ls-files -z`.split("\x0").reject do |f|
32
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
33
+ end
34
+ end
35
+ spec.bindir = 'exe'
36
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ['lib']
38
+
39
+ spec.add_runtime_dependency 'thor', '~> 1.3'
40
+
41
+ spec.add_development_dependency 'bundler-audit', '~> 0.9'
42
+ spec.add_development_dependency 'create_github_release', '~> 1.3'
43
+ spec.add_development_dependency 'rake', '~> 13.1'
44
+ spec.add_development_dependency 'rspec', '~> 3.12'
45
+ spec.add_development_dependency 'rubocop', '~> 1.59'
46
+ spec.add_development_dependency 'simplecov', '~> 0.22'
47
+ spec.add_development_dependency 'simplecov-lcov', '~> 0.8'
48
+
49
+ unless RUBY_PLATFORM == 'java'
50
+ spec.add_development_dependency 'redcarpet', '~> 3.6'
51
+ spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
52
+ spec.add_development_dependency 'yardstick', '~> 0.9'
53
+ end
54
+
55
+ spec.metadata['rubygems_mfa_required'] = 'true'
56
+ end