richcss 0.1.1 → 0.1.3
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -3
- data/lib/richcss/part.rb +1 -1
- data/lib/richcss/resolver.rb +1 -1
- data/lib/richcss/richcss_specification_provider.rb +1 -1
- data/lib/richcss/vendor/version_kit/lib/version_kit.rb +9 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/dependency.rb +42 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/gem_metadata.rb +3 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/requirement.rb +143 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/requirement_list.rb +77 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/set.rb +25 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/version.rb +274 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/version/components_helper.rb +162 -0
- data/lib/richcss/vendor/version_kit/lib/version_kit/version/helper.rb +117 -0
- data/lib/richcss/version.rb +1 -1
- data/richcss.gemspec +5 -5
- metadata +30 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 366b8fb9be65306620313fa5a8f366121fbb1d85
|
4
|
+
data.tar.gz: dc610a0d85f1d6d086df8560ba4088595730c436
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71720c41734a75842e177180cdce7c2fc3cb466fe54db8670497d21f3e37f601aa1b119268d642f9651ac4763d32a040a843627f7a8a6919db414454820401ae
|
7
|
+
data.tar.gz: f2e84138469c33156861866a239f932892f01b3cabb4ddabe930daa019a5be905dae93aae0c5e9e36b0eb81c2d6ae7c19b8997398da89be2d22ab4acde06dd4f
|
data/Gemfile
CHANGED
data/lib/richcss/part.rb
CHANGED
@@ -49,7 +49,7 @@ module Richcss
|
|
49
49
|
homepage = homepage.split("\/")
|
50
50
|
repo_owner = homepage[0]
|
51
51
|
repo_name = homepage[1]
|
52
|
-
jsonResponse = JSON.parse(Net::HTTP.get(URI("https://api.github.com/repos/#{repo_owner}/#{repo_name}/releases/tags
|
52
|
+
jsonResponse = JSON.parse(Net::HTTP.get(URI("https://api.github.com/repos/#{repo_owner}/#{repo_name}/releases/tags/#{body["version"]}")))
|
53
53
|
downloadLink = jsonResponse["zipball_url"]
|
54
54
|
install(part_name, body["version"], downloadLink)
|
55
55
|
else
|
data/lib/richcss/resolver.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'richcss/vendor/version_kit/lib/version_kit/gem_metadata'
|
2
|
+
require 'richcss/vendor/version_kit/lib/version_kit/version'
|
3
|
+
require 'richcss/vendor/version_kit/lib/version_kit/requirement'
|
4
|
+
require 'richcss/vendor/version_kit/lib/version_kit/requirement_list'
|
5
|
+
require 'richcss/vendor/version_kit/lib/version_kit/dependency'
|
6
|
+
|
7
|
+
# VersionKit provides support for SemVer versioning and dependency resolution
|
8
|
+
module Richcss::VersionKit
|
9
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Richcss::VersionKit
|
2
|
+
#
|
3
|
+
#
|
4
|
+
class Dependency
|
5
|
+
# @return [String] The name
|
6
|
+
#
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
# @return [Array<Requirement>]
|
10
|
+
#
|
11
|
+
attr_accessor :requirement_list
|
12
|
+
|
13
|
+
#
|
14
|
+
#
|
15
|
+
def initialize(name, requirements)
|
16
|
+
@name = name
|
17
|
+
@requirement_list = RequirementList.new(requirements)
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
#
|
22
|
+
def satisfied_by?(candidate_version)
|
23
|
+
requirement_list.satisfied_by?(candidate_version)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @!group Object methods
|
27
|
+
#-------------------------------------------------------------------------#
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"#{name} (#{requirement_list})"
|
31
|
+
end
|
32
|
+
|
33
|
+
def ==(other)
|
34
|
+
name == other.name &&
|
35
|
+
requirement_list == other.requirement_list
|
36
|
+
end
|
37
|
+
|
38
|
+
def hash
|
39
|
+
name.hash ^ requirement_list.hash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Richcss::VersionKit
|
2
|
+
# Describes a constraint on the acceptable elements of a list of versions.
|
3
|
+
# The only relevant method for this class is the `#satisfied_by?` method.
|
4
|
+
#
|
5
|
+
# The optimistic requirement is deemed optimistic because the user if
|
6
|
+
# optimistic about the correct versioning of the software the requirement
|
7
|
+
# refers to.
|
8
|
+
#
|
9
|
+
class Requirement
|
10
|
+
# @return [String] The operator of the constraint.
|
11
|
+
#
|
12
|
+
attr_reader :operator
|
13
|
+
|
14
|
+
# @return [String] The reference version of the operator.
|
15
|
+
#
|
16
|
+
attr_reader :reference_version
|
17
|
+
|
18
|
+
# @return [Hash {String=>Lambda}] The operators supported by this class
|
19
|
+
# associated to the lambda used to evaluate them.
|
20
|
+
#
|
21
|
+
OPERATORS = ['=', '!=', '>', '<', '>=', '<=', '~>']
|
22
|
+
|
23
|
+
# @param [String] string The string representation of the requirement.
|
24
|
+
#
|
25
|
+
def initialize(string)
|
26
|
+
operator, reference_version = parse_string(string)
|
27
|
+
check_parsing(string, operator, reference_version)
|
28
|
+
|
29
|
+
@operator = operator
|
30
|
+
@reference_version = reference_version
|
31
|
+
@reference = Version.new(reference_version)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [String] candidate_version
|
35
|
+
#
|
36
|
+
# @return [Bool] Whether a given version is accepted by the given
|
37
|
+
# requirement.
|
38
|
+
#
|
39
|
+
# rubocop:disable MethodLength, CyclomaticComplexity
|
40
|
+
#
|
41
|
+
def satisfied_by?(candidate_version)
|
42
|
+
candidate = Version.new(candidate_version)
|
43
|
+
reference = @reference
|
44
|
+
|
45
|
+
case operator
|
46
|
+
when '=' then candidate == reference
|
47
|
+
when '!=' then candidate != reference
|
48
|
+
when '>' then candidate > reference
|
49
|
+
when '<' then candidate < reference
|
50
|
+
when '>=' then candidate >= reference
|
51
|
+
when '<=' then candidate <= reference
|
52
|
+
when '~>'
|
53
|
+
candidate >= reference && candidate < bumped_reference_version
|
54
|
+
end
|
55
|
+
end
|
56
|
+
#
|
57
|
+
# rubocop:enable MethodLength, CyclomaticComplexity
|
58
|
+
|
59
|
+
public
|
60
|
+
|
61
|
+
# @!group Object methods
|
62
|
+
#-------------------------------------------------------------------------#
|
63
|
+
|
64
|
+
# @return [String] the string representation of this class. The string is
|
65
|
+
# equivalent, but not strictly equal, to the one used on
|
66
|
+
# initialization.
|
67
|
+
#
|
68
|
+
def to_s
|
69
|
+
"#{operator} #{reference_version}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Fixnum] Useful for sorting a list of requirements.
|
73
|
+
#
|
74
|
+
def <=>(other)
|
75
|
+
to_s <=> other.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [Fixnum] The hash of the instance.
|
79
|
+
#
|
80
|
+
def hash
|
81
|
+
to_s.hash
|
82
|
+
end
|
83
|
+
|
84
|
+
def ==(other)
|
85
|
+
operator == other.operator &&
|
86
|
+
reference_version == other.reference_version
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# @!group Private Helpers
|
92
|
+
#-------------------------------------------------------------------------#
|
93
|
+
|
94
|
+
# @param [String] string
|
95
|
+
#
|
96
|
+
# @return [Array<String, String>]
|
97
|
+
#
|
98
|
+
def parse_string(string)
|
99
|
+
splitted = string.to_s.strip.split(' ')
|
100
|
+
if splitted.count == 1
|
101
|
+
operator = '='
|
102
|
+
version = splitted[0]
|
103
|
+
else
|
104
|
+
operator = splitted[0]
|
105
|
+
version = splitted[1]
|
106
|
+
end
|
107
|
+
@version_specificity = version.scan(/[^-+]+/).first.split('.').count
|
108
|
+
version = Version.normalize(version) if version
|
109
|
+
[operator, version]
|
110
|
+
end
|
111
|
+
|
112
|
+
# @param [String] string
|
113
|
+
#
|
114
|
+
# @param [String] operator
|
115
|
+
#
|
116
|
+
# @param [String] version
|
117
|
+
#
|
118
|
+
# @return [void] Checks that the initialization string and the result of
|
119
|
+
# the parsing are acceptable.
|
120
|
+
#
|
121
|
+
def check_parsing(string, operator, version)
|
122
|
+
unless OPERATORS.include?(operator)
|
123
|
+
raise ArgumentError, "Unsupported operator `#{operator}` " \
|
124
|
+
"requirement `#{string}`"
|
125
|
+
end
|
126
|
+
|
127
|
+
unless Version.valid?(version)
|
128
|
+
raise ArgumentError, "Malformed version `#{version}` for " \
|
129
|
+
"requirement `#{string}`"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# @return [Bool] Whether a given candidate versions is acceptable according
|
134
|
+
# to the optimistic operator (`~>`) given the reference version.
|
135
|
+
#
|
136
|
+
def bumped_reference_version
|
137
|
+
index = @version_specificity - 2
|
138
|
+
Version::Helper.bump(reference_version, index)
|
139
|
+
end
|
140
|
+
|
141
|
+
#-------------------------------------------------------------------------#
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Richcss::VersionKit
|
2
|
+
#
|
3
|
+
#
|
4
|
+
class RequirementList
|
5
|
+
# @return [Array<Requirement>]
|
6
|
+
#
|
7
|
+
attr_reader :requirements
|
8
|
+
|
9
|
+
#-------------------------------------------------------------------------#
|
10
|
+
|
11
|
+
# @param [Array<Requirement>] @see #requirements.
|
12
|
+
#
|
13
|
+
def initialize(requirements = [])
|
14
|
+
@requirements = Array(requirements).map do |requirement|
|
15
|
+
normalize_requirement(requirement)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [void]
|
20
|
+
#
|
21
|
+
def add_requirement(requirement)
|
22
|
+
requirement = normalize_requirement(requirement)
|
23
|
+
requirements << requirement
|
24
|
+
requirements.uniq!
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Bool]
|
28
|
+
#
|
29
|
+
def satisfied_by?(candidate_version)
|
30
|
+
requirements.all? do |requirement|
|
31
|
+
requirement.satisfied_by?(candidate_version)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
public
|
36
|
+
|
37
|
+
# @!group Object methods
|
38
|
+
#-------------------------------------------------------------------------#
|
39
|
+
|
40
|
+
# @return [String] the string representation of this class. The string is
|
41
|
+
# equivalent, but not strictly equal, to the one used on
|
42
|
+
# initialization.
|
43
|
+
#
|
44
|
+
def to_s
|
45
|
+
requirements.map(&:to_s).join(', ')
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Fixnum] The hash of the instance.
|
49
|
+
#
|
50
|
+
def hash
|
51
|
+
to_s.hash
|
52
|
+
end
|
53
|
+
|
54
|
+
def ==(other)
|
55
|
+
requirements == other.requirements
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# @!group Private Helpers
|
61
|
+
#-------------------------------------------------------------------------#
|
62
|
+
|
63
|
+
def normalize_requirement(requirement)
|
64
|
+
case requirement
|
65
|
+
when Requirement
|
66
|
+
requirement
|
67
|
+
when String, Version
|
68
|
+
Requirement.new(requirement)
|
69
|
+
else
|
70
|
+
raise ArgumentError, 'Unable to normalize requirement ' \
|
71
|
+
"`#{requirement.inspect}`"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#-------------------------------------------------------------------------#
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Richcss::VersionKit
|
2
|
+
#
|
3
|
+
#
|
4
|
+
class Set
|
5
|
+
# @return [String] the name of the Pod.
|
6
|
+
#
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
# @return [Array<Source>] the sources that contain the specifications for
|
10
|
+
# the available versions of a Pod.
|
11
|
+
#
|
12
|
+
attr_reader :versions
|
13
|
+
|
14
|
+
# @param [String] name
|
15
|
+
# the name of the Pod.
|
16
|
+
#
|
17
|
+
# @param [Array<Source>,Source] sources
|
18
|
+
# the sources that contain a Pod.
|
19
|
+
#
|
20
|
+
def initialize(name, versions)
|
21
|
+
@name = name
|
22
|
+
@versions = Array(versions)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require 'richcss/vendor/version_kit/lib/version_kit/version/helper'
|
2
|
+
require 'richcss/vendor/version_kit/lib/version_kit/version/components_helper'
|
3
|
+
|
4
|
+
module Richcss::VersionKit
|
5
|
+
# Model class which provides support for versions according to the [Semantic
|
6
|
+
# Versioning Specification](http://semver.org).
|
7
|
+
#
|
8
|
+
# Currently based on Semantic Versioning 2.0.0.
|
9
|
+
#
|
10
|
+
# Example version: 1.2.3-rc.1+2014.01.01
|
11
|
+
#
|
12
|
+
# Glossary:
|
13
|
+
#
|
14
|
+
# - version: a string representing a specific release of a software.
|
15
|
+
# - component: a version can have 3 components the number (1.2.3), the
|
16
|
+
# pre-release metadata (rc.1), and the Build component (2014.01.01).
|
17
|
+
# - identifier: each component in turn is composed by multiple identifier
|
18
|
+
# separated by a dot (like 1, 2, or 01).
|
19
|
+
# - bumping: the act of increasing by a single unit one identifier of the
|
20
|
+
# version.
|
21
|
+
#
|
22
|
+
class Version
|
23
|
+
# @return [RegEx] The regular expression to use to validate a string
|
24
|
+
# representation of a version.
|
25
|
+
#
|
26
|
+
# The components have the following characteristics:
|
27
|
+
#
|
28
|
+
# - Number component: Three dot-separated numeric elements.
|
29
|
+
# - Pre-release component: Hyphen, followed by any combination of digits,
|
30
|
+
# letters, or hyphens separated by periods.
|
31
|
+
# - Build component: Plus sign, followed by any combination of digits,
|
32
|
+
# letters, or hyphens separated by periods.
|
33
|
+
#
|
34
|
+
VERSION_PATTERN = /\A
|
35
|
+
[0-9]+\.[0-9]+\.[0-9]+ (?# Number component)
|
36
|
+
([-][0-9a-z-]+(\.[0-9a-z-]+)*)? (?# Pre-release component)
|
37
|
+
([+][0-9a-z-]+(\.[0-9a-z-]+)*)? (?# Build component)
|
38
|
+
\Z/xi
|
39
|
+
|
40
|
+
include Comparable
|
41
|
+
|
42
|
+
# @return [Array<Array<Fixnum,String>>] The list of the components of the
|
43
|
+
# version.
|
44
|
+
#
|
45
|
+
attr_reader :components
|
46
|
+
|
47
|
+
# The Semantic Versioning Specification mandates a number component
|
48
|
+
# composed by 3 identifiers. Therefore strictly speaking `1` and `1.0`
|
49
|
+
# are not versions according the specification. This class accepts those
|
50
|
+
# values normalizing them to `1.0.0`. To ensure strict adherence to the
|
51
|
+
# standard clients can use the `Version::valid?` method to check any
|
52
|
+
# string.
|
53
|
+
#
|
54
|
+
# @param [#to_s, Array<Array<String, Fixnum>>] version
|
55
|
+
# A representation of a version convertible to a string or the
|
56
|
+
# components of a version.
|
57
|
+
#
|
58
|
+
# @raise If initialized with a string which cannot be converted to a
|
59
|
+
# version.
|
60
|
+
#
|
61
|
+
# rubocop:disable MethodLength
|
62
|
+
#
|
63
|
+
def initialize(version_or_components)
|
64
|
+
if version_or_components.is_a?(Array)
|
65
|
+
components = self.class.normalize_components(version_or_components)
|
66
|
+
unless ComponentsHelper.validate_components?(components)
|
67
|
+
raise ArgumentError, "Malformed version components `#{components}`"
|
68
|
+
end
|
69
|
+
@components = components
|
70
|
+
|
71
|
+
else
|
72
|
+
version = self.class.normalize(version_or_components)
|
73
|
+
unless self.class.valid?(version)
|
74
|
+
raise ArgumentError, "Malformed version `#{version}`"
|
75
|
+
end
|
76
|
+
@components = ComponentsHelper.split_components(version)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
#
|
80
|
+
# rubocop:enable MethodLength
|
81
|
+
|
82
|
+
# @!group Class methods
|
83
|
+
#-------------------------------------------------------------------------#
|
84
|
+
|
85
|
+
# Normalizes the given string representation of a version by defaulting
|
86
|
+
# the minor and the patch version to 0 if possible.
|
87
|
+
#
|
88
|
+
# @param [#to_s] version
|
89
|
+
# The string representation to normalize.
|
90
|
+
#
|
91
|
+
# @return [String] The normalized or the original version.
|
92
|
+
#
|
93
|
+
def self.normalize(version)
|
94
|
+
version = version.to_s.strip
|
95
|
+
version << '.0' if version =~ /\A[0-9]+\Z/
|
96
|
+
version << '.0' if version =~ /\A[0-9]+\.[0-9]+\Z/
|
97
|
+
version
|
98
|
+
end
|
99
|
+
|
100
|
+
# Normalizes the given version components by defaulting the minor and the
|
101
|
+
# patch version to 0 if possible.
|
102
|
+
#
|
103
|
+
# @param [Array<Array<String, Fixnum>>] components
|
104
|
+
# The components to normalize.
|
105
|
+
#
|
106
|
+
# @return [Array] The normalized or the original components.
|
107
|
+
#
|
108
|
+
def self.normalize_components(components)
|
109
|
+
if components.is_a?(Array) && components[0].is_a?(Array)
|
110
|
+
count = components.count
|
111
|
+
components = components.fill([], count, 3 - count) if count < 3
|
112
|
+
|
113
|
+
number_count = components[0].count
|
114
|
+
if number_count < 3
|
115
|
+
components[0] = components[0].fill(0, number_count, 3 - number_count)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
components
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return [Bool] Whether a string representation of a version is can be
|
123
|
+
# accepted by this class. This comparison is much more lenient than
|
124
|
+
# the requirements described in the SemVer specification to support
|
125
|
+
# the diversity of versioning practices found in practice.
|
126
|
+
#
|
127
|
+
def self.valid?(version)
|
128
|
+
!(version.to_s =~ VERSION_PATTERN).nil?
|
129
|
+
end
|
130
|
+
|
131
|
+
# @!group Semantic Versioning
|
132
|
+
#-------------------------------------------------------------------------#
|
133
|
+
|
134
|
+
# @return [Array<Fixnum>] The list of the identifiers of the number
|
135
|
+
# component.
|
136
|
+
#
|
137
|
+
def number_component
|
138
|
+
@components[0]
|
139
|
+
end
|
140
|
+
|
141
|
+
# @return [Array<String, Fixnum>] The list of the identifiers of the
|
142
|
+
# pre-release component.
|
143
|
+
#
|
144
|
+
def pre_release_component
|
145
|
+
@components[1]
|
146
|
+
end
|
147
|
+
|
148
|
+
# @return [Array<String, Fixnum>] The list of the identifiers of the build
|
149
|
+
# component.
|
150
|
+
#
|
151
|
+
def build_component
|
152
|
+
@components[2]
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [Fixnum] The major version.
|
156
|
+
#
|
157
|
+
def major_version
|
158
|
+
number_component[0]
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [Fixnum] The minor version.
|
162
|
+
#
|
163
|
+
def minor
|
164
|
+
number_component[1]
|
165
|
+
end
|
166
|
+
|
167
|
+
# @return [Fixnum] The patch version.
|
168
|
+
#
|
169
|
+
def patch
|
170
|
+
number_component[2]
|
171
|
+
end
|
172
|
+
|
173
|
+
# @return [Boolean] Indicates whether or not the version is a pre-release
|
174
|
+
# version.
|
175
|
+
#
|
176
|
+
def pre_release?
|
177
|
+
!pre_release_component.empty?
|
178
|
+
end
|
179
|
+
|
180
|
+
# @!group Object methods
|
181
|
+
#-------------------------------------------------------------------------#
|
182
|
+
|
183
|
+
# @return [String] The string representation of the version.
|
184
|
+
#
|
185
|
+
def to_s
|
186
|
+
result = number_component.join('.')
|
187
|
+
|
188
|
+
if pre_release_component.count > 0
|
189
|
+
result << '-' << pre_release_component.join('.')
|
190
|
+
end
|
191
|
+
|
192
|
+
if build_component.count > 0
|
193
|
+
result << '+' << build_component.join('.')
|
194
|
+
end
|
195
|
+
|
196
|
+
result
|
197
|
+
end
|
198
|
+
|
199
|
+
# @return [String] a string representation suitable for debugging.
|
200
|
+
#
|
201
|
+
def inspect
|
202
|
+
"<#{self.class} #{self}>"
|
203
|
+
end
|
204
|
+
|
205
|
+
# @return [Bool]
|
206
|
+
#
|
207
|
+
def ==(other)
|
208
|
+
to_s == other.to_s
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns whether a hash should consider equal two versions for being used
|
212
|
+
# as a key. To be considered equal versions should be specified with the
|
213
|
+
# same precision (i.e. `'1.0' != '1.0.0'`)
|
214
|
+
#
|
215
|
+
# @param [Object] The object to compare.
|
216
|
+
#
|
217
|
+
# @return [Bool] whether a hash should consider other as an equal key to
|
218
|
+
# the instance.
|
219
|
+
#
|
220
|
+
def eql?(other)
|
221
|
+
self.class == other.class && to_s == other.to_s
|
222
|
+
end
|
223
|
+
|
224
|
+
# @return [Fixnum] The hash value for this instance.
|
225
|
+
#
|
226
|
+
def hash
|
227
|
+
[to_s].hash
|
228
|
+
end
|
229
|
+
|
230
|
+
# Compares the instance to another version to determine how it sorts.
|
231
|
+
#
|
232
|
+
# @param [Object] The object to compare.
|
233
|
+
#
|
234
|
+
# @return [Fixnum] -1 means self is smaller than other. 0 means self is
|
235
|
+
# equal to other. 1 means self is bigger than other.
|
236
|
+
# @return [Nil] If the two objects could not be compared.
|
237
|
+
#
|
238
|
+
# @note From semver.org:
|
239
|
+
#
|
240
|
+
# - Major, minor, and patch versions are always compared
|
241
|
+
# numerically.
|
242
|
+
# - When major, minor, and patch are equal, a pre-release version
|
243
|
+
# has lower precedence than a normal version.
|
244
|
+
# - Precedence for two pre-release versions with the same major,
|
245
|
+
# minor, and patch version MUST be determined by comparing each
|
246
|
+
# dot separated identifier from left to right until a difference
|
247
|
+
# is found as follows:
|
248
|
+
# - identifiers consisting of only digits are compared
|
249
|
+
# numerically and identifiers with letters or hyphens are
|
250
|
+
# compared lexically in ASCII sort order.
|
251
|
+
# - Numeric identifiers always have lower precedence than
|
252
|
+
# non-numeric identifiers.
|
253
|
+
# - A larger set of pre-release fields has a higher precedence
|
254
|
+
# than a smaller set, if all of the preceding identifiers are
|
255
|
+
# equal.
|
256
|
+
# - Build metadata SHOULD be ignored when determining version
|
257
|
+
# precedence.
|
258
|
+
#
|
259
|
+
def <=>(other)
|
260
|
+
return nil unless other.class == self.class
|
261
|
+
result = nil
|
262
|
+
|
263
|
+
result ||= ComponentsHelper.compare_number_component(
|
264
|
+
number_component, other.number_component
|
265
|
+
)
|
266
|
+
|
267
|
+
result ||= ComponentsHelper.compare_pre_release_component(
|
268
|
+
pre_release_component, other.pre_release_component
|
269
|
+
)
|
270
|
+
|
271
|
+
result || 0
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module Richcss::VersionKit
|
2
|
+
class Version
|
3
|
+
# Provides support for working with version components and comparing them.
|
4
|
+
#
|
5
|
+
# Assumes identifiers converted to the appropriate class as the ones
|
6
|
+
# returned by the `::split_identifiers` method.
|
7
|
+
#
|
8
|
+
module ComponentsHelper
|
9
|
+
# Splits a string representing a component in a list of the single
|
10
|
+
# identifiers (separated by a dot). Identifiers composed only by digits
|
11
|
+
# are converted to an integer in the process.
|
12
|
+
#
|
13
|
+
# @param [Array<String>] components
|
14
|
+
# The list of the components.
|
15
|
+
#
|
16
|
+
# @return [Array<String,Fixnum>] The list of the elements of the
|
17
|
+
# component.
|
18
|
+
#
|
19
|
+
def self.split_components(version)
|
20
|
+
component_strings = version.scan(/[^-+]+/)
|
21
|
+
(0...3).map do |index|
|
22
|
+
indentifiers_string = component_strings[index]
|
23
|
+
if indentifiers_string
|
24
|
+
ComponentsHelper.split_identifiers(indentifiers_string)
|
25
|
+
else
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Splits a string representing a component in a list of the single
|
32
|
+
# identifiers (separated by a dot). Identifiers composed only by digits
|
33
|
+
# are converted to an integer in the process.
|
34
|
+
#
|
35
|
+
# @param [String] component
|
36
|
+
# The string of the component to split in identifiers.
|
37
|
+
#
|
38
|
+
# @return [Array<String,Fixnum>] The list of the identifiers of the
|
39
|
+
# component.
|
40
|
+
#
|
41
|
+
def self.split_identifiers(component)
|
42
|
+
component.split('.').map do |identifier|
|
43
|
+
if identifier =~ /\A[0-9]+\Z/
|
44
|
+
identifier.to_i
|
45
|
+
else
|
46
|
+
identifier
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Compares the number component of one version with the one of another
|
52
|
+
# version.
|
53
|
+
#
|
54
|
+
# @param [Array<Fixnum>] first
|
55
|
+
# The component of the first version.
|
56
|
+
#
|
57
|
+
# @param [Array<Fixnum>] second
|
58
|
+
# The component of the second version.
|
59
|
+
#
|
60
|
+
# @return [Fixnum] See #<=>
|
61
|
+
#
|
62
|
+
def self.compare_number_component(first, second)
|
63
|
+
count = [first.count, second.count].max
|
64
|
+
count.times do |index|
|
65
|
+
result = first[index].to_i <=> second[index].to_i
|
66
|
+
return result unless result.zero?
|
67
|
+
end
|
68
|
+
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# Compares the pre-release component of one version with the one of
|
73
|
+
# another version.
|
74
|
+
#
|
75
|
+
# @param [Array<Fixnum>] first
|
76
|
+
# The component of the first version.
|
77
|
+
#
|
78
|
+
# @param [Array<Fixnum>] second
|
79
|
+
# The component of the second version.
|
80
|
+
#
|
81
|
+
# @return [Fixnum] See #<=>
|
82
|
+
#
|
83
|
+
def self.compare_pre_release_component(first, second)
|
84
|
+
result = (first.empty? ? 1 : 0) <=> (second.empty? ? 1 : 0)
|
85
|
+
return result unless result.zero?
|
86
|
+
|
87
|
+
count = [first.count, second.count].max
|
88
|
+
count.times do |index|
|
89
|
+
result = compare_pre_release_identifiers(first[index], second[index])
|
90
|
+
return result unless result.zero?
|
91
|
+
end
|
92
|
+
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
# Compares two pre-release identifiers.
|
97
|
+
#
|
98
|
+
# @param [String,Fixnum] fist
|
99
|
+
# The first identifier to compare.
|
100
|
+
#
|
101
|
+
# @param [String,Fixnum] second
|
102
|
+
# The second identifier to compare.
|
103
|
+
#
|
104
|
+
# @return [Fixnum] See #<=>
|
105
|
+
#
|
106
|
+
def self.compare_pre_release_identifiers(first, second)
|
107
|
+
result = compare(first, second)
|
108
|
+
result ||= compare(first.is_a?(String), second.is_a?(String))
|
109
|
+
return result if result
|
110
|
+
|
111
|
+
if first.is_a?(Fixnum)
|
112
|
+
first.to_i <=> second.to_i
|
113
|
+
elsif first.is_a?(String)
|
114
|
+
first.to_s <=> second.to_s
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Compares two boolean values returning a comparison result if only one
|
119
|
+
# condition is truthy.
|
120
|
+
#
|
121
|
+
# @param [Object] fist
|
122
|
+
# The first object to compare.
|
123
|
+
#
|
124
|
+
# @param [Object] second
|
125
|
+
# The second object to compare.
|
126
|
+
#
|
127
|
+
# @return [Fixnum] See #<=>
|
128
|
+
# @return [Nil] If the comparison didn't produce any result.
|
129
|
+
#
|
130
|
+
def self.compare(first, second)
|
131
|
+
if first && !second
|
132
|
+
+1
|
133
|
+
elsif second && !first
|
134
|
+
-1
|
135
|
+
else
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Checks whether the given components are valid.
|
141
|
+
#
|
142
|
+
# @param [Array<Array<String, Fixnum>>] components
|
143
|
+
# The components to check.
|
144
|
+
#
|
145
|
+
# @return [Bool] If the given components are valid.
|
146
|
+
#
|
147
|
+
# rubocop:disable CyclomaticComplexity
|
148
|
+
#
|
149
|
+
def self.validate_components?(components)
|
150
|
+
components.is_a?(Array) &&
|
151
|
+
components.map(&:class).uniq == [Array] &&
|
152
|
+
components.count == 3 &&
|
153
|
+
components.first.count == 3 &&
|
154
|
+
(components[0].map(&:class) - [Fixnum]).empty? &&
|
155
|
+
(components[1].map(&:class) - [String, Fixnum]).empty? &&
|
156
|
+
(components[2].map(&:class) - [String, Fixnum]).empty?
|
157
|
+
end
|
158
|
+
#
|
159
|
+
# rubocop:enable CyclomaticComplexity
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Richcss::VersionKit
|
2
|
+
class Version
|
3
|
+
# Identifies the possible next versions from a given one.
|
4
|
+
#
|
5
|
+
module Helper
|
6
|
+
# Bumps the component at the given index
|
7
|
+
# @param [Version, #to_s] version
|
8
|
+
# @param [#to_i] component
|
9
|
+
# @return [Version]
|
10
|
+
#
|
11
|
+
def self.bump(version, index)
|
12
|
+
index = index.to_i
|
13
|
+
unless (0..2).include?(index)
|
14
|
+
raise ArgumentError, "Unsupported index `#{index}`"
|
15
|
+
end
|
16
|
+
|
17
|
+
version = coherce_version(version)
|
18
|
+
number_components = version.number_component[0..index]
|
19
|
+
number_components[index] = number_components[index].succ
|
20
|
+
Version.new([number_components])
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param [Version, #to_s] version
|
24
|
+
# @return [Version]
|
25
|
+
#
|
26
|
+
def self.next_major(version)
|
27
|
+
bump(version, 0)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param [Version, #to_s] version
|
31
|
+
# @return [Version]
|
32
|
+
#
|
33
|
+
def self.next_minor(version)
|
34
|
+
bump(version, 1)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Version, #to_s] version
|
38
|
+
# @return [Version]
|
39
|
+
#
|
40
|
+
def self.next_patch(version)
|
41
|
+
bump(version, 2)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param [Version, #to_s] version
|
45
|
+
# @return [Version]
|
46
|
+
# @return [Nil]
|
47
|
+
#
|
48
|
+
def self.next_pre_release(version)
|
49
|
+
version = coherce_version(version)
|
50
|
+
return nil unless version.pre_release_component
|
51
|
+
pre_release_component = []
|
52
|
+
version.pre_release_component.each do |element|
|
53
|
+
element = element.succ if element.is_a?(Fixnum)
|
54
|
+
pre_release_component << element
|
55
|
+
end
|
56
|
+
if version.pre_release_component != pre_release_component
|
57
|
+
Version.new([version.number_component, pre_release_component])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param [Version, #to_s] version
|
62
|
+
# @return [Array<Version>] All the possible versions the given one
|
63
|
+
# might evolve in.
|
64
|
+
#
|
65
|
+
def self.next_versions(version)
|
66
|
+
version = coherce_version(version)
|
67
|
+
[
|
68
|
+
next_major(version),
|
69
|
+
next_minor(version),
|
70
|
+
next_patch(version),
|
71
|
+
next_pre_release(version)
|
72
|
+
].compact
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param [Version, #to_s] version
|
76
|
+
# @param [Version, #to_s] candidate
|
77
|
+
# @return [Bool]
|
78
|
+
#
|
79
|
+
def self.valid_next_version?(version, candidate)
|
80
|
+
version = coherce_version(version)
|
81
|
+
candidate = coherce_version(candidate)
|
82
|
+
next_versions(version).include?(candidate)
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Version] The version stripped of any pre-release or build
|
86
|
+
# metadata.
|
87
|
+
#
|
88
|
+
def self.release_version(version)
|
89
|
+
version = coherce_version(version)
|
90
|
+
Version.new([version.number_component])
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [String] The optimistic requirement (`~>`) which, according to
|
94
|
+
# SemVer, preserves backwards compatibility.
|
95
|
+
#
|
96
|
+
def self.optimistic_requirement(version)
|
97
|
+
version = coherce_version(version)
|
98
|
+
if version.major_version == 0
|
99
|
+
"~> #{version.number_component[0..2].join('.')}"
|
100
|
+
else
|
101
|
+
"~> #{version.number_component[0..1].join('.')}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param [Version, #to_s] version
|
106
|
+
# @return [Version]
|
107
|
+
#
|
108
|
+
def self.coherce_version(version)
|
109
|
+
if version.is_a?(Version)
|
110
|
+
version
|
111
|
+
else
|
112
|
+
Version.new(version)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/richcss/version.rb
CHANGED
data/richcss.gemspec
CHANGED
@@ -23,9 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec"
|
24
24
|
spec.add_development_dependency "pry"
|
25
25
|
|
26
|
-
spec.add_dependency "thor"
|
27
|
-
spec.add_dependency "molinillo"
|
28
|
-
spec.add_dependency "rest-client"
|
29
|
-
spec.add_dependency "zipruby"
|
30
|
-
spec.add_dependency "email_validator"
|
26
|
+
spec.add_dependency "thor", '~> 0.19'
|
27
|
+
spec.add_dependency "molinillo", '~> 0.4'
|
28
|
+
spec.add_dependency "rest-client", '~> 1.8'
|
29
|
+
spec.add_dependency "zipruby", '~> 0.3'
|
30
|
+
spec.add_dependency "email_validator", '~> 1.6'
|
31
31
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: richcss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Lo, Gabriel Cheng, Bill Xu, Jonathan Lai, David Zhu
|
@@ -70,72 +70,72 @@ dependencies:
|
|
70
70
|
name: thor
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
75
|
+
version: '0.19'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
82
|
+
version: '0.19'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: molinillo
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
89
|
+
version: '0.4'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
96
|
+
version: '0.4'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rest-client
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '1.8'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '1.8'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: zipruby
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - "
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
117
|
+
version: '0.3'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - "
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
124
|
+
version: '0.3'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: email_validator
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
131
|
+
version: '1.6'
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
138
|
+
version: '1.6'
|
139
139
|
description:
|
140
140
|
email:
|
141
141
|
- richcssa4@gmail.com
|
@@ -164,6 +164,15 @@ files:
|
|
164
164
|
- lib/richcss/richcss_specification_provider.rb
|
165
165
|
- lib/richcss/richcss_test_specification.rb
|
166
166
|
- lib/richcss/richcss_ui.rb
|
167
|
+
- lib/richcss/vendor/version_kit/lib/version_kit.rb
|
168
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/dependency.rb
|
169
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/gem_metadata.rb
|
170
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/requirement.rb
|
171
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/requirement_list.rb
|
172
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/set.rb
|
173
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/version.rb
|
174
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/version/components_helper.rb
|
175
|
+
- lib/richcss/vendor/version_kit/lib/version_kit/version/helper.rb
|
167
176
|
- lib/richcss/version.rb
|
168
177
|
- richcss.gemspec
|
169
178
|
homepage: https://github.com/fdp-A4/richcss-cli
|