version_boss 0.1.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.
@@ -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