versionomy 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +10 -0
- data/README.rdoc +3 -29
- data/Rakefile +1 -1
- data/Versionomy.rdoc +346 -0
- data/lib/versionomy.rb +0 -3
- data/lib/versionomy/conversion.rb +15 -6
- data/lib/versionomy/format.rb +112 -18
- data/lib/versionomy/{format → format_definitions}/rubygems.rb +111 -2
- data/lib/versionomy/{format → format_definitions}/standard.rb +1 -1
- data/lib/versionomy/interface.rb +5 -5
- data/lib/versionomy/schema/wrapper.rb +78 -8
- data/lib/versionomy/value.rb +63 -17
- data/lib/versionomy/version.rb +1 -1
- data/tests/tc_rubygems_basic.rb +35 -0
- data/tests/tc_standard_reset.rb +106 -0
- metadata +8 -5
- data/lib/versionomy/conversion/rubygems.rb +0 -146
data/History.rdoc
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 0.3.0 / 2009-11-30
|
2
|
+
|
3
|
+
* Alpha release, opened for public feedback
|
4
|
+
* Autoloading of format definitions using a load path.
|
5
|
+
* Format and conversion registry/lookup is now thread-safe.
|
6
|
+
* Implemented resetting a particular field in the value.
|
7
|
+
* Implemented aliases for field names.
|
8
|
+
* Changed the canonical YAML tag to its permanent value. The old one will continue to be recognized, but only the permanent one will be written from now on.
|
9
|
+
* Documentation updates
|
10
|
+
|
1
11
|
=== 0.2.5 / 2009-11-24
|
2
12
|
|
3
13
|
* Preserve minimum width of a field, if the field has leading zeros. For example, "2.01".
|
data/README.rdoc
CHANGED
@@ -4,35 +4,9 @@ Versionomy is a generalized version number library.
|
|
4
4
|
It provides tools to represent, manipulate, parse, and compare version
|
5
5
|
numbers in the wide variety of versioning schemes in use.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
seldom seem to be done right.
|
11
|
-
|
12
|
-
Imagine the common case of testing the Ruby version. Most of us, if we
|
13
|
-
need to worry about Ruby VM compatibility, will do something like:
|
14
|
-
|
15
|
-
do_something if RUBY_VERSION >= "1.8.7"
|
16
|
-
|
17
|
-
Treating the version number as a string works well enough, until it
|
18
|
-
doesn't. The above code will do the right thing for Ruby 1.8.6, 1.8.7,
|
19
|
-
1.8.8, and 1.9.1. But it will fail if the version is "1.8.10" or "1.10".
|
20
|
-
And properly interpreting "prerelease" version syntax such as
|
21
|
-
"1.9.2-preview1"? Forget it.
|
22
|
-
|
23
|
-
There are a few version number classes out there that do better than
|
24
|
-
treating version numbers as plain strings. One example is Gem::Version,
|
25
|
-
part of the RubyGems package. This class separates the version into fields
|
26
|
-
and lets you manipulate and compare version numbers more robustly. It even
|
27
|
-
provides limited support for "prerelease" versions through using string-
|
28
|
-
valued fields-- although it's a hack, and a bit of a clumsy one at that. A
|
29
|
-
prerelease version has to be represented like this: "1.9.2.b.1" or
|
30
|
-
"1.9.2.preview.2". Wouldn't it be nice to be able to parse more typical
|
31
|
-
version number formats such as "1.9.2b1" and "1.9.2-preview2"? Wouldn't
|
32
|
-
it be nice for a version like "1.9.2b1" to _understand_ that it's a "beta"
|
33
|
-
version and behave accordingly?
|
34
|
-
|
35
|
-
With Versionomy, you can do all this and more.
|
7
|
+
This document summarizes the features of Versionomy with a quick synopsis
|
8
|
+
and feature list. For more detailed usage information and examples, see
|
9
|
+
{Versionomy.rdoc}[link:Versionomy\_rdoc.html].
|
36
10
|
|
37
11
|
=== Some examples
|
38
12
|
|
data/Rakefile
CHANGED
data/Versionomy.rdoc
ADDED
@@ -0,0 +1,346 @@
|
|
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
|
+
This document provides a step-by-step introduction to most of the features
|
8
|
+
of Versionomy.
|
9
|
+
|
10
|
+
=== Version numbers done right?
|
11
|
+
|
12
|
+
Let's be honest. Version numbers are not easy to deal with, and very
|
13
|
+
seldom seem to be done right.
|
14
|
+
|
15
|
+
Imagine the common case of testing the Ruby version. Most of us, if we
|
16
|
+
need to worry about Ruby VM compatibility, will do something like:
|
17
|
+
|
18
|
+
do_something if RUBY_VERSION >= "1.8.7"
|
19
|
+
|
20
|
+
Treating the version number as a string works well enough, until it
|
21
|
+
doesn't. The above code will do the right thing for Ruby 1.8.6, 1.8.7,
|
22
|
+
1.8.8, and 1.9.1. But it will fail if the version is "1.8.10" or "1.10".
|
23
|
+
And properly interpreting "prerelease" version syntax such as
|
24
|
+
"1.9.2-preview1"? Forget it.
|
25
|
+
|
26
|
+
There are a few version number classes out there that do better than
|
27
|
+
treating version numbers as plain strings. One example is Gem::Version,
|
28
|
+
part of the RubyGems package. This class separates the version into fields
|
29
|
+
and lets you manipulate and compare version numbers more robustly. It even
|
30
|
+
provides limited support for "prerelease" versions through using string-
|
31
|
+
valued fields-- although it's a hack, and a bit of a clumsy one at that. A
|
32
|
+
prerelease version has to be represented like this: "1.9.2.b.1" or
|
33
|
+
"1.9.2.preview.2". Wouldn't it be nice to be able to parse more typical
|
34
|
+
version number formats such as "1.9.2b1" and "1.9.2-preview2"? Wouldn't
|
35
|
+
it be nice for a version like "1.9.2b1" to _understand_ that it's a "beta"
|
36
|
+
version and behave accordingly?
|
37
|
+
|
38
|
+
With Versionomy, you can do all this and more. Here's how...
|
39
|
+
|
40
|
+
=== Creating version numbers
|
41
|
+
|
42
|
+
Creating a version number object in Versionomy is as simple as passing a
|
43
|
+
string to a factory. Versionomy understands a wide range of version number
|
44
|
+
formats out of the box.
|
45
|
+
|
46
|
+
v1 = Versionomy.parse('1.2') # Simple version numbers
|
47
|
+
v2 = Versionomy.parse('2.1.5.0') # Up to four fields supported
|
48
|
+
v3 = Versionomy.parse('1.9b3') # Alpha and beta versions
|
49
|
+
v4 = Versionomy.parse('1.9rc2') # Release candidates too
|
50
|
+
v5 = Versionomy.parse('1.9.2-preview2') # Preview releases
|
51
|
+
v6 = Versionomy.parse('1.9.2-p6') # Patchlevels
|
52
|
+
v7 = Versionomy.parse('v2.0 beta 6.1') # Many alternative syntaxes
|
53
|
+
|
54
|
+
You can also construct version numbers manually by passing a hash of field
|
55
|
+
values. See the next section for a discussion of fields.
|
56
|
+
|
57
|
+
v1 = Versionomy.create(:major => 1, :minor => 2) # creates version "1.2"
|
58
|
+
v2 = Versionomy.create(:major => 1, :minor => 9,
|
59
|
+
:release_type => :beta, :beta_version => 3) # creates version "1.9b3"
|
60
|
+
|
61
|
+
The current ruby virtual machine version can be obtained using:
|
62
|
+
|
63
|
+
v1 = Versionomy.ruby_version
|
64
|
+
|
65
|
+
Many other libraries include their version as a string constant in their
|
66
|
+
main namespace module. Versionomy provides a quick facility to attempt to
|
67
|
+
extract the version of a library:
|
68
|
+
|
69
|
+
require 'nokogiri'
|
70
|
+
v1 = Versionomy.version_of(Nokogiri)
|
71
|
+
|
72
|
+
=== Version number fields
|
73
|
+
|
74
|
+
A version number is a collection of fields in a particular order. Standard
|
75
|
+
version numbers have the following fields:
|
76
|
+
|
77
|
+
* :major
|
78
|
+
* :minor
|
79
|
+
* :tiny
|
80
|
+
* :tiny2
|
81
|
+
* :release_type
|
82
|
+
|
83
|
+
The first four fields correspond to the four numeric fields of the version
|
84
|
+
number. E.g. version numbers have the form "major.minor.tiny.tiny2".
|
85
|
+
Trailing fields that have a zero value may be omitted from a string
|
86
|
+
representation, but are still present in the Versionomy::Value object.
|
87
|
+
|
88
|
+
The fifth field is special. Its value is one of the following symbols:
|
89
|
+
|
90
|
+
* :development
|
91
|
+
* :alpha
|
92
|
+
* :beta
|
93
|
+
* :release_candidate
|
94
|
+
* :preview
|
95
|
+
* :final
|
96
|
+
|
97
|
+
The value of the :release_type field determines which other fields are
|
98
|
+
available in the version number. If the :release_type is :development, then
|
99
|
+
the two fields :development_version and :development_minor are available.
|
100
|
+
Similarly, if :release_type is :alpha, then the two fields :alpha_version
|
101
|
+
and :alpha_minor are available, and so on. If :release_type is :final, that
|
102
|
+
exposes the two fields :patchlevel and :patchlevel_minor.
|
103
|
+
|
104
|
+
You can query a field value simply by calling a method on the value:
|
105
|
+
|
106
|
+
v1 = Versionomy.parse('1.2b3')
|
107
|
+
v1.major # => 1
|
108
|
+
v1.minor # => 2
|
109
|
+
v1.tiny # => 0
|
110
|
+
v1.tiny2 # => 0
|
111
|
+
v1.release_type # => :beta
|
112
|
+
v1.beta_version # => 3
|
113
|
+
v1.beta_minor # => 0
|
114
|
+
v1.release_candidate_version # raises NoMethodError
|
115
|
+
|
116
|
+
The above fields are merely the standard fields that Versionomy provides
|
117
|
+
out of the box. Versionomy also provides advanced users the ability to
|
118
|
+
define new version "schemas" with any number of different fields and
|
119
|
+
different semantics. See the RDocs for Versionomy::Schema for more
|
120
|
+
information.
|
121
|
+
|
122
|
+
=== Version number calculations
|
123
|
+
|
124
|
+
Version numbers can be compared (and thus sorted). Versionomy knows how to
|
125
|
+
handle prerelease versions and patchlevels correctly. It also compares the
|
126
|
+
semantic value so even if versions use an alternate syntax, they will be
|
127
|
+
compared correctly. Each of these expressions evaluates to true:
|
128
|
+
|
129
|
+
Versionomy.parse('1.2') < Versionomy.parse('1.10')
|
130
|
+
Versionomy.parse('1.2') > Versionomy.parse('1.2b3')
|
131
|
+
Versionomy.parse('1.2b3') > Versionomy.parse('1.2a4')
|
132
|
+
Versionomy.parse('1.2') < Versionomy.parse('1.2-p1')
|
133
|
+
Versionomy.parse('1.2') == Versionomy.parse('1.2-p0')
|
134
|
+
Versionomy.parse('1.2b3') == Versionomy.parse('1.2.0-beta3')
|
135
|
+
|
136
|
+
Versionomy automatically converts (parses) strings when comparing with a
|
137
|
+
version number, so you could even evaluate these:
|
138
|
+
|
139
|
+
Versionomy.parse('1.2') < '1.10'
|
140
|
+
Versionomy::VERSION > '0.2'
|
141
|
+
|
142
|
+
The Versionomy API provides various methods for manipulating fields such as
|
143
|
+
bumping, resetting to default, and changing to an arbitrary value. Version
|
144
|
+
numbers are always immutable, so changing a version number always produces
|
145
|
+
a copy. Below are a few examples. See the RDocs for the class
|
146
|
+
Versionomy::Value for more details.
|
147
|
+
|
148
|
+
v_orig = Versionomy.parse('1.2b3')
|
149
|
+
v1 = v_orig.change(:beta_version => 4) # creates version "1.2b4"
|
150
|
+
v2 = v_orig.change(:tiny => 4) # creates version "1.2.4b3"
|
151
|
+
v3 = v_orig.bump(:minor) # creates version "1.3"
|
152
|
+
v4 = v_orig.bump(:release_type) # creates version "1.2rc1"
|
153
|
+
v5 = v_orig.reset(:minor) # creates version "1.0"
|
154
|
+
|
155
|
+
A few more common calculations are also provided:
|
156
|
+
|
157
|
+
v_orig = Versionomy.parse('1.2b3')
|
158
|
+
v_orig.prerelease? # => true
|
159
|
+
v6 = v_orig.release # creates version "1.2"
|
160
|
+
|
161
|
+
=== Parsing and unparsing
|
162
|
+
|
163
|
+
Versionomy's parsing and unparsing services appear simple from the outside,
|
164
|
+
but a closer look reveals some sophisticated features. Parsing is as simple
|
165
|
+
as passing a string to Versionomy#parse, and unparsing is as simple as
|
166
|
+
calling Versionomy::Value#unparse or Versionomy::Value#to_s.
|
167
|
+
|
168
|
+
v = Versionomy.parse('1.2b3') # Create a Versionomy::Value
|
169
|
+
v.unparse # => "1.2b3"
|
170
|
+
|
171
|
+
Versionomy does its best to preserve the original syntax when parsing a
|
172
|
+
version string, so that syntax can be used when unparsing.
|
173
|
+
|
174
|
+
v1 = Versionomy.parse('1.2b3')
|
175
|
+
v2 = Versionomy.parse('1.2.0-beta3')
|
176
|
+
v1 == b2 # => true
|
177
|
+
v1.unparse # => "1.2b3"
|
178
|
+
v2.unparse # => "1.2.0-beta3"
|
179
|
+
|
180
|
+
Versionomy even preserves the original syntax when changing a value:
|
181
|
+
|
182
|
+
v1 = Versionomy.parse('1.2b3')
|
183
|
+
v2 = Versionomy.parse('1.2.0.0b3')
|
184
|
+
v1 == v2 # => true
|
185
|
+
v1r = v1.release
|
186
|
+
v2r = v2.release
|
187
|
+
v1r == v2r # => true
|
188
|
+
v1r.unparse # => "1.2"
|
189
|
+
v2r.unparse # => "1.2.0.0"
|
190
|
+
|
191
|
+
You can change the settings manually when unparsing a value.
|
192
|
+
|
193
|
+
v1 = Versionomy.parse('1.2b3')
|
194
|
+
v1.unparse # => "1.2b3"
|
195
|
+
v1.unparse(:required_fields => :tiny) # => "1.2.0b3"
|
196
|
+
v1.unparse(:release_type_delim => '-',
|
197
|
+
:release_type_style => :long) # => "1.2-beta3"
|
198
|
+
|
199
|
+
Versionomy also supports serialization using Marshal and YAML.
|
200
|
+
|
201
|
+
require 'yaml'
|
202
|
+
v1 = Versionomy.parse('1.2b3')
|
203
|
+
v1.unparse # => "1.2b3"
|
204
|
+
str = v1.to_yaml
|
205
|
+
v2 = YAML.load(str)
|
206
|
+
v2.unparse # => "1.2b3"
|
207
|
+
|
208
|
+
=== Customized formats
|
209
|
+
|
210
|
+
Although the standard parser used by Versionomy is likely sufficient for
|
211
|
+
most common syntaxes, Versionomy also lets you customize the parser for an
|
212
|
+
unusual syntax. Here is an example of a customized formatter for version
|
213
|
+
numbers used by a certain large software company:
|
214
|
+
|
215
|
+
year_sp_format = Versionomy.default_format.modified_copy do
|
216
|
+
field(:minor) do
|
217
|
+
recognize_number(:default_value_optional => true,
|
218
|
+
:delimiter_regexp => '\s?sp',
|
219
|
+
:default_delimiter => ' SP')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
v1 = year_sp_format.parse('2008 SP2')
|
223
|
+
v1.major # => 2008
|
224
|
+
v1.minor # => 2
|
225
|
+
v1.unparse # => "2008 SP2"
|
226
|
+
v1 == "2008.2" # => true
|
227
|
+
v2 = v1.bump(:minor)
|
228
|
+
v2.unparse # => "2008 SP3"
|
229
|
+
|
230
|
+
The above example uses a powerful DSL provided by Versionomy to create a
|
231
|
+
specialized parser. In most cases, this DSL will be powerful enough to
|
232
|
+
handle your parsing needs; in fact Versionomy's entire standard parser is
|
233
|
+
written using the DSL. However, in case you need to parse very unusual
|
234
|
+
syntax, you can also write an arbitrary parser. See the RDocs for the
|
235
|
+
Versionomy::Format::Delimiter class for more information on the DSL. See
|
236
|
+
the RDocs for the Versionomy::Format::Base class for information on the
|
237
|
+
interface you need to implement to write an arbitrary parser.
|
238
|
+
|
239
|
+
If you create a format, you can register it with Versionomy and provide a
|
240
|
+
name for it. This will allow you to reference it easily, as well as allow
|
241
|
+
Versionomy to serialize versions created with your custom format. See the
|
242
|
+
RDocs for the Versionomy::Format module for more information.
|
243
|
+
|
244
|
+
Versionomy::Format.register("bigcompany.versionformat", year_sp_format)
|
245
|
+
v1 = Versionomy.parse("2009 SP1", "bigcompany.versionformat")
|
246
|
+
|
247
|
+
Note that versions in the year_sp_format example can be compared with
|
248
|
+
versions using the standard parser. This is because the versions actually
|
249
|
+
share the same schema-- that is, they have the same fields. We have merely
|
250
|
+
changed the parser.
|
251
|
+
|
252
|
+
Recall that it is also possible to change the schema (the fields). This is
|
253
|
+
also done via a DSL (see the Versionomy::Schema module and its contents).
|
254
|
+
Version numbers with different schemas cannot normally be compared, because
|
255
|
+
they have different fields and different semantics. You can, however,
|
256
|
+
define ways to convert version numbers from one schema to another. See the
|
257
|
+
Versionomy::Conversion module and its contents for details.
|
258
|
+
|
259
|
+
Versionomy provides an example of a custom schema with its own custom
|
260
|
+
format, designed to mimic the Rubygems version class. This can be accessed
|
261
|
+
using the format registered under the name "rubygems". Conversion functions
|
262
|
+
are also provided between the rubygems and standard schemas.
|
263
|
+
|
264
|
+
v1 = Versionomy.parse("1.2b3") # Standard schema/format
|
265
|
+
v2 = Versionomy.parse("1.2.b.4", :rubygems) # Rubygems schema/format
|
266
|
+
v2.field0 # => 1
|
267
|
+
# (Rubygems fields have different names)
|
268
|
+
v1a = v1.convert(:rubygems) # creates rubygems version "1.2.b.3"
|
269
|
+
v2a = v2.convert(:standard) # creates standard version "1.2b4"
|
270
|
+
v1 < v2 # => true
|
271
|
+
# (Schemas are different but Versionomy
|
272
|
+
# autoconverts if possible)
|
273
|
+
v2 < v1 # => false
|
274
|
+
v3 = Versionomy.parse("1.2.foo", :rubygems) # rubygems schema/format
|
275
|
+
v3a = v3.convert(:standard) # raises Versionomy::Errors::ConversionError
|
276
|
+
# (Value not convertable to standard)
|
277
|
+
v1 < v3 # raises Versionomy::Errors::SchemaMismatchError
|
278
|
+
# (Autoconversion failed)
|
279
|
+
v3 > v1 # => true
|
280
|
+
# (Autoconversion is attempted only on the
|
281
|
+
# the second value, and this one succeeds.)
|
282
|
+
|
283
|
+
The APIs for defining schemas, formats, and conversions are rather complex.
|
284
|
+
I recommend looking through the examples in the modules
|
285
|
+
Versionomy::Format::Standard, Versionomy::Format::Rubygems, and
|
286
|
+
Versionomy::Conversion::Rubygems for further information.
|
287
|
+
|
288
|
+
=== Requirements
|
289
|
+
|
290
|
+
* Ruby 1.8.6 or later (1.8.7 recommended), Ruby 1.9.1 or later, or JRuby
|
291
|
+
1.4 or later.
|
292
|
+
* blockenspiel 0.3.1 or later.
|
293
|
+
|
294
|
+
=== Installation
|
295
|
+
|
296
|
+
gem install versionomy
|
297
|
+
|
298
|
+
=== Known issues and limitations
|
299
|
+
|
300
|
+
* Test coverage is still a little skimpy. It is focused on the "standard"
|
301
|
+
version number format and schema, but doesn't fully exercise all the
|
302
|
+
capabilities of custom formats.
|
303
|
+
|
304
|
+
=== Development and support
|
305
|
+
|
306
|
+
Documentation is available at http://virtuoso.rubyforge.org/versionomy/README_rdoc.html
|
307
|
+
|
308
|
+
Source code is hosted on Github at http://github.com/dazuma/versionomy
|
309
|
+
|
310
|
+
Report bugs on Github issues at http://github.org/dazuma/versionomy/issues
|
311
|
+
|
312
|
+
Contact the author at dazuma at gmail dot com.
|
313
|
+
|
314
|
+
=== Author / Credits
|
315
|
+
|
316
|
+
Versionomy is written by Daniel Azuma (http://www.daniel-azuma.com/).
|
317
|
+
|
318
|
+
== LICENSE:
|
319
|
+
|
320
|
+
Copyright 2008-2009 Daniel Azuma.
|
321
|
+
|
322
|
+
All rights reserved.
|
323
|
+
|
324
|
+
Redistribution and use in source and binary forms, with or without
|
325
|
+
modification, are permitted provided that the following conditions are met:
|
326
|
+
|
327
|
+
* Redistributions of source code must retain the above copyright notice,
|
328
|
+
this list of conditions and the following disclaimer.
|
329
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
330
|
+
this list of conditions and the following disclaimer in the documentation
|
331
|
+
and/or other materials provided with the distribution.
|
332
|
+
* Neither the name of the copyright holder, nor the names of any other
|
333
|
+
contributors to this software, may be used to endorse or promote products
|
334
|
+
derived from this software without specific prior written permission.
|
335
|
+
|
336
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
337
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
338
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
339
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
340
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
341
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
342
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
343
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
344
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
345
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
346
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/lib/versionomy.rb
CHANGED
@@ -47,13 +47,10 @@ includes_ = [
|
|
47
47
|
'format',
|
48
48
|
'format/base',
|
49
49
|
'format/delimiter',
|
50
|
-
'format/standard',
|
51
|
-
'format/rubygems',
|
52
50
|
'value',
|
53
51
|
'conversion',
|
54
52
|
'conversion/base',
|
55
53
|
'conversion/parsing',
|
56
|
-
'conversion/rubygems',
|
57
54
|
'interface',
|
58
55
|
'version',
|
59
56
|
]
|
@@ -34,6 +34,9 @@
|
|
34
34
|
;
|
35
35
|
|
36
36
|
|
37
|
+
require 'thread'
|
38
|
+
|
39
|
+
|
37
40
|
module Versionomy
|
38
41
|
|
39
42
|
|
@@ -60,7 +63,8 @@ module Versionomy
|
|
60
63
|
|
61
64
|
module Conversion
|
62
65
|
|
63
|
-
@registry =
|
66
|
+
@registry = {}
|
67
|
+
@mutex = ::Mutex.new
|
64
68
|
|
65
69
|
class << self
|
66
70
|
|
@@ -95,7 +99,7 @@ module Versionomy
|
|
95
99
|
|
96
100
|
def get(from_schema_, to_schema_, strict_=false)
|
97
101
|
key_ = _get_key(from_schema_, to_schema_)
|
98
|
-
conversion_ = @registry[key_]
|
102
|
+
conversion_ = @mutex.synchronize{ @registry[key_] }
|
99
103
|
if strict_ && conversion_.nil?
|
100
104
|
raise Errors::UnknownConversionError
|
101
105
|
end
|
@@ -114,12 +118,17 @@ module Versionomy
|
|
114
118
|
# Raises Versionomy::Errors::UnknownFormatError if a format was
|
115
119
|
# specified by name but the name is not known.
|
116
120
|
|
117
|
-
def register(from_schema_, to_schema_, conversion_)
|
121
|
+
def register(from_schema_, to_schema_, conversion_, silent_=false)
|
118
122
|
key_ = _get_key(from_schema_, to_schema_)
|
119
|
-
|
120
|
-
|
123
|
+
@mutex.synchronize do
|
124
|
+
if @registry.include?(key_)
|
125
|
+
unless silent_
|
126
|
+
raise Errors::ConversionRedefinedError
|
127
|
+
end
|
128
|
+
else
|
129
|
+
@registry[key_] = conversion_
|
130
|
+
end
|
121
131
|
end
|
122
|
-
@registry[key_] = conversion_
|
123
132
|
end
|
124
133
|
|
125
134
|
|