versionomy 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +15 -1
- data/README.rdoc +73 -22
- data/Rakefile +1 -1
- data/lib/versionomy/{formats.rb → conversion/base.rb} +36 -37
- data/lib/versionomy/conversion/parsing.rb +173 -0
- data/lib/versionomy/conversion/rubygems.rb +138 -0
- data/lib/versionomy/conversion.rb +145 -0
- data/lib/versionomy/errors.rb +22 -2
- data/lib/versionomy/format/base.rb +53 -5
- data/lib/versionomy/format/delimiter.rb +39 -27
- data/lib/versionomy/format/rubygems.rb +234 -0
- data/lib/versionomy/format/standard.rb +382 -0
- data/lib/versionomy/format.rb +73 -4
- data/lib/versionomy/interface.rb +22 -14
- data/lib/versionomy/schema/field.rb +14 -5
- data/lib/versionomy/schema/wrapper.rb +84 -10
- data/lib/versionomy/schema.rb +9 -6
- data/lib/versionomy/value.rb +191 -53
- data/lib/versionomy/version.rb +1 -1
- data/lib/versionomy.rb +6 -2
- data/tests/tc_custom_format.rb +4 -4
- data/tests/tc_readme_examples.rb +9 -9
- data/tests/tc_rubygems_basic.rb +210 -0
- data/tests/tc_rubygems_conversions.rb +178 -0
- data/tests/tc_standard_basic.rb +10 -10
- data/tests/tc_standard_bump.rb +10 -10
- data/tests/tc_standard_change.rb +5 -5
- data/tests/tc_standard_comparison.rb +29 -16
- data/tests/tc_standard_misc.rb +95 -0
- data/tests/tc_standard_parse.rb +43 -23
- metadata +15 -5
- data/lib/versionomy/formats/standard.rb +0 -346
data/History.rdoc
CHANGED
@@ -1,6 +1,20 @@
|
|
1
|
+
=== 0.2.0 / 2009-11-05
|
2
|
+
|
3
|
+
* API CHANGE: Slight change to value comparison semantics. Value#eql? returns true only if the schemas are the same, whereas Value#== and the greater than and less than comparisons attempt to compare the semantic value, and thus may perform automatic schema conversion on the RHS.
|
4
|
+
* API CHANGE: Merged Formats namespace into Format. Versionomy::Formats is now a (deprecated) alias for Versionomy::Format.
|
5
|
+
* API CHANGE: The delimiter parsing algorithm now defaults :extra_characters to :error instead of :ignore.
|
6
|
+
* Added a mechanism for converting from one format/schema to another.
|
7
|
+
* Added Rubygems format, along with conversions to and from the standard format.
|
8
|
+
* Values now include Comparable.
|
9
|
+
* Values can now be serialized using Marshal and YAML.
|
10
|
+
* Schemas can now add custom methods to value objects. Added "prerelease?" and "release" methods to rubygems and standard format values.
|
11
|
+
* Added default field settings to schema DSL.
|
12
|
+
* Implemented #=== for schemas and formats.
|
13
|
+
* Many minor bug fixes and documentation updates.
|
14
|
+
|
1
15
|
=== 0.1.3 / 2009-10-29
|
2
16
|
|
3
|
-
* Fixed an issue with parsing the "-p" patchlevel delimiter
|
17
|
+
* Fixed an issue with parsing the "-p" patchlevel delimiter, e.g. "1.9.1-p243". (Reported by Luis Lavena.)
|
4
18
|
|
5
19
|
=== 0.1.2 / 2009-10-28
|
6
20
|
|
data/README.rdoc
CHANGED
@@ -4,15 +4,46 @@ 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
|
+
=== Version numbers done right?
|
8
|
+
|
9
|
+
Let's be honest. Version numbers are not easy to deal with, and very
|
10
|
+
seldom seem to be done right.
|
11
|
+
Imagine the common case of testing the Ruby version. Most of us, if we
|
12
|
+
need to worry about Ruby VM compatibility, will do something like:
|
13
|
+
|
14
|
+
do_something if RUBY_VERSION >= "1.8.7"
|
15
|
+
|
16
|
+
Treating the version number as a string works well enough, until it
|
17
|
+
doesn't. The above code will do the right thing for Ruby 1.8.6, 1.8.7,
|
18
|
+
1.8.8, and 1.9.1. But it will fail if the version is "1.8.10".
|
19
|
+
|
20
|
+
There are a few version number classes out there that do better than
|
21
|
+
treating version numbers as plain strings. One well-known class is
|
22
|
+
Gem::Version, part of rubygems. This class separates the version into
|
23
|
+
fields and lets you manipulate and compare version numbers more robustly.
|
24
|
+
It provides limited support for "prerelease" versions through using
|
25
|
+
string-valued fields as a bit of a hack. However, it's still a little
|
26
|
+
clumsy. A prerelease version has to be represented like this: "1.9.2.b.1"
|
27
|
+
or "1.9.2.preview.2". Wouldn't it be nice to be able to parse more typical
|
28
|
+
version number formats such as "1.9.2b1" and "1.9.2 preview-2"? Wouldn't
|
29
|
+
it be nice for a version like "1.9.2b1" to _understand_ that it's a "beta"
|
30
|
+
version and behave accordingly?
|
31
|
+
|
32
|
+
With Versionomy, you can!
|
33
|
+
|
7
34
|
=== Some examples
|
8
35
|
|
9
36
|
require 'versionomy'
|
10
37
|
|
11
|
-
|
38
|
+
# Create version numbers that understand their own semantics
|
39
|
+
v1 = Versionomy.create(:major => 1, :minor => 3, :tiny => 2)
|
12
40
|
v1.major # => 1
|
13
41
|
v1.minor # => 3
|
14
42
|
v1.tiny # => 2
|
43
|
+
v1.release_type # => :final
|
44
|
+
v1.patchlevel # => 0
|
15
45
|
|
46
|
+
# Parse version numbers, including common prerelease syntax
|
16
47
|
v2 = Versionomy.parse('1.4a3')
|
17
48
|
v2.major # => 1
|
18
49
|
v2.minor # => 4
|
@@ -20,7 +51,9 @@ numbers in the wide variety of versioning schemes in use.
|
|
20
51
|
v2.release_type # => :alpha
|
21
52
|
v2.alpha_version # => 3
|
22
53
|
v2 > v1 # => true
|
54
|
+
v2.to_s # => '1.4a3'
|
23
55
|
|
56
|
+
# Another parsing example.
|
24
57
|
v3 = Versionomy.parse('1.4.0b2')
|
25
58
|
v3.major # => 1
|
26
59
|
v3.minor # => 4
|
@@ -31,29 +64,44 @@ numbers in the wide variety of versioning schemes in use.
|
|
31
64
|
v3 > v2 # => true
|
32
65
|
v3.to_s # => '1.4.0b2'
|
33
66
|
|
34
|
-
|
67
|
+
# You can bump any field
|
68
|
+
v4 = Versionomy.parse('1.4.0b2').bump(:beta_version)
|
35
69
|
v4.to_s # => '1.4.0b3'
|
70
|
+
v5 = v4.bump(:tiny)
|
71
|
+
v5.to_s # => '1.4.1'
|
36
72
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
v6
|
41
|
-
|
42
|
-
|
43
|
-
v7
|
44
|
-
v7.to_s # => '1.4.1'
|
73
|
+
# Bumping the release type works as you would expect
|
74
|
+
v6 = Versionomy.parse('1.4.0b2').bump(:release_type)
|
75
|
+
v6.release_type # => :release_candidate
|
76
|
+
v6.to_s # => '1.4.0rc1'
|
77
|
+
v7 = v6.bump(:release_type)
|
78
|
+
v7.release_type # => :final
|
79
|
+
v7.to_s # => '1.4.0'
|
45
80
|
|
46
|
-
|
81
|
+
# If a version has trailing zeros, it remembers how many fields to
|
82
|
+
# unparse; however, you can also change this.
|
83
|
+
v8 = Versionomy.parse('1.4.0b2').bump(:major)
|
47
84
|
v8.to_s # => '2.0.0'
|
48
85
|
v8.unparse(:optional_fields => [:tiny]) # => '2.0'
|
86
|
+
v8.unparse(:required_fields => [:tiny2]) # => '2.0.0.0'
|
49
87
|
|
88
|
+
# Comparisons are semantic, so will behave as expected even if the
|
89
|
+
# formatting is set up differently.
|
50
90
|
v9 = Versionomy.parse('2.0.0.0')
|
51
91
|
v9.to_s # => '2.0.0.0'
|
52
|
-
v9 ==
|
92
|
+
v9 == Versionomy.parse('2') # => true
|
53
93
|
|
54
|
-
|
94
|
+
# Patchlevels are supported when the release type is :final
|
95
|
+
v10 = Versionomy.parse('2.0.0').bump(:patchlevel)
|
96
|
+
v10.patchlevel # => 1
|
55
97
|
v10.to_s # => '2.0.0-1'
|
98
|
+
v11 = Versionomy.parse('2.0p1')
|
99
|
+
v11.patchlevel # => 1
|
100
|
+
v11.to_s # => '2.0p1'
|
101
|
+
v11 == v10 # => true
|
56
102
|
|
103
|
+
# You can create your own format from scratch or by modifying an
|
104
|
+
# existing format
|
57
105
|
microsoft_format = Versionomy.default_format.modified_copy do
|
58
106
|
field(:minor) do
|
59
107
|
recognize_number(:default_value_optional => true,
|
@@ -61,12 +109,12 @@ numbers in the wide variety of versioning schemes in use.
|
|
61
109
|
:default_delimiter => ' SP')
|
62
110
|
end
|
63
111
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
112
|
+
v12 = microsoft_format.parse('2008 SP2')
|
113
|
+
v12.major # => 2008
|
114
|
+
v12.minor # => 2
|
115
|
+
v12.tiny # => 0
|
116
|
+
v12.to_s # => '2008 SP2'
|
117
|
+
v12 == Versionomy.parse('2008.2') # => true
|
70
118
|
|
71
119
|
=== Feature list
|
72
120
|
|
@@ -82,12 +130,15 @@ custom formats.
|
|
82
130
|
|
83
131
|
Finally, Versionomy also lets you to create alternate versioning "schemas".
|
84
132
|
You can define any number of version number fields, and provide your own
|
85
|
-
semantics for comparing, parsing, and modifying version numbers.
|
133
|
+
semantics for comparing, parsing, and modifying version numbers. You can
|
134
|
+
provide conversions from one schema to another. As an example, Versionomy
|
135
|
+
provides a schema and formatter/parser matching Gem::Version.
|
86
136
|
|
87
137
|
=== Requirements
|
88
138
|
|
89
|
-
* Ruby 1.8.6 or later (1.8.7 recommended), Ruby 1.9.1 or later, or JRuby
|
90
|
-
|
139
|
+
* Ruby 1.8.6 or later (1.8.7 recommended), Ruby 1.9.1 or later, or JRuby
|
140
|
+
1.4 or later.
|
141
|
+
* blockenspiel 0.3 or later.
|
91
142
|
|
92
143
|
=== Installation
|
93
144
|
|
data/Rakefile
CHANGED
@@ -89,7 +89,7 @@ gemspec_ = Gem::Specification.new do |s_|
|
|
89
89
|
s_.has_rdoc = true
|
90
90
|
s_.test_files = FileList['tests/tc_*.rb']
|
91
91
|
s_.platform = Gem::Platform::RUBY
|
92
|
-
s_.add_dependency('blockenspiel', '>= 0.
|
92
|
+
s_.add_dependency('blockenspiel', '>= 0.3.0')
|
93
93
|
end
|
94
94
|
Rake::GemPackageTask.new(gemspec_) do |task_|
|
95
95
|
task_.need_zip = false
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
2
|
#
|
3
|
-
# Versionomy
|
3
|
+
# Versionomy conversion base class
|
4
4
|
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2008-2009 Daniel Azuma
|
@@ -37,51 +37,50 @@
|
|
37
37
|
module Versionomy
|
38
38
|
|
39
39
|
|
40
|
-
|
41
|
-
#
|
42
|
-
# Use the methods of this module to register formats with a name. This
|
43
|
-
# allows version numbers to be serialized with their format.
|
44
|
-
#
|
45
|
-
# You may also access predefined formats such as the standard format from
|
46
|
-
# this module. It also contains the implementations of these formats as
|
47
|
-
# examples.
|
48
|
-
|
49
|
-
module Formats
|
50
|
-
|
51
|
-
|
52
|
-
@names = ::Hash.new
|
40
|
+
module Conversion
|
53
41
|
|
54
42
|
|
55
|
-
#
|
43
|
+
# The base conversion class.
|
56
44
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
45
|
+
# This base class defines the API for a conversion. All conversions must
|
46
|
+
# define the method <tt>convert_value</tt> documented here. Conversions
|
47
|
+
# need not actually extend this base class, as long as they duck-type
|
48
|
+
# this method. However, this base class does provide a few convenience
|
49
|
+
# methods such as a sane implementation of inspect.
|
60
50
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
51
|
+
class Base
|
52
|
+
|
53
|
+
|
54
|
+
# Convert the given value to the given format and return the converted
|
55
|
+
# value.
|
56
|
+
#
|
57
|
+
# The convert_params may be interpreted however the particular
|
58
|
+
# conversion wishes.
|
59
|
+
#
|
60
|
+
# Raises Versionomy::Errors::ConversionError if the conversion failed.
|
61
|
+
|
62
|
+
def convert_value(value_, format_, convert_params_=nil)
|
63
|
+
raise Errors::ConversionError, "Conversion not implemented"
|
65
64
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
# Raises Versionomy::Errors::FormatRedefinedError if the name has
|
73
|
-
# already been defined.
|
74
|
-
|
75
|
-
def self.register(name_, format_)
|
76
|
-
name_ = name_.to_s
|
77
|
-
if @names.include?(name_)
|
78
|
-
raise Errors::FormatRedefinedError, name_
|
65
|
+
|
66
|
+
|
67
|
+
# Inspect this conversion.
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
"#<#{self.class}:0x#{object_id.to_s(16)}>"
|
79
71
|
end
|
80
|
-
|
72
|
+
|
73
|
+
|
74
|
+
# The default to_s implementation just calls inspect.
|
75
|
+
|
76
|
+
def to_s
|
77
|
+
inspect
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
81
|
end
|
82
82
|
|
83
83
|
|
84
84
|
end
|
85
85
|
|
86
|
-
|
87
86
|
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Versionomy conversion base class
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2008-2009 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
|
+
module Conversion
|
41
|
+
|
42
|
+
|
43
|
+
# A conversion strategy that relies on parsing.
|
44
|
+
# Essentially, it unparses the value and then attempts to parse it with
|
45
|
+
# the new format.
|
46
|
+
|
47
|
+
class Parsing < Base
|
48
|
+
|
49
|
+
|
50
|
+
# Create a parsing conversion.
|
51
|
+
#
|
52
|
+
# By default, this just unparses and reparses using the default
|
53
|
+
# parse settings. In some cases, this may be enough, but you may
|
54
|
+
# wish to improve the reliability of the conversion by tweaking the
|
55
|
+
# parsing settings. To do so, pass a block to the new method, and
|
56
|
+
# call methods of Versionomy::Conversion::Parsing::Builder in that
|
57
|
+
# block.
|
58
|
+
|
59
|
+
def initialize(&block_)
|
60
|
+
if block_
|
61
|
+
builder_ = Builder.new
|
62
|
+
::Blockenspiel.invoke(block_, builder_)
|
63
|
+
@string_modifier = builder_._get_string_modifier
|
64
|
+
@unparse_params_modifier = builder_._get_unparse_params_modifier
|
65
|
+
@parse_params_generator ||= builder_._get_parse_params_generator
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# Returns a value equivalent to the given value in the given format.
|
71
|
+
#
|
72
|
+
# The convert_params are passed to this conversion's customization
|
73
|
+
# blocks (if any).
|
74
|
+
#
|
75
|
+
# Raises Versionomy::Errors::ConversionError if the conversion failed.
|
76
|
+
# Typically, this is due to a failure of the parsing or unparsing.
|
77
|
+
|
78
|
+
def convert_value(value_, format_, convert_params_=nil)
|
79
|
+
begin
|
80
|
+
unparse_params_ = value_.unparse_params
|
81
|
+
if @unparse_params_modifier
|
82
|
+
unparse_params_ = @unparse_params_modifier.call(unparse_params_, convert_params_)
|
83
|
+
end
|
84
|
+
string_ = value_.unparse(unparse_params_)
|
85
|
+
if @string_modifier
|
86
|
+
string_ = @string_modifier.call(string_, convert_params_)
|
87
|
+
end
|
88
|
+
if @parse_params_generator
|
89
|
+
parse_params_ = @parse_params_generator.call(convert_params_)
|
90
|
+
else
|
91
|
+
parse_params_ = nil
|
92
|
+
end
|
93
|
+
new_value_ = format_.parse(string_, parse_params_)
|
94
|
+
return new_value_
|
95
|
+
rescue Errors::UnparseError => ex_
|
96
|
+
raise Errors::ConversionError, "Unparsing failed: #{ex_.inspect}"
|
97
|
+
rescue Errors::ParseError => ex_
|
98
|
+
raise Errors::ConversionError, "Parsing failed: #{ex_.inspect}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# Call methods of this class in the block passed to
|
104
|
+
# Versionomy::Conversion::Parsing#new to fine-tune the behavior of
|
105
|
+
# the converter.
|
106
|
+
|
107
|
+
class Builder
|
108
|
+
|
109
|
+
include ::Blockenspiel::DSL
|
110
|
+
|
111
|
+
|
112
|
+
def initialize # :nodoc:
|
113
|
+
@string_modifier = nil
|
114
|
+
@parse_params_generator = nil
|
115
|
+
@unparse_params_modifier = nil
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Provide a block that generates the params used to parse the new
|
120
|
+
# value. The block should take one parameter, the convert_params
|
121
|
+
# passed to convert_value (which may be nil). It should return the
|
122
|
+
# parse params that should be used.
|
123
|
+
|
124
|
+
def to_generate_parse_params(&block_)
|
125
|
+
@parse_params_generator = block_
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
# Provide a block that can modify the params used to unparse the
|
130
|
+
# old value. The block should take two parameters: first, the
|
131
|
+
# original unparse params from the old value (which may be nil),
|
132
|
+
# and second, the convert_params passed to convert_value (which
|
133
|
+
# may also be nil). It should return the unparse params that
|
134
|
+
# should actually be used.
|
135
|
+
|
136
|
+
def to_modify_unparse_params(&block_)
|
137
|
+
@unparse_params_modifier = block_
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Provide a block that can modify the unparsed string prior to
|
142
|
+
# it being passed to the parser. The block should take two
|
143
|
+
# parameters: first, the string resulting from unparsing the old
|
144
|
+
# value, and second, the convert_params passed to convert_value
|
145
|
+
# (which may be nil). It should return the string to be parsed to
|
146
|
+
# get the new value.
|
147
|
+
|
148
|
+
def to_modify_string(&block_)
|
149
|
+
@string_modifier = block_
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def _get_string_modifier # :nodoc:
|
154
|
+
@string_modifier
|
155
|
+
end
|
156
|
+
|
157
|
+
def _get_unparse_params_modifier # :nodoc:
|
158
|
+
@unparse_params_modifier
|
159
|
+
end
|
160
|
+
|
161
|
+
def _get_parse_params_generator # :nodoc:
|
162
|
+
@parse_params_generator
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Versionomy standard format implementation
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2008-2009 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
|
+
module Conversion
|
40
|
+
|
41
|
+
|
42
|
+
# This is a namespace for the implementation of the conversion between
|
43
|
+
# the rubygems and standard formats.
|
44
|
+
|
45
|
+
module Rubygems
|
46
|
+
|
47
|
+
|
48
|
+
# Create the conversion from standard to rubygems format.
|
49
|
+
# This method is called internally when Versionomy initializes itself,
|
50
|
+
# and you should not need to call it again. It is documented, however,
|
51
|
+
# so that you can inspect its source code from RDoc, since the source
|
52
|
+
# contains useful examples of how to use the conversion DSLs.
|
53
|
+
|
54
|
+
def self.create_standard_to_rubygems
|
55
|
+
|
56
|
+
# We'll use a parsing conversion.
|
57
|
+
Conversion::Parsing.new do
|
58
|
+
|
59
|
+
# We're going to modify how the standard format version is
|
60
|
+
# unparsed, so the rubygems format will have a better chance
|
61
|
+
# of parsing it.
|
62
|
+
to_modify_unparse_params do |params_, convert_params_|
|
63
|
+
|
64
|
+
params_ ||= {}
|
65
|
+
|
66
|
+
# If the standard format version has a prerelease notation,
|
67
|
+
# make sure it is set off using a delimiter that the rubygems
|
68
|
+
# format can recognized. So instead of "1.0b2", we force the
|
69
|
+
# unparsing to generate "1.0.b.2".
|
70
|
+
params_[:release_type_delim] = '.'
|
71
|
+
params_[:release_type_postdelim] = '.'
|
72
|
+
|
73
|
+
# If the standard format version has a patchlevel notation,
|
74
|
+
# force it to use the default number rather than letter style.
|
75
|
+
# So instead of "1.2c", we force the unparsing to generate
|
76
|
+
# "1.2-3".
|
77
|
+
params_[:patchlevel_style] = nil
|
78
|
+
|
79
|
+
# If the standard format version has a patchlevel notation,
|
80
|
+
# force it to use the default delimiter of "-" so the rubygems
|
81
|
+
# format will recognize it. So instead of "1.9.1p243", we force
|
82
|
+
# the unparsing to generate "1.9.1-243".
|
83
|
+
params_[:patchlevel_delim] = nil
|
84
|
+
|
85
|
+
params_
|
86
|
+
end
|
87
|
+
|
88
|
+
# Standard formats sometimes allow hyphens and spaces in field
|
89
|
+
# delimiters, but the rubygems format requires periods. So modify
|
90
|
+
# the unparsed string to conform to rubygems's expectations.
|
91
|
+
to_modify_string do |str_, convert_params_|
|
92
|
+
str_.gsub(/[\.\s-]+/, '.')
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Create the conversion from rubygems to standard format.
|
101
|
+
# This method is called internally when Versionomy initializes itself,
|
102
|
+
# and you should not need to call it again. It is documented, however,
|
103
|
+
# so that you can inspect its source code from RDoc, since the source
|
104
|
+
# contains useful examples of how to use the conversion DSLs.
|
105
|
+
|
106
|
+
def self.create_rubygems_to_standard
|
107
|
+
|
108
|
+
# We'll use a parsing conversion.
|
109
|
+
Conversion::Parsing.new do
|
110
|
+
|
111
|
+
# Handle the case where the rubygems version ends with a string
|
112
|
+
# field, e.g. "1.0.b". We want to treat this like "1.0b0" rather
|
113
|
+
# than "1.0-2" since the rubygems semantic states that this is a
|
114
|
+
# prerelease version. So we add 0 to the end of the parsed string
|
115
|
+
# if it ends in a letter.
|
116
|
+
to_modify_string do |str_, convert_params_|
|
117
|
+
str_.gsub(/([[:alpha:]])\z/, '\10')
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
unless Conversion.get(:standard, :rubygems)
|
126
|
+
Conversion.register(:standard, :rubygems, create_standard_to_rubygems)
|
127
|
+
end
|
128
|
+
unless Conversion.get(:rubygems, :standard)
|
129
|
+
Conversion.register(:rubygems, :standard, create_rubygems_to_standard)
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|