php-composer 0.4.5 → 1.0.0.pre.alpha11
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/.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
|