versionomy 0.1.3 → 0.2.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/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
|