php-composer 0.4.5 → 1.0.0.pre.alpha11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rbenv-gemsets +1 -0
- data/.rubocop.yml +131 -188
- data/.ruby-version +1 -0
- data/Gemfile +0 -9
- data/Rakefile +11 -0
- data/lib/composer.rb +52 -49
- data/lib/composer/json/json_file.rb +110 -83
- data/lib/composer/json/json_formatter.rb +43 -77
- data/lib/composer/json/{json_validaton_error.rb → json_validation_error.rb} +6 -2
- data/lib/composer/package/alias_package.rb +77 -61
- data/lib/composer/package/complete_package.rb +88 -18
- data/lib/composer/package/dumper/hash_dumper.rb +50 -118
- data/lib/composer/package/dumper/hash_dumper/complete_package_attribute_dumpers.rb +47 -0
- data/lib/composer/package/dumper/hash_dumper/package_attribute_dumpers.rb +145 -0
- data/lib/composer/package/dumper/hash_dumper/root_package_attribute_dumpers.rb +24 -0
- data/lib/composer/package/link.rb +15 -5
- data/lib/composer/package/loader/hash_loader.rb +92 -228
- data/lib/composer/package/loader/hash_loader/complete_package_attribute_loaders.rb +83 -0
- data/lib/composer/package/loader/hash_loader/package_attribute_loaders.rb +181 -0
- data/lib/composer/package/loader/hash_loader/root_package_attribute_loaders.rb +32 -0
- data/lib/composer/package/loader/json_loader.rb +7 -9
- data/lib/composer/package/package.rb +611 -43
- data/lib/composer/package/root_alias_package.rb +186 -15
- data/lib/composer/package/root_package.rb +12 -4
- data/lib/composer/package/version/version_parser.rb +16 -532
- data/lib/composer/package/version/version_selector.rb +127 -68
- data/lib/composer/repository/base_repository.rb +46 -3
- data/lib/composer/repository/composite_repository.rb +4 -4
- data/lib/composer/repository/filesystem_repository.rb +15 -8
- data/lib/composer/repository/hash_repository.rb +62 -45
- data/lib/composer/repository/writeable_hash_repository.rb +5 -5
- data/lib/composer/util/composer_mirror.rb +76 -0
- data/php-composer.gemspec +14 -8
- data/resources/composer-schema.json +12 -0
- metadata +117 -16
- data/lib/composer/error.rb +0 -8
- data/lib/composer/package/base_package.rb +0 -130
- data/lib/composer/package/link_constraint/base_constraint.rb +0 -36
- data/lib/composer/package/link_constraint/empty_constraint.rb +0 -35
- data/lib/composer/package/link_constraint/multi_constraint.rb +0 -67
- data/lib/composer/package/link_constraint/specific_constraint.rb +0 -41
- data/lib/composer/package/link_constraint/version_constraint.rb +0 -221
- data/lib/composer/version.rb +0 -3
@@ -12,26 +12,197 @@
|
|
12
12
|
module Composer
|
13
13
|
module Package
|
14
14
|
|
15
|
-
|
16
|
-
#
|
17
|
-
|
15
|
+
##
|
16
|
+
# The root alias package represents the project's composer.json
|
17
|
+
# and contains additional metadata.
|
18
|
+
##
|
19
|
+
class RootAliasPackage < ::Composer::Package::AliasPackage
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
##
|
22
|
+
# Creates a new root alias package.
|
23
|
+
#
|
24
|
+
# Params:
|
25
|
+
# @param alias_of ::Composer::Package::Package
|
26
|
+
# The package this package is an alias of.
|
27
|
+
# @param version string
|
28
|
+
# The version the alias must report.
|
29
|
+
# @param pretty_version string
|
30
|
+
# The alias's non-normalized version.
|
31
|
+
##
|
32
|
+
def initialize(alias_of, version, pretty_version)
|
33
|
+
unless ::Composer::Package::ROOT_PACKAGE_INTERFACE.all? { |m| alias_of.respond_to?(m) }
|
34
|
+
raise ArgumentError,
|
35
|
+
%q("alias_of" must implement all methods defined in ROOT_PACKAGE_INTERFACE)
|
36
|
+
end
|
37
|
+
super(alias_of, version, pretty_version)
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Returns a set of package names and their aliases.
|
42
|
+
# @return array
|
43
|
+
##
|
44
|
+
def aliases
|
45
|
+
alias_of.aliases
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Returns the minimum stability of the package.
|
50
|
+
# @return string
|
51
|
+
##
|
52
|
+
def minimum_stability
|
53
|
+
alias_of.minimum_stability
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Returns the stability flags to apply to dependencies.
|
58
|
+
#
|
59
|
+
# array('foo/bar' => 'dev')
|
60
|
+
#
|
61
|
+
# @return array
|
62
|
+
##
|
63
|
+
def stability_flags
|
64
|
+
alias_of.stability_flags
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Returns a set of package names and source references that must be enforced on them.
|
69
|
+
#
|
70
|
+
# array('foo/bar' => 'abcd1234')
|
71
|
+
#
|
72
|
+
# @return array
|
73
|
+
##
|
74
|
+
def references
|
75
|
+
alias_of.references
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Returns true if the root package prefers picking stable packages over unstable ones.
|
80
|
+
# @return bool
|
81
|
+
##
|
82
|
+
def prefer_stable?
|
83
|
+
alias_of.prefer_stable?
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Set the required packages.
|
88
|
+
#
|
89
|
+
# @param requires array
|
90
|
+
# A set of package links.
|
91
|
+
##
|
92
|
+
def requires=(requires)
|
93
|
+
@requires = replace_self_version_dependencies(requires, 'requires')
|
94
|
+
alias_of.requires = requires
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Set the recommended packages.
|
99
|
+
#
|
100
|
+
# @param dev_requires array
|
101
|
+
# A set of package links.
|
102
|
+
##
|
103
|
+
def dev_requires=(dev_requires)
|
104
|
+
@dev_requires = replace_self_version_dependencies(dev_requires, 'devRequires')
|
105
|
+
alias_of.dev_requires = dev_requires
|
106
|
+
end
|
21
107
|
|
22
|
-
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
27
|
-
|
108
|
+
##
|
109
|
+
# Set the conflicting packages.
|
110
|
+
#
|
111
|
+
# @param conflicts array
|
112
|
+
# A set of package links.
|
113
|
+
##
|
114
|
+
def conflicts=(conflicts)
|
115
|
+
@conflicts = replace_self_version_dependencies(conflicts, 'conflicts')
|
116
|
+
alias_of.conflicts = conflicts
|
117
|
+
end
|
28
118
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
119
|
+
##
|
120
|
+
# Set the provided virtual packages.
|
121
|
+
#
|
122
|
+
# @param provides array
|
123
|
+
# A set of package links.
|
124
|
+
##
|
125
|
+
def provides=(provides)
|
126
|
+
@provides = replace_self_version_dependencies(provides, 'provides')
|
127
|
+
alias_of.provides = provides
|
33
128
|
end
|
34
129
|
|
130
|
+
##
|
131
|
+
# Set the packages this one replaces.
|
132
|
+
#
|
133
|
+
# @param replaces array
|
134
|
+
# A set of package links.
|
135
|
+
##
|
136
|
+
def replaces=(replaces)
|
137
|
+
@replaces = replace_self_version_dependencies(replaces, 'replaces')
|
138
|
+
alias_of.replaces = replaces
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# Set the repositories.
|
143
|
+
#
|
144
|
+
# @param repositories array
|
145
|
+
# A set of package links.
|
146
|
+
##
|
147
|
+
def repositories=(repositories)
|
148
|
+
alias_of.repositories = repositories
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Set the autoload mapping.
|
153
|
+
#
|
154
|
+
# @param autoload array
|
155
|
+
# An array of autoloaded packages.
|
156
|
+
##
|
157
|
+
def autoload=(autoload)
|
158
|
+
alias_of.autoload(autoload);
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Set the dev autoload mapping.
|
163
|
+
#
|
164
|
+
# @param dev_autoload array
|
165
|
+
# An array of dev autoloaded packages.
|
166
|
+
##
|
167
|
+
def dev_autoload=(dev_autoload)
|
168
|
+
alias_of.dev_autoload(dev_autoload)
|
169
|
+
end
|
170
|
+
|
171
|
+
##
|
172
|
+
# Set the stability flags.
|
173
|
+
#
|
174
|
+
# @param stability_flags array
|
175
|
+
# An array of stability flags.
|
176
|
+
##
|
177
|
+
def stability_flags=(stability_flags)
|
178
|
+
alias_of.stability_flags(stability_flags)
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Set the package suggested packages.
|
183
|
+
#
|
184
|
+
# @param suggests array
|
185
|
+
# An array of suggested packages.
|
186
|
+
##
|
187
|
+
def suggests=(suggests)
|
188
|
+
alias_of.suggests(suggests)
|
189
|
+
end
|
190
|
+
|
191
|
+
##
|
192
|
+
# Set the package extra packages.
|
193
|
+
#
|
194
|
+
# @param extra array
|
195
|
+
# An array of extra packages.
|
196
|
+
##
|
197
|
+
def extra=(extra)
|
198
|
+
alias_of.extra(extra)
|
199
|
+
end
|
200
|
+
|
201
|
+
# def __clone
|
202
|
+
# parent::__clone;
|
203
|
+
# this->aliasOf = clone this->aliasOf;
|
204
|
+
# end
|
205
|
+
|
35
206
|
end
|
36
207
|
end
|
37
208
|
end
|
@@ -12,17 +12,25 @@
|
|
12
12
|
module Composer
|
13
13
|
module Package
|
14
14
|
|
15
|
+
##
|
15
16
|
# The root package represents the project's composer.json
|
16
17
|
# and contains additional metadata
|
17
|
-
|
18
|
+
##
|
19
|
+
class RootPackage < ::Composer::Package::CompletePackage
|
18
20
|
|
19
21
|
attr_accessor :minimum_stability, :prefer_stable, :stability_flags,
|
20
22
|
:references, :aliases
|
21
23
|
|
24
|
+
##
|
22
25
|
# Creates a new root package in memory package.
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
+
#
|
27
|
+
# @param name string name
|
28
|
+
# The package's name
|
29
|
+
# @param version string version
|
30
|
+
# The package's version
|
31
|
+
# @param: pretty_version string
|
32
|
+
# The package's non-normalized version
|
33
|
+
##
|
26
34
|
def initialize(name, version, pretty_version)
|
27
35
|
super(name, version, pretty_version)
|
28
36
|
|
@@ -1,17 +1,23 @@
|
|
1
|
-
|
1
|
+
##
|
2
2
|
# This file was ported to ruby from Composer php source code file.
|
3
|
+
#
|
3
4
|
# Original Source: Composer\Package\Version\VersionParser.php
|
5
|
+
# Ref SHA: 1328d9c3b2fbe2d71079c5009b2d5204ce956c2e
|
4
6
|
#
|
5
7
|
# (c) Nils Adermann <naderman@naderman.de>
|
6
8
|
# Jordi Boggiano <j.boggiano@seld.be>
|
7
9
|
#
|
8
10
|
# For the full copyright and license information, please view the LICENSE
|
9
11
|
# file that was distributed with this source code.
|
10
|
-
|
12
|
+
##
|
13
|
+
|
14
|
+
require 'composer/semver'
|
11
15
|
|
12
16
|
module Composer
|
13
17
|
module Package
|
14
18
|
module Version
|
19
|
+
|
20
|
+
##
|
15
21
|
# Version Parser
|
16
22
|
#
|
17
23
|
# PHP Authors:
|
@@ -19,299 +25,19 @@ module Composer
|
|
19
25
|
#
|
20
26
|
# Ruby Authors:
|
21
27
|
# Ioannis Kappas <ikappas@devworks.gr>
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
class << self
|
26
|
-
|
27
|
-
# Returns the stability of a version
|
28
|
-
#
|
29
|
-
# Params:
|
30
|
-
# +version+:: string The version to parse for stability
|
31
|
-
#
|
32
|
-
# Returns:
|
33
|
-
# string The version's stability
|
34
|
-
def parse_stability(version)
|
35
|
-
raise ArgumentError, 'version must be specified' unless version
|
36
|
-
raise TypeError, 'version must be of type String' unless version.is_a?(String)
|
37
|
-
raise UnexpectedValueError, 'version string must not be empty' if version.empty?
|
38
|
-
|
39
|
-
version = version.gsub(/#.+$/i, '')
|
40
|
-
|
41
|
-
if version.start_with?('dev-') || version.end_with?('-dev')
|
42
|
-
return 'dev'
|
43
|
-
end
|
44
|
-
|
45
|
-
if matches = /#{MODIFIER_REGEX}$/i.match(version.downcase)
|
46
|
-
if matches[3]
|
47
|
-
return 'dev'
|
48
|
-
elsif matches[1]
|
49
|
-
if 'beta' === matches[1] || 'b' === matches[1]
|
50
|
-
return 'beta'
|
51
|
-
elsif 'alpha' === matches[1] || 'a' === matches[1]
|
52
|
-
return 'alpha'
|
53
|
-
elsif 'rc' === matches[1]
|
54
|
-
return 'RC'
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
'stable'
|
60
|
-
end
|
61
|
-
|
62
|
-
# Normalize the specified stability
|
63
|
-
# Param: string stability
|
64
|
-
# Return: string
|
65
|
-
def normalize_stability(stability)
|
66
|
-
raise ArgumentError, 'stability must be specified' unless stability
|
67
|
-
raise TypeError, 'stability must be of type String' unless stability.is_a?(String)
|
68
|
-
stability = stability.downcase
|
69
|
-
stability === 'rc' ? 'RC' : stability
|
70
|
-
end
|
71
|
-
|
72
|
-
# Formats package version
|
73
|
-
# Param: Composer::Package::Package package
|
74
|
-
# Param: boolean truncate
|
75
|
-
# Return: string
|
76
|
-
def format_version(package, truncate = true)
|
77
|
-
if !package.is_dev || !['hg', 'git'].include?(package.source_type)
|
78
|
-
return package.pretty_version
|
79
|
-
end
|
80
|
-
|
81
|
-
# if source reference is a sha1 hash -- truncate
|
82
|
-
if truncate && package.source_reference.length === 40
|
83
|
-
return "#{package.pretty_version} #{package.source_reference[0..6]}"
|
84
|
-
end
|
85
|
-
|
86
|
-
"#{package.pretty_version} #{package.source_reference}"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Normalizes a version string to be able to perform comparisons on it
|
91
|
-
#
|
92
|
-
# Params:
|
93
|
-
# +version+:: <tt>String</tt> The version string to normalize
|
94
|
-
# +full_version+:: <tt>String</tt> optional complete version string to
|
95
|
-
# give more context
|
96
|
-
#
|
97
|
-
# Throws:
|
98
|
-
# +InvalidVersionStringError+
|
99
|
-
#
|
100
|
-
# Returns:
|
101
|
-
# +String+
|
102
|
-
def normalize(version, full_version = nil)
|
103
|
-
raise ArgumentError, 'version must be specified' unless version
|
104
|
-
raise TypeError, 'version must be of type String' unless version.is_a?(String)
|
105
|
-
raise UnexpectedValueError, 'version string must not be empty' if version.empty?
|
106
|
-
|
107
|
-
version.strip!
|
108
|
-
if full_version == nil
|
109
|
-
full_version = version
|
110
|
-
end
|
111
|
-
|
112
|
-
# ignore aliases and just assume the alias is required
|
113
|
-
# instead of the source
|
114
|
-
if matches = /^([^,\s]+) +as +([^,\s]+)$/.match(version)
|
115
|
-
version = matches[1]
|
116
|
-
end
|
117
|
-
|
118
|
-
# ignore build metadata
|
119
|
-
if matches = /^([^,\s+]+)\+[^\s]+$/.match(version)
|
120
|
-
version = matches[1]
|
121
|
-
end
|
122
|
-
|
123
|
-
# match master-like branches
|
124
|
-
if matches = /^(?:dev-)?(?:master|trunk|default)$/i.match(version)
|
125
|
-
return '9999999-dev'
|
126
|
-
end
|
127
|
-
|
128
|
-
if 'dev-' === version[0...4].downcase
|
129
|
-
return "dev-#{version[4..version.size]}"
|
130
|
-
end
|
131
|
-
|
132
|
-
# match classical versioning
|
133
|
-
index = 0
|
134
|
-
if matches = /^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?#{MODIFIER_REGEX}$/i.match(version)
|
135
|
-
version = ''
|
136
|
-
matches.to_a[1..4].each do |c|
|
137
|
-
version += c ? c : '.0'
|
138
|
-
end
|
139
|
-
index = 5
|
140
|
-
elsif matches = /^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)#{MODIFIER_REGEX}$/i.match(version)
|
141
|
-
version = matches[1].gsub(/\D/, '-')
|
142
|
-
index = 2
|
143
|
-
elsif matches = /^v?(\d{4,})(\.\d+)?(\.\d+)?(\.\d+)?#{MODIFIER_REGEX}$/i.match(version)
|
144
|
-
version = ''
|
145
|
-
matches.to_a[1..4].each do |c|
|
146
|
-
version << (c.nil? ? '.0' : c)
|
147
|
-
end
|
148
|
-
index = 5
|
149
|
-
end
|
150
|
-
|
151
|
-
# add version modifiers if a version was matched
|
152
|
-
if index > 0
|
153
|
-
if matches[index]
|
154
|
-
if 'stable' === matches[index]
|
155
|
-
return version
|
156
|
-
end
|
157
|
-
stability = expand_stability(matches[index])
|
158
|
-
version = "#{version}-#{stability ? stability : matches[index]}#{matches[index + 1] ? matches[index + 1] : ''}"
|
159
|
-
end
|
160
|
-
|
161
|
-
if matches[index + 2]
|
162
|
-
version = "#{version}-dev"
|
163
|
-
end
|
164
|
-
|
165
|
-
return version
|
166
|
-
end
|
167
|
-
|
168
|
-
# match dev branches
|
169
|
-
if matches = /(.*?)[.-]?dev$/i.match(version)
|
170
|
-
begin
|
171
|
-
return normalize_branch(matches[1])
|
172
|
-
rescue
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
extra_message = ''
|
177
|
-
if matches = / +as +#{Regexp.escape(version)}$/.match(full_version)
|
178
|
-
extra_message = " in \"#{full_version}\", the alias must be an exact version"
|
179
|
-
elsif matches = /^#{Regexp.escape(version)} +as +/.match(full_version)
|
180
|
-
extra_message = " in \"#{full_version}\", the alias source must be an exact version, if it is a branch name you should prefix it with dev-"
|
181
|
-
end
|
182
|
-
|
183
|
-
raise UnexpectedValueError, "Invalid version string \"#{version}\"#{extra_message}"
|
184
|
-
end
|
185
|
-
|
186
|
-
# Normalizes a branch name to be able to perform comparisons on it
|
187
|
-
#
|
188
|
-
# Params:
|
189
|
-
# +name+:: string The branch name to normalize
|
190
|
-
#
|
191
|
-
# Returns:
|
192
|
-
# string The normalized branch name
|
193
|
-
def normalize_branch(name)
|
194
|
-
name.strip!
|
195
|
-
|
196
|
-
if ['master', 'trunk', 'default'].include?(name)
|
197
|
-
return normalize(name)
|
198
|
-
end
|
199
|
-
|
200
|
-
if matches = /^v?(\d+)(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?$/i.match(name)
|
201
|
-
version = ''
|
202
|
-
|
203
|
-
# for i in 0..3
|
204
|
-
# # version << matches[i] ? matches[i].gsub('*', 'x').gsub('X', 'x') : '.x'
|
205
|
-
# end
|
206
|
-
matches.captures.each { |match| version << (match != nil ? match.gsub('*', 'x').gsub('X', 'x') : '.x') }
|
207
|
-
return "#{version.gsub('x', '9999999')}-dev"
|
208
|
-
end
|
209
|
-
|
210
|
-
"dev-#{name}"
|
211
|
-
end
|
212
|
-
|
213
|
-
# Params:
|
214
|
-
# +source+:: string source package name
|
215
|
-
# +source_version+:: string source package version (pretty version ideally)
|
216
|
-
# +description+:: string link description (e.g. requires, replaces, ..)
|
217
|
-
# +links+:: array An array of package name => constraint mappings
|
218
|
-
#
|
219
|
-
# Returns:
|
220
|
-
# Link[]
|
221
|
-
def parse_links(source, source_version, description, links)
|
222
|
-
res = {}
|
223
|
-
links.each do |target, constraint|
|
224
|
-
if 'self.version' === constraint
|
225
|
-
parsed_constraint = parse_constraints(source_version)
|
226
|
-
else
|
227
|
-
parsed_constraint = parse_constraints(constraint)
|
228
|
-
end
|
229
|
-
res[target.downcase] = Composer::Package::Link.new(
|
230
|
-
source,
|
231
|
-
target,
|
232
|
-
parsed_constraint,
|
233
|
-
description,
|
234
|
-
constraint
|
235
|
-
)
|
236
|
-
end
|
237
|
-
res
|
238
|
-
end
|
239
|
-
|
240
|
-
def parse_constraints(constraints)
|
241
|
-
raise ArgumentError, 'version must be specified' unless constraints
|
242
|
-
raise TypeError, 'version must be of type String' unless constraints.is_a?(String)
|
243
|
-
raise UnexpectedValueError, 'version string must not be empty' if constraints.empty?
|
244
|
-
|
245
|
-
pretty_constraint = constraints
|
246
|
-
|
247
|
-
stabilites = Composer::Package::BasePackage.stabilities.keys.join('|')
|
248
|
-
if match = /^([^,\s]*?)@(#{stabilites})$/i.match(constraints)
|
249
|
-
constraints = match[1].nil? || match[1].empty? ? '*' : match[1]
|
250
|
-
end
|
251
|
-
|
252
|
-
if match = /^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#.+$/i.match(constraints)
|
253
|
-
constraints = match[1]
|
254
|
-
end
|
255
|
-
|
256
|
-
# or_constraints = preg_split('{\s*\|\|?\s*}', trim(constraints))
|
257
|
-
or_constraints = constraints.strip.split(/\s*\|\|?\s*/)
|
258
|
-
or_groups = []
|
259
|
-
or_constraints.each do |constraints|
|
260
|
-
|
261
|
-
# and_constraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', constraints)
|
262
|
-
and_constraints = constraints.split(/(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)/)
|
263
|
-
|
264
|
-
if and_constraints.length > 1
|
265
|
-
constraint_objects = []
|
266
|
-
and_constraints.each do |constraint|
|
267
|
-
constraint_objects << parse_constraint(constraint)
|
268
|
-
end
|
269
|
-
else
|
270
|
-
constraint_objects = parse_constraint(and_constraints[0])
|
271
|
-
end
|
272
|
-
|
273
|
-
if constraint_objects.length === 1
|
274
|
-
constraint = constraint_objects[0]
|
275
|
-
else
|
276
|
-
constraint = Composer::Package::LinkConstraint::MultiConstraint.new(constraint_objects)
|
277
|
-
end
|
278
|
-
|
279
|
-
or_groups << constraint
|
280
|
-
end
|
281
|
-
|
282
|
-
if or_groups.length === 1
|
283
|
-
constraint = or_groups[0]
|
284
|
-
else
|
285
|
-
constraint = Composer::Package::LinkConstraint::MultiConstraint.new(or_groups, false)
|
286
|
-
end
|
287
|
-
|
288
|
-
constraint.pretty_string = pretty_constraint
|
289
|
-
|
290
|
-
constraint
|
291
|
-
end
|
292
|
-
|
293
|
-
# Extract numeric prefix from alias, if it is in numeric format,
|
294
|
-
# suitable for version comparison
|
295
|
-
#
|
296
|
-
# Params:
|
297
|
-
# +branch+:: string Branch name (e.g. 2.1.x-dev)
|
298
|
-
#
|
299
|
-
# Returns:
|
300
|
-
# string|false Numeric prefix if present (e.g. 2.1.) or false
|
301
|
-
def parse_numeric_alias_prefix(branch)
|
302
|
-
if matches = /^(?<version>(\d+\.)*\d+)(?:\.x)?-dev$/i.match(branch)
|
303
|
-
return "#{matches['version']}."
|
304
|
-
end
|
305
|
-
false
|
306
|
-
end
|
28
|
+
##
|
29
|
+
class VersionParser < ::Composer::Semver::VersionParser
|
307
30
|
|
31
|
+
##
|
308
32
|
# Parses a name/version pairs and returns an array of pairs + the
|
309
33
|
#
|
310
34
|
# Params:
|
311
|
-
#
|
35
|
+
# @param pairs
|
36
|
+
# a set of package/version pairs separated by ":", "=" or " "
|
312
37
|
#
|
313
|
-
#
|
314
|
-
# array
|
38
|
+
# @return array[]
|
39
|
+
# An array of arrays containing a name and (if provided) a version
|
40
|
+
##
|
315
41
|
def parse_name_version_pairs(pairs)
|
316
42
|
pairs = pairs.values
|
317
43
|
result = []
|
@@ -335,248 +61,6 @@ module Composer
|
|
335
61
|
result
|
336
62
|
end
|
337
63
|
|
338
|
-
# PRIVATE METHODS
|
339
|
-
private
|
340
|
-
|
341
|
-
def parse_constraint(constraint)
|
342
|
-
|
343
|
-
stabilites = Composer::Package::BasePackage.stabilities.keys.join('|')
|
344
|
-
if match = /^([^,\s]+?)@(#{stabilites})$/i.match(constraint)
|
345
|
-
constraint = match[1]
|
346
|
-
if match[2] != 'stable'
|
347
|
-
stability_modifier = match[2]
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
if /^[xX*](\.[xX*])*$/i.match(constraint)
|
352
|
-
return [
|
353
|
-
Composer::Package::LinkConstraint::EmptyConstraint.new
|
354
|
-
]
|
355
|
-
end
|
356
|
-
|
357
|
-
version_regex = '(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?' + MODIFIER_REGEX
|
358
|
-
|
359
|
-
# match tilde constraints
|
360
|
-
# like wildcard constraints, unsuffixed tilde constraints say that they must be greater than the previous
|
361
|
-
# version, to ensure that unstable instances of the current version are allowed.
|
362
|
-
# however, if a stability suffix is added to the constraint, then a >= match on the current version is
|
363
|
-
# used instead
|
364
|
-
if matches = /^~>?#{version_regex}$/i.match(constraint)
|
365
|
-
|
366
|
-
if constraint[0...2] === '~>'
|
367
|
-
raise UnexpectedValueError,
|
368
|
-
"Could not parse version constraint #{constraint}: \
|
369
|
-
Invalid operator \"~>\", you probably meant to use the \"~\" operator"
|
370
|
-
end
|
371
|
-
|
372
|
-
# Work out which position in the version we are operating at
|
373
|
-
if matches[4] && matches[4] != ''
|
374
|
-
position = 4
|
375
|
-
elsif matches[3] && matches[3] != ''
|
376
|
-
position = 3
|
377
|
-
elsif matches[2] && matches[2] != ''
|
378
|
-
position = 2
|
379
|
-
else
|
380
|
-
position = 1
|
381
|
-
end
|
382
|
-
|
383
|
-
# Calculate the stability suffix
|
384
|
-
stability_suffix = ''
|
385
|
-
if !matches[5].nil? && !matches[5].empty?
|
386
|
-
stability_suffix << "-#{expand_stability(matches[5])}"
|
387
|
-
if !matches[6].nil? && !matches[6].empty?
|
388
|
-
stability_suffix << matches[6]
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
if !matches[7].nil? && !matches[7].empty?
|
393
|
-
stability_suffix << '-dev'
|
394
|
-
end
|
395
|
-
|
396
|
-
stability_suffix = '-dev' if stability_suffix.empty?
|
397
|
-
|
398
|
-
low_version = manipulate_version_string(matches.to_a, position, 0) + stability_suffix
|
399
|
-
lower_bound = Composer::Package::LinkConstraint::VersionConstraint.new('>=', low_version)
|
400
|
-
|
401
|
-
# For upper bound, we increment the position of one more significance,
|
402
|
-
# but high_position = 0 would be illegal
|
403
|
-
high_position = [1, position - 1].max
|
404
|
-
high_version = manipulate_version_string(matches.to_a, high_position, 1) + '-dev'
|
405
|
-
upper_bound = Composer::Package::LinkConstraint::VersionConstraint.new('<', high_version)
|
406
|
-
|
407
|
-
return [
|
408
|
-
lower_bound,
|
409
|
-
upper_bound
|
410
|
-
]
|
411
|
-
end
|
412
|
-
|
413
|
-
# match caret constraints
|
414
|
-
if matches = /^\^#{version_regex}($)/i.match(constraint)
|
415
|
-
# Create comparison array
|
416
|
-
has_match = []
|
417
|
-
for i in 0..(matches.to_a.length - 1)
|
418
|
-
has_match[i] = !matches[i].nil? && !matches[i].empty?
|
419
|
-
end
|
420
|
-
|
421
|
-
# Work out which position in the version we are operating at
|
422
|
-
if matches[1] != '0' || !has_match[2]
|
423
|
-
position = 1
|
424
|
-
elsif matches[2] != '0' || !has_match[3]
|
425
|
-
position = 2
|
426
|
-
else
|
427
|
-
position = 3
|
428
|
-
end
|
429
|
-
|
430
|
-
# Calculate the stability suffix
|
431
|
-
stability_suffix = ''
|
432
|
-
if !has_match[5] && !has_match[7]
|
433
|
-
stability_suffix << '-dev'
|
434
|
-
end
|
435
|
-
|
436
|
-
low_pretty = "#{constraint}#{stability_suffix}"
|
437
|
-
low_version = normalize(low_pretty[1..low_pretty.length - 1])
|
438
|
-
lower_bound = Composer::Package::LinkConstraint::VersionConstraint.new('>=', low_version)
|
439
|
-
|
440
|
-
# For upper bound, we increment the position of one more significance,
|
441
|
-
# but high_position = 0 would be illegal
|
442
|
-
high_version = manipulate_version_string(matches.to_a, position, 1) + '-dev'
|
443
|
-
upper_bound = Composer::Package::LinkConstraint::VersionConstraint.new('<', high_version)
|
444
|
-
|
445
|
-
return [
|
446
|
-
lower_bound,
|
447
|
-
upper_bound
|
448
|
-
]
|
449
|
-
end
|
450
|
-
|
451
|
-
# match wildcard constraints
|
452
|
-
if matches = /^(\d+)(?:\.(\d+))?(?:\.(\d+))?\.[xX*]$/.match(constraint)
|
453
|
-
if matches[3] && matches[3] != ''
|
454
|
-
position = 3
|
455
|
-
elsif matches[2] && matches[2] != ''
|
456
|
-
position = 2
|
457
|
-
else
|
458
|
-
position = 1
|
459
|
-
end
|
460
|
-
|
461
|
-
low_version = manipulate_version_string(matches.to_a, position) + '-dev'
|
462
|
-
high_version = manipulate_version_string(matches.to_a, position, 1) + '-dev'
|
463
|
-
|
464
|
-
if low_version === "0.0.0.0-dev"
|
465
|
-
return [Composer::Package::LinkConstraint::VersionConstraint.new('<', high_version)]
|
466
|
-
end
|
467
|
-
|
468
|
-
return [
|
469
|
-
Composer::Package::LinkConstraint::VersionConstraint.new('>=', low_version),
|
470
|
-
Composer::Package::LinkConstraint::VersionConstraint.new('<', high_version),
|
471
|
-
]
|
472
|
-
end
|
473
|
-
|
474
|
-
# match hyphen constraints
|
475
|
-
if matches = /^(#{version_regex}) +- +(#{version_regex})($)/i.match(constraint)
|
476
|
-
|
477
|
-
match_from = matches[1]
|
478
|
-
match_to = matches[9]
|
479
|
-
|
480
|
-
# Create comparison array
|
481
|
-
has_match = []
|
482
|
-
for i in 0..(matches.to_a.length - 1)
|
483
|
-
has_match[i] = !matches[i].nil? && !matches[i].empty?
|
484
|
-
end
|
485
|
-
|
486
|
-
# Calculate the stability suffix
|
487
|
-
low_stability_suffix = ''
|
488
|
-
if !has_match[6] && !has_match[8]
|
489
|
-
low_stability_suffix = '-dev'
|
490
|
-
end
|
491
|
-
|
492
|
-
low_version = normalize(match_from)
|
493
|
-
lower_bound = Composer::Package::LinkConstraint::VersionConstraint.new('>=', low_version + low_stability_suffix)
|
494
|
-
|
495
|
-
# high_version = matches[10]
|
496
|
-
|
497
|
-
if (has_match[11] && has_match[12]) || has_match[14] || has_match[16]
|
498
|
-
high_version = normalize(match_to)
|
499
|
-
upper_bound = Composer::Package::LinkConstraint::VersionConstraint.new('<=', high_version)
|
500
|
-
else
|
501
|
-
high_match = ['', matches[10], matches[11], matches[12], matches[13]]
|
502
|
-
high_version = manipulate_version_string(high_match, (!has_match[11] ? 1 : 2), 1) + '-dev'
|
503
|
-
upper_bound = Composer::Package::LinkConstraint::VersionConstraint.new('<', high_version)
|
504
|
-
end
|
505
|
-
|
506
|
-
return [
|
507
|
-
lower_bound,
|
508
|
-
upper_bound
|
509
|
-
]
|
510
|
-
end
|
511
|
-
|
512
|
-
# match operators constraints
|
513
|
-
if matches = /^(<>|!=|>=?|<=?|==?)?\s*(.*)/.match(constraint)
|
514
|
-
begin
|
515
|
-
version = normalize(matches[2])
|
516
|
-
stability = VersionParser::parse_stability(version)
|
517
|
-
if !stability_modifier.nil? && !stability_modifier.empty? && (stability === 'stable')
|
518
|
-
version << "-#{stability_modifier}"
|
519
|
-
elsif matches[1] === '<'
|
520
|
-
unless /-#{MODIFIER_REGEX}$/.match(matches[2].downcase)
|
521
|
-
version << '-dev'
|
522
|
-
end
|
523
|
-
end
|
524
|
-
operator = matches[1].nil? ? '=' : matches[1]
|
525
|
-
return [Composer::Package::LinkConstraint::VersionConstraint.new(operator, version)]
|
526
|
-
rescue Exception => e
|
527
|
-
end
|
528
|
-
end
|
529
|
-
|
530
|
-
message = "Could not parse version constraint #{constraint}"
|
531
|
-
message << ": #{e.message}" if e
|
532
|
-
raise UnexpectedValueError, message
|
533
|
-
end
|
534
|
-
|
535
|
-
# Increment, decrement, or simply pad a version number.
|
536
|
-
# Support function for {@link parse_constraint()}
|
537
|
-
#
|
538
|
-
# Params:
|
539
|
-
# +matches+ Array with version parts in array indexes 1,2,3,4
|
540
|
-
# +position+ Integer 1,2,3,4 - which segment of the version to decrement
|
541
|
-
# +increment+ Integer
|
542
|
-
# +pad+ String The string to pad version parts after position
|
543
|
-
#
|
544
|
-
# Returns:
|
545
|
-
# string The new version
|
546
|
-
def manipulate_version_string(matches, position, increment = 0, pad = '0')
|
547
|
-
4.downto(1).each do |i|
|
548
|
-
if i > position
|
549
|
-
matches[i] = pad
|
550
|
-
elsif i == position && increment
|
551
|
-
matches[i] = matches[i].to_i + increment
|
552
|
-
# If matches[i] was 0, carry the decrement
|
553
|
-
if matches[i] < 0
|
554
|
-
matches[i] = pad
|
555
|
-
position -= 1
|
556
|
-
|
557
|
-
# Return nil on a carry overflow
|
558
|
-
return nil if i == 1
|
559
|
-
end
|
560
|
-
end
|
561
|
-
end
|
562
|
-
"#{matches[1]}.#{matches[2]}.#{matches[3]}.#{matches[4]}"
|
563
|
-
end
|
564
|
-
|
565
|
-
def expand_stability(stability)
|
566
|
-
stability = stability.downcase
|
567
|
-
case stability
|
568
|
-
when 'a'
|
569
|
-
'alpha'
|
570
|
-
when 'b'
|
571
|
-
'beta'
|
572
|
-
when 'p', 'pl'
|
573
|
-
'patch'
|
574
|
-
when 'rc'
|
575
|
-
'RC'
|
576
|
-
else
|
577
|
-
stability
|
578
|
-
end
|
579
|
-
end
|
580
64
|
end
|
581
65
|
end
|
582
66
|
end
|