versionomy 0.0.4 → 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.
data/README.txt DELETED
@@ -1,133 +0,0 @@
1
- == Versionomy
2
-
3
- Versionomy is a generalized version number library.
4
- It provides tools to represent, manipulate, parse, and compare version
5
- numbers in the wide variety of versioning schemes in use.
6
-
7
- === Some examples
8
-
9
- v1 = Versionomy.parse('1.3.2')
10
- v1.major # => 1
11
- v1.minor # => 3
12
- v1.tiny # => 2
13
-
14
- v2 = Versionomy.parse('1.4a3')
15
- v2.major # => 1
16
- v2.minor # => 4
17
- v2.tiny # => 0
18
- v2.release_type # => :alpha
19
- v2.alpha_version # => 3
20
- v2 > v1 # => true
21
-
22
- v3 = Versionomy.parse('1.4.0b2')
23
- v3.major # => 1
24
- v3.minor # => 4
25
- v3.tiny # => 0
26
- v3.release_type # => :beta
27
- v3.alpha_version # raises NameError
28
- v3.beta_version # => 2
29
- v3 > v2 # => true
30
- v3.to_s # => '1.4.0b2'
31
-
32
- v4 = v3.bump(:beta_version)
33
- v4.to_s # => '1.4.0b3'
34
-
35
- v5 = v3.bump(:release_type)
36
- v5.to_s # => '1.4.0rc1'
37
-
38
- v6 = v3.bump(:tiny)
39
- v6.to_s # => '1.4.1'
40
-
41
- v7 = v3.bump(:major)
42
- v7.to_s # => '2.0.0'
43
- v7.parse_params[:required_fields] = 2
44
- v7.to_s # => '2.0'
45
-
46
- v8 = Versionomy.parse('2.0.0.0')
47
- v8.to_s # => '2.0.0.0'
48
- v8 == v7 # => true
49
-
50
- v9 = v7.bump(:patchlevel)
51
- v9.to_s # => '2.0-1'
52
-
53
- v10 = Versionomy.parse('2008 SP2', :patchlevel_separator => ' SP')
54
- v10.major # => 2008
55
- v10.minor # => 0
56
- v10.patchlevel # => 2
57
- v10.to_s # => '2008 SP2'
58
-
59
- === Feature list
60
-
61
- Versionomy's default versioning scheme handles four primary fields (labeled
62
- +major+, +minor+, +tiny+, and +tiny2+). It also supports prerelease versions
63
- such as "pre", development, alpha, beta, and release candidate. Finally, it
64
- supports patchlevel numbers for released versions.
65
-
66
- Versionomy can compare any two version numbers, and "bump" versions at any
67
- level. It supports parsing and unparsing in most commonly-used formats, and
68
- allows you to extend the parsing to include custom formats.
69
-
70
- Finally, Versionomy also lets you to specify any arbitrary versioning
71
- "schema". You can define any number of version number fields, and provide
72
- your own semantics and behavior for comparing, parsing, and modifying
73
- version numbers.
74
-
75
- === Requirements
76
-
77
- * Ruby 1.8.7 or later.
78
- * Rubygems
79
- * mixology gem.
80
- * blockenspiel gem.
81
-
82
- === Installation
83
-
84
- gem install versionomy
85
-
86
- === Known issues and limitations
87
-
88
- * Not yet compatible with Ruby 1.9 due to issues with the mixology gem.
89
- * JRuby status not yet known.
90
-
91
- === Development and support
92
-
93
- Documentation is available at http://virtuoso.rubyforge.org/versionomy
94
-
95
- Source code is hosted by Github at http://github.com/dazuma/versionomy/tree
96
-
97
- Report bugs on RubyForge at http://rubyforge.org/projects/virtuoso
98
-
99
- Contact the author at dazuma at gmail dot com.
100
-
101
- === Author / Credits
102
-
103
- Versionomy is written by Daniel Azuma (http://www.daniel-azuma.com).
104
-
105
- == LICENSE:
106
-
107
- Copyright 2008 Daniel Azuma.
108
-
109
- All rights reserved.
110
-
111
- Redistribution and use in source and binary forms, with or without
112
- modification, are permitted provided that the following conditions are met:
113
-
114
- * Redistributions of source code must retain the above copyright notice,
115
- this list of conditions and the following disclaimer.
116
- * Redistributions in binary form must reproduce the above copyright notice,
117
- this list of conditions and the following disclaimer in the documentation
118
- and/or other materials provided with the distribution.
119
- * Neither the name of the copyright holder, nor the names of any other
120
- contributors to this software, may be used to endorse or promote products
121
- derived from this software without specific prior written permission.
122
-
123
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
124
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
125
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
126
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
127
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
128
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
129
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
130
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
131
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
132
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
133
- POSSIBILITY OF SUCH DAMAGE.
@@ -1,392 +0,0 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # Versionomy standard schema and formats
4
- #
5
- # -----------------------------------------------------------------------------
6
- # Copyright 2008 Daniel Azuma
7
- #
8
- # All rights reserved.
9
- #
10
- # Redistribution and use in source and binary forms, with or without
11
- # modification, are permitted provided that the following conditions are met:
12
- #
13
- # * Redistributions of source code must retain the above copyright notice,
14
- # this list of conditions and the following disclaimer.
15
- # * Redistributions in binary form must reproduce the above copyright notice,
16
- # this list of conditions and the following disclaimer in the documentation
17
- # and/or other materials provided with the distribution.
18
- # * Neither the name of the copyright holder, nor the names of any other
19
- # contributors to this software, may be used to endorse or promote products
20
- # derived from this software without specific prior written permission.
21
- #
22
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
- # POSSIBILITY OF SUCH DAMAGE.
33
- # -----------------------------------------------------------------------------
34
- ;
35
-
36
-
37
- module Versionomy
38
-
39
-
40
- # === The standard schema
41
- #
42
- # The standard schema is designed to handle most commonly-used version
43
- # number forms, and allow parsing and comparison between them.
44
- #
45
- # It begins with four numeric fields: "major.minor.tiny.tiny2".
46
- #
47
- # The next field, "release_type", defines the remaining structure.
48
- # The release type can be one of these symbolic values: <tt>:prerelease</tt>,
49
- # <tt>:development</tt>, <tt>:alpha</tt>, <tt>:beta</tt>,
50
- # <tt>:release_candidate</tt>, or <tt>:release</tt>.
51
- #
52
- # Depending on that value, additional fields become available. For example,
53
- # the <tt>:alpha</tt> value enables the fields "alpha_version"
54
- # and "alpha_minor", which represent version numbers after the "a" alpha
55
- # specifier. i.e. "2.1a30" has an alpha_version of 30. "2.1a30.2" also
56
- # has an alpha_minor of 2. Similarly, the <tt>:beta</tt> release_type
57
- # value enables the fields "beta_version" and "beta_minor". A release_type
58
- # of <tt>:release</tt> enables "patchlevel" and "patchlevel_minor", to
59
- # support versions like "1.8.7p72".
60
- #
61
- # The full definition of the standard schema is as follows:
62
- #
63
- # Schema.new(:major, :initial => 1) do
64
- # schema(:minor) do
65
- # schema(:tiny) do
66
- # schema(:tiny2) do
67
- # schema(:release_type, :type => :symbol) do
68
- # symbol(:prerelease, :bump => :release)
69
- # symbol(:development, :bump => :alpha)
70
- # symbol(:alpha, :bump => :beta)
71
- # symbol(:beta, :bump => :release_candidate)
72
- # symbol(:release_candidate, :bump => :release)
73
- # symbol(:release, :bump => :release)
74
- # initial_value(:release)
75
- # schema(:prerelease_version, :only => :prerelease, :initial => 1) do
76
- # schema(:prerelease_minor)
77
- # end
78
- # schema(:development_version, :only => :development, :initial => 1) do
79
- # schema(:development_minor)
80
- # end
81
- # schema(:alpha_version, :only => :alpha, :initial => 1) do
82
- # schema(:alpha_minor)
83
- # end
84
- # schema(:beta_version, :only => :beta, :initial => 1) do
85
- # schema(:beta_minor)
86
- # end
87
- # schema(:release_candidate_version, :only => :release_candidate, :initial => 1) do
88
- # schema(:release_candidate_minor)
89
- # end
90
- # schema(:patchlevel, :only => :release) do
91
- # schema(:patchlevel_minor)
92
- # end
93
- # end
94
- # end
95
- # end
96
- # end
97
- # end
98
-
99
- module Standard
100
-
101
-
102
- # A formatter for the standard schema
103
-
104
- class StandardFormat
105
-
106
-
107
- # Create a new formatter
108
-
109
- def initialize(opts_={})
110
- @name = opts_[:name] || :standard
111
- @patchlevel_separator = opts_[:patchlevel_separator] || ['-', '\s?[Pp]']
112
- @prerelease_symbol = opts_[:prerelease_symbol] || '\s?(PRE|Pre|pre)'
113
- @development_symbol = opts_[:development_symbol] || '\s?[Dd]'
114
- @alpha_symbol = opts_[:alpha_symbol] || '\s?[Aa](LPHA|lpha)?'
115
- @beta_symbol = opts_[:beta_symbol] || '\s?[Bb](ETA|eta)?'
116
- @release_candidate_symbol = opts_[:release_candidate_symbol] || '\s?(RC|Rc|rc)'
117
- @patchlevel_separator_unparse = opts_[:patchlevel_separator_unparse] || '-'
118
- @prerelease_symbol_unparse = opts_[:prerelease_symbol_unparse] || 'pre'
119
- @development_symbol_unparse = opts_[:development_symbol_unparse] || 'd'
120
- @alpha_symbol_unparse = opts_[:alpha_symbol_unparse] || 'a'
121
- @beta_symbol_unparse = opts_[:beta_symbol_unparse] || 'b'
122
- @release_candidate_symbol_unparse = opts_[:release_candidate_symbol_unparse] || 'rc'
123
- end
124
-
125
-
126
- def _create_regex(given_, default_) # :nodoc:
127
- if given_
128
- if given_.respond_to?(:join)
129
- given_.join('|')
130
- else
131
- given_.to_s
132
- end
133
- else
134
- if default_.respond_to?(:join)
135
- default_.join('|')
136
- else
137
- default_.to_s
138
- end
139
- end
140
- end
141
- private :_create_regex
142
-
143
-
144
- # The format name
145
-
146
- def name
147
- @name
148
- end
149
-
150
-
151
- # Parse a string for the standard schema.
152
-
153
- def parse(schema_, str_, params_)
154
- params_ = {:format => @name}.merge(params_)
155
- hash_ = Hash.new
156
- if str_ =~ /^(\d+)(.*)$/
157
- hash_[:major] = $1.to_i
158
- str_ = $2
159
- else
160
- hash_[:major] = 0
161
- end
162
- if str_ =~ /^\.(\d+)(.*)$/
163
- hash_[:minor] = $1.to_i
164
- str_ = $2
165
- if str_ =~ /^\.(\d+)(.*)$/
166
- hash_[:tiny] = $1.to_i
167
- str_ = $2
168
- if str_ =~ /^\.(\d+)(.*)$/
169
- hash_[:tiny2] = $1.to_i
170
- str_ = $2
171
- params_[:required_fields] = 4
172
- else
173
- hash_[:tiny2] = 0
174
- params_[:required_fields] = 3
175
- end
176
- else
177
- hash_[:tiny] = 0
178
- params_[:required_fields] = 2
179
- end
180
- else
181
- hash_[:minor] = 0
182
- params_[:required_fields] = 1
183
- end
184
- if str_ =~ /^(#{_create_regex(params_[:prerelease_symbol], @prerelease_symbol)})(\d+)(.*)$/
185
- matches_ = $~
186
- params_[:prerelease_symbol_unparse] = matches_[1]
187
- hash_[:release_type] = :prerelease
188
- hash_[:prerelease_version] = matches_[-2].to_i
189
- str_ = matches_[-1]
190
- if str_ =~ /^\.(\d+)/
191
- hash_[:prerelease_minor] = $1.to_i
192
- params_[:prerelease_required_fields] = 2
193
- else
194
- params_[:prerelease_required_fields] = 1
195
- end
196
- elsif str_ =~ /^(#{_create_regex(params_[:development_symbol], @development_symbol)})(\d+)(.*)$/
197
- matches_ = $~
198
- params_[:development_symbol_unparse] = matches_[1]
199
- hash_[:release_type] = :development
200
- hash_[:development_version] = matches_[-2].to_i
201
- str_ = matches_[-1]
202
- if str_ =~ /^\.(\d+)/
203
- hash_[:development_minor] = $1.to_i
204
- params_[:development_required_fields] = 2
205
- else
206
- params_[:development_required_fields] = 1
207
- end
208
- elsif str_ =~ /^(#{_create_regex(params_[:alpha_symbol], @alpha_symbol)})(\d+)(.*)$/
209
- matches_ = $~
210
- params_[:alpha_symbol_unparse] = matches_[1]
211
- hash_[:release_type] = :alpha
212
- hash_[:alpha_version] = matches_[-2].to_i
213
- str_ = matches_[-1]
214
- if str_ =~ /^\.(\d+)/
215
- hash_[:alpha_minor] = $1.to_i
216
- params_[:alpha_required_fields] = 2
217
- else
218
- params_[:alpha_required_fields] = 1
219
- end
220
- elsif str_ =~ /^(#{_create_regex(params_[:beta_symbol], @beta_symbol)})(\d+)(.*)$/
221
- matches_ = $~
222
- params_[:beta_symbol_unparse] = matches_[1]
223
- hash_[:release_type] = :beta
224
- hash_[:beta_version] = matches_[-2].to_i
225
- str_ = matches_[-1]
226
- if str_ =~ /^\.(\d+)/
227
- hash_[:beta_minor] = $1.to_i
228
- params_[:beta_required_fields] = 2
229
- else
230
- params_[:beta_required_fields] = 1
231
- end
232
- elsif str_ =~ /^(#{_create_regex(params_[:release_candidate_symbol], @release_candidate_symbol)})(\d+)(.*)$/
233
- matches_ = $~
234
- params_[:release_candidate_symbol_unparse] = matches_[1]
235
- hash_[:release_candidate_version] = matches_[-2].to_i
236
- hash_[:release_type] = :release_candidate
237
- str_ = matches_[-1]
238
- if str_ =~ /^\.(\d+)/
239
- hash_[:release_candidate_minor] = $1.to_i
240
- params_[:release_candidate_required_fields] = 2
241
- else
242
- params_[:release_candidate_required_fields] = 1
243
- end
244
- else
245
- hash_[:release_type] = :release
246
- if str_ =~ /^(#{_create_regex(params_[:patchlevel_separator], @patchlevel_separator)})(\d+)(.*)$/
247
- matches_ = $~
248
- params_[:patchlevel_separator_unparse] = matches_[1]
249
- params_[:patchlevel_format] = :digit
250
- hash_[:patchlevel] = matches_[-2].to_i
251
- str_ = matches_[-1]
252
- if str_ =~ /^\.(\d+)/
253
- hash_[:patchlevel_minor] = $1.to_i
254
- params_[:patchlevel_required_fields] = 2
255
- else
256
- params_[:patchlevel_required_fields] = 1
257
- end
258
- elsif str_ =~ /^([a-z])/
259
- char_ = $1
260
- params_[:patchlevel_format] = :alpha_lower
261
- params_[:patchlevel_required_fields] = 1
262
- hash[:patchlevel] = (char_.bytes.next rescue char_[0]) - 96
263
- elsif str_ =~ /^([A-Z])/
264
- char_ = $1
265
- params_[:patchlevel_format] = :alpha_upper
266
- params_[:patchlevel_required_fields] = 1
267
- hash[:patchlevel] = (char_.bytes.next rescue char_[0]) - 64
268
- end
269
- end
270
- Versionomy::Value._new(schema_, hash_, params_)
271
- end
272
-
273
-
274
- # Unparse a value for the standard schema.
275
-
276
- def unparse(schema_, value_, params_)
277
- params_ = value_.parse_params.merge(params_)
278
- str_ = "#{value_.major}.#{value_.minor}.#{value_.tiny}.#{value_.tiny2}"
279
- (4 - (params_[:required_fields] || 2)).times{ str_.sub!(/\.0$/, '') }
280
- case value_.release_type
281
- when :prerelease
282
- prerelease_required_fields_ = params_[:prerelease_required_fields] || 1
283
- str_ << (params_[:prerelease_symbol_unparse] || @prerelease_symbol_unparse)
284
- str_ << value_.prerelease_version.to_s
285
- if value_.prerelease_minor > 0 || prerelease_required_fields_ > 1
286
- str_ << ".#{value_.prerelease_minor}"
287
- end
288
- when :development
289
- development_required_fields_ = params_[:development_required_fields] || 1
290
- str_ << (params_[:development_symbol_unparse] || @development_symbol_unparse)
291
- str_ << value_.development_version.to_s
292
- if value_.development_minor > 0 || development_required_fields_ > 1
293
- str_ << ".#{value_.development_minor}"
294
- end
295
- when :alpha
296
- alpha_required_fields_ = params_[:alpha_required_fields] || 1
297
- str_ << (params_[:alpha_symbol_unparse] || @alpha_symbol_unparse)
298
- str_ << value_.alpha_version.to_s
299
- if value_.alpha_minor > 0 || alpha_required_fields_ > 1
300
- str_ << ".#{value_.alpha_minor}"
301
- end
302
- when :beta
303
- beta_required_fields_ = params_[:beta_required_fields] || 1
304
- str_ << (params_[:beta_symbol_unparse] || @beta_symbol_unparse)
305
- str_ << value_.beta_version.to_s
306
- if value_.beta_minor > 0 || beta_required_fields_ > 1
307
- str_ << ".#{value_.beta_minor}"
308
- end
309
- when :release_candidate
310
- release_candidate_required_fields_ = params_[:release_candidate_required_fields] || 1
311
- str_ << (params_[:release_candidate_symbol_unparse] || @release_candidate_symbol_unparse)
312
- str_ << value_.release_candidate_version.to_s
313
- if value_.release_candidate_minor > 0 || release_candidate_required_fields_ > 1
314
- str_ << ".#{value_.release_candidate_minor}"
315
- end
316
- else
317
- patchlevel_required_fields_ = params_[:patchlevel_required_fields] || 0
318
- if value_.patchlevel > 0 || patchlevel_required_fields_ > 0
319
- if params_[:patchlevel_format] == :alpha_lower
320
- str_.concat(96 + value_.patchlevel)
321
- elsif params_[:patchlevel_format] == :alpha_upper
322
- str_.concat(64 + value_.patchlevel)
323
- else
324
- str_ << (params_[:patchlevel_separator_unparse] || @patchlevel_separator_unparse)
325
- str_ << value_.patchlevel.to_s
326
- if value_.patchlevel_minor > 0 || patchlevel_required_fields_ > 1
327
- str_ << ".#{value_.patchlevel_minor}"
328
- end
329
- end
330
- end
331
- end
332
- str_
333
- end
334
-
335
- end
336
-
337
-
338
- # Get the standard schema
339
-
340
- def self.schema
341
- @standard_schema ||= SchemaCreator._create_schema
342
- end
343
-
344
-
345
- module SchemaCreator # :nodoc:
346
-
347
- def self._create_schema
348
- Schema.new(:major, :initial => 1) do
349
- schema(:minor) do
350
- schema(:tiny) do
351
- schema(:tiny2) do
352
- schema(:release_type, :type => :symbol) do
353
- symbol(:prerelease, :bump => :release)
354
- symbol(:development, :bump => :alpha)
355
- symbol(:alpha, :bump => :beta)
356
- symbol(:beta, :bump => :release_candidate)
357
- symbol(:release_candidate, :bump => :release)
358
- symbol(:release, :bump => :release)
359
- initial_value(:release)
360
- schema(:prerelease_version, :only => :prerelease, :initial => 1) do
361
- schema(:prerelease_minor)
362
- end
363
- schema(:development_version, :only => :development, :initial => 1) do
364
- schema(:development_minor)
365
- end
366
- schema(:alpha_version, :only => :alpha, :initial => 1) do
367
- schema(:alpha_minor)
368
- end
369
- schema(:beta_version, :only => :beta, :initial => 1) do
370
- schema(:beta_minor)
371
- end
372
- schema(:release_candidate_version, :only => :release_candidate, :initial => 1) do
373
- schema(:release_candidate_minor)
374
- end
375
- schema(:patchlevel, :only => :release) do
376
- schema(:patchlevel_minor)
377
- end
378
- end
379
- end
380
- end
381
- end
382
- define_format(StandardFormat.new)
383
- end
384
- end
385
-
386
-
387
- end
388
-
389
- end
390
-
391
-
392
- end