richcss 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|