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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rbenv-gemsets +1 -0
  3. data/.rubocop.yml +131 -188
  4. data/.ruby-version +1 -0
  5. data/Gemfile +0 -9
  6. data/Rakefile +11 -0
  7. data/lib/composer.rb +52 -49
  8. data/lib/composer/json/json_file.rb +110 -83
  9. data/lib/composer/json/json_formatter.rb +43 -77
  10. data/lib/composer/json/{json_validaton_error.rb → json_validation_error.rb} +6 -2
  11. data/lib/composer/package/alias_package.rb +77 -61
  12. data/lib/composer/package/complete_package.rb +88 -18
  13. data/lib/composer/package/dumper/hash_dumper.rb +50 -118
  14. data/lib/composer/package/dumper/hash_dumper/complete_package_attribute_dumpers.rb +47 -0
  15. data/lib/composer/package/dumper/hash_dumper/package_attribute_dumpers.rb +145 -0
  16. data/lib/composer/package/dumper/hash_dumper/root_package_attribute_dumpers.rb +24 -0
  17. data/lib/composer/package/link.rb +15 -5
  18. data/lib/composer/package/loader/hash_loader.rb +92 -228
  19. data/lib/composer/package/loader/hash_loader/complete_package_attribute_loaders.rb +83 -0
  20. data/lib/composer/package/loader/hash_loader/package_attribute_loaders.rb +181 -0
  21. data/lib/composer/package/loader/hash_loader/root_package_attribute_loaders.rb +32 -0
  22. data/lib/composer/package/loader/json_loader.rb +7 -9
  23. data/lib/composer/package/package.rb +611 -43
  24. data/lib/composer/package/root_alias_package.rb +186 -15
  25. data/lib/composer/package/root_package.rb +12 -4
  26. data/lib/composer/package/version/version_parser.rb +16 -532
  27. data/lib/composer/package/version/version_selector.rb +127 -68
  28. data/lib/composer/repository/base_repository.rb +46 -3
  29. data/lib/composer/repository/composite_repository.rb +4 -4
  30. data/lib/composer/repository/filesystem_repository.rb +15 -8
  31. data/lib/composer/repository/hash_repository.rb +62 -45
  32. data/lib/composer/repository/writeable_hash_repository.rb +5 -5
  33. data/lib/composer/util/composer_mirror.rb +76 -0
  34. data/php-composer.gemspec +14 -8
  35. data/resources/composer-schema.json +12 -0
  36. metadata +117 -16
  37. data/lib/composer/error.rb +0 -8
  38. data/lib/composer/package/base_package.rb +0 -130
  39. data/lib/composer/package/link_constraint/base_constraint.rb +0 -36
  40. data/lib/composer/package/link_constraint/empty_constraint.rb +0 -35
  41. data/lib/composer/package/link_constraint/multi_constraint.rb +0 -67
  42. data/lib/composer/package/link_constraint/specific_constraint.rb +0 -41
  43. data/lib/composer/package/link_constraint/version_constraint.rb +0 -221
  44. data/lib/composer/version.rb +0 -3
@@ -12,26 +12,197 @@
12
12
  module Composer
13
13
  module Package
14
14
 
15
- # The root package represents the project's composer.json
16
- # and contains additional metadata
17
- class RootAliasPackage < Composer::Package::CompletePackage
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
- attr_accessor :minimum_stability, :prefer_stable, :stability_flags,
20
- :references, :aliases
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
- # Creates a new root package in memory package.
23
- # Param: string name The package's name
24
- # Param: string version The package's version
25
- # Param: string prettyVersion The package's non-normalized version
26
- def initialize(name, version, pretty_version)
27
- super(name, version, pretty_version)
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
- @minimum_stability = 'stable'
30
- @stability_flags = []
31
- @references = []
32
- @aliases = []
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
- class RootPackage < Composer::Package::CompletePackage
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
- # Param: string name The package's name
24
- # Param: string version The package's version
25
- # Param: string prettyVersion The package's non-normalized version
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
- class VersionParser
23
- MODIFIER_REGEX = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?'.freeze()
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
- # +pairs+:: array a set of package/version pairs separated by ":", "=" or " "
35
+ # @param pairs
36
+ # a set of package/version pairs separated by ":", "=" or " "
312
37
  #
313
- # Returns:
314
- # array[] array of arrays containing a name and (if provided) a version
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