php-composer 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -10
  3. data/Gemfile +15 -15
  4. data/LICENSE.txt +21 -21
  5. data/README.md +35 -35
  6. data/Rakefile +1 -1
  7. data/lib/composer.rb +52 -52
  8. data/lib/composer/error.rb +8 -8
  9. data/lib/composer/json/json_file.rb +270 -270
  10. data/lib/composer/package/alias_package.rb +273 -273
  11. data/lib/composer/package/base_package.rb +130 -130
  12. data/lib/composer/package/complete_package.rb +55 -55
  13. data/lib/composer/package/dumper/hash_dumper.rb +169 -169
  14. data/lib/composer/package/link.rb +51 -51
  15. data/lib/composer/package/link_constraint/base_constraint.rb +35 -35
  16. data/lib/composer/package/link_constraint/empty_constraint.rb +34 -34
  17. data/lib/composer/package/link_constraint/multi_constraint.rb +66 -66
  18. data/lib/composer/package/link_constraint/specific_constraint.rb +40 -40
  19. data/lib/composer/package/link_constraint/version_constraint.rb +220 -220
  20. data/lib/composer/package/loader/hash_loader.rb +316 -316
  21. data/lib/composer/package/loader/json_loader.rb +47 -47
  22. data/lib/composer/package/loader/project_attributes_loader.rb +71 -71
  23. data/lib/composer/package/loader/project_root_package_loader.rb +28 -28
  24. data/lib/composer/package/package.rb +118 -118
  25. data/lib/composer/package/root_alias_package.rb +37 -37
  26. data/lib/composer/package/root_package.rb +37 -37
  27. data/lib/composer/package/version/version_parser.rb +583 -583
  28. data/lib/composer/package/version/version_selector.rb +106 -106
  29. data/lib/composer/repository/filesystem_repository.rb +84 -85
  30. data/lib/composer/repository/{array_repository.rb → hash_repository.rb} +195 -195
  31. data/lib/composer/repository/{writeable_array_repository.rb → writeable_hash_repository.rb} +57 -59
  32. data/lib/composer/version.rb +3 -3
  33. data/php-composer.gemspec +31 -31
  34. metadata +4 -4
@@ -1,221 +1,221 @@
1
- #
2
- # This file was ported to ruby from Composer php source code file.
3
- # Original Source: Composer\Package\LinkConstraint\VersionConstraint.php
4
- #
5
- # (c) Nils Adermann <naderman@naderman.de>
6
- # Jordi Boggiano <j.boggiano@seld.be>
7
- #
8
- # For the full copyright and license information, please view the LICENSE
9
- # file that was distributed with this source code.
10
- #
11
-
12
- module Composer
13
- module Package
14
- module LinkConstraint
15
- class VersionConstraint < SpecificConstraint
16
- attr_reader :operator, :version
17
-
18
- @@cache = nil
19
-
20
- # Sets operator and version to compare a package with
21
- # @param string $operator A comparison operator
22
- # @param string $version A version to compare to
23
- def initialize(operator, version)
24
- if operator === '='
25
- operator = '=='
26
- end
27
-
28
- if operator === '<>'
29
- operator = '!='
30
- end
31
-
32
- @operator = operator
33
- @version = version
34
- end
35
-
36
- def version_compare(a, b, operator, compare_branches = false)
37
-
38
- a_is_branch = 'dev-' === a[0...4]
39
- b_is_branch = 'dev-' === b[0...4]
40
- if a_is_branch && b_is_branch
41
- return operator == '==' && a === b
42
- end
43
-
44
- # when branches are not comparable, we make sure dev branches never match anything
45
- if !compare_branches && (a_is_branch || b_is_branch)
46
- return false
47
- end
48
-
49
- # Standardise versions
50
- ver_a = a.strip.gsub(/([\-?\_?\+?])/, '.').gsub(/([^0-9\.]+)/, '.$1.').gsub(/\.\./, '.').split('.')
51
- ver_b = b.strip.gsub(/([\-?\_?\+?])/, '.').gsub(/([^0-9\.]+)/, '.$1.').gsub(/\.\./, '.').split('.')
52
-
53
- # Replace empty entries at the start of the array
54
- while ver_a[0] && ver_a[0].empty?
55
- ver_a.shift
56
- end
57
- while ver_b[0] && ver_b[0].empty?
58
- ver_b.shift
59
- end
60
-
61
- # Release state order
62
- # '#' stands for any number
63
- versions = {
64
- 'dev' => 0,
65
- 'alpha' => 1,
66
- 'a' => 1,
67
- 'beta' => 2,
68
- 'b' => 2,
69
- 'RC' => 3,
70
- '#' => 4,
71
- 'p' => 5,
72
- 'pl' => 5
73
- }
74
-
75
- # Loop through each segment in the version string
76
- compare = 0
77
- for i in 0..([ver_a.length, ver_b.length].min - 1)
78
- # for (i = 0, $x = [ver_a.length, ver_b.length].min; i < $x; i++) {
79
-
80
- next if ver_a[i] == ver_b[i]
81
-
82
- i1 = ver_a[i]
83
- i2 = ver_b[i]
84
-
85
- i1_is_numeric = true if Float(i1) rescue false
86
- i2_is_numeric = true if Float(i2) rescue false
87
-
88
- if i1_is_numeric && i2_is_numeric
89
- compare = (i1 < i2) ? -1 : 1
90
- break
91
- end
92
-
93
- # We use the position of '#' in the versions list
94
- # for numbers... (so take care of # in original string)
95
- if i1 == '#'
96
- i1 = ''
97
- elsif i1_is_numeric
98
- i1 = '#';
99
- end
100
-
101
- if i2 == '#'
102
- i2 = ''
103
- elsif i2_is_numeric
104
- i2 = '#'
105
- end
106
-
107
- if !versions[i1].nil? && versions[i2].nil?
108
- compare = versions[i1] < versions[i2] ? -1 : 1
109
- elsif !versions[i1].nil?
110
- compare = 1;
111
- elsif !versions[i2].nil?
112
- compare = -1;
113
- else
114
- compare = 0;
115
- end
116
-
117
- break;
118
-
119
- end
120
-
121
- # If previous loop didn't find anything, compare the "extra" segments
122
- if compare == 0
123
- if ver_b.length > ver_a.length
124
- if !ver_b[i].nil && !versions[ver_b[i]].nil
125
- compare = (versions[ver_b[i]] < 4) ? 1 : -1;
126
- else
127
- compare = -1;
128
- end
129
- elsif ver_b.length < ver_a.length
130
- if !ver_a[i].nil && !versions[ver_a[i]].nil
131
- compare = (versions[ver_a[i]] < 4) ? -1 : 1;
132
- else
133
- compare = 1;
134
- end
135
- end
136
- end
137
-
138
- # Compare the versions
139
- case operator
140
- when '>', 'gt'
141
- return compare > 0
142
- when '>=', 'ge'
143
- return compare >= 0
144
- when '<=', 'le'
145
- return compare <= 0
146
- when '==', '=', 'eq'
147
- return compare == 0
148
- when '<>', '!=', 'ne'
149
- return compare != 0
150
- when '', '<', 'lt'
151
- return compare < 0
152
- end
153
-
154
- false
155
- end
156
-
157
- # @param VersionConstraint provider
158
- # @param bool compare_branches
159
- # @return bool
160
- def match_specific(provider, compare_branches = false)
161
- @@cache = {} unless @@cache
162
- @@cache[@operator] = {} unless @@cache.key?(@operator)
163
- @@cache[@operator][@version] = {} unless @@cache[@operator].key?(@version)
164
- @@cache[@operator][@version][provider.operator] = {} unless @@cache[@operator][@version].key?(provider.operator)
165
- @@cache[@operator][@version][provider.operator][provider.version] = {} unless @@cache[@operator][@version][provider.operator].key?(provider.version)
166
-
167
- if @@cache[@operator][@version][provider.operator][provider.version].key?(compare_branches)
168
- return @@cache[@operator][@version][provider.operator][provider.version][compare_branches]
169
- end
170
-
171
- (@@cache[@operator][@version][provider.operator][provider.version][compare_branches] = do_match_specific(provider, compare_branches))
172
- end
173
-
174
- def to_s
175
- "#{@operator} #{@version}"
176
- end
177
-
178
- private
179
-
180
- # /**
181
- # * @param VersionConstraint provider
182
- # * @param bool compare_branches
183
- # * @return bool
184
- def do_match_specific(provider, compare_branches = false)
185
- self_op_ne = @operator.gsub('=', '')
186
- provider_op_ne = provider.operator.gsub('=', '')
187
-
188
- self_op_is_eq = '==' === @operator
189
- self_op_is_ne = '!=' === @operator
190
- provider_op_is_eq = '==' === provider.operator
191
- provider_op_is_ne = '!=' === provider.operator
192
-
193
- # '!=' operator is match when other operator is not '==' operator or version is not match
194
- # these kinds of comparisons always have a solution
195
- if self_op_is_ne || provider_op_is_ne
196
- return !self_op_is_eq && !provider_op_is_eq ||
197
- version_compare(provider.version, @version, '!=', compare_branches)
198
- end
199
-
200
- # an example for the condition is <= 2.0 & < 1.0
201
- # these kinds of comparisons always have a solution
202
- if @operator != '==' && self_op_ne == provider_op_ne
203
- return true
204
- end
205
-
206
- if version_compare(provider.version, @version, @operator, compare_branches)
207
- # special case, e.g. require >= 1.0 and provide < 1.0
208
- # 1.0 >= 1.0 but 1.0 is outside of the provided interval
209
- if provider.version == @version && provider.operator == provider_op_ne && @operator != self_op_ne
210
- return false
211
- end
212
-
213
- return true
214
- end
215
-
216
- false
217
- end
218
- end
219
- end
220
- end
1
+ #
2
+ # This file was ported to ruby from Composer php source code file.
3
+ # Original Source: Composer\Package\LinkConstraint\VersionConstraint.php
4
+ #
5
+ # (c) Nils Adermann <naderman@naderman.de>
6
+ # Jordi Boggiano <j.boggiano@seld.be>
7
+ #
8
+ # For the full copyright and license information, please view the LICENSE
9
+ # file that was distributed with this source code.
10
+ #
11
+
12
+ module Composer
13
+ module Package
14
+ module LinkConstraint
15
+ class VersionConstraint < SpecificConstraint
16
+ attr_reader :operator, :version
17
+
18
+ @@cache = nil
19
+
20
+ # Sets operator and version to compare a package with
21
+ # @param string $operator A comparison operator
22
+ # @param string $version A version to compare to
23
+ def initialize(operator, version)
24
+ if operator === '='
25
+ operator = '=='
26
+ end
27
+
28
+ if operator === '<>'
29
+ operator = '!='
30
+ end
31
+
32
+ @operator = operator
33
+ @version = version
34
+ end
35
+
36
+ def version_compare(a, b, operator, compare_branches = false)
37
+
38
+ a_is_branch = 'dev-' === a[0...4]
39
+ b_is_branch = 'dev-' === b[0...4]
40
+ if a_is_branch && b_is_branch
41
+ return operator == '==' && a === b
42
+ end
43
+
44
+ # when branches are not comparable, we make sure dev branches never match anything
45
+ if !compare_branches && (a_is_branch || b_is_branch)
46
+ return false
47
+ end
48
+
49
+ # Standardise versions
50
+ ver_a = a.strip.gsub(/([\-?\_?\+?])/, '.').gsub(/([^0-9\.]+)/, '.$1.').gsub(/\.\./, '.').split('.')
51
+ ver_b = b.strip.gsub(/([\-?\_?\+?])/, '.').gsub(/([^0-9\.]+)/, '.$1.').gsub(/\.\./, '.').split('.')
52
+
53
+ # Replace empty entries at the start of the array
54
+ while ver_a[0] && ver_a[0].empty?
55
+ ver_a.shift
56
+ end
57
+ while ver_b[0] && ver_b[0].empty?
58
+ ver_b.shift
59
+ end
60
+
61
+ # Release state order
62
+ # '#' stands for any number
63
+ versions = {
64
+ 'dev' => 0,
65
+ 'alpha' => 1,
66
+ 'a' => 1,
67
+ 'beta' => 2,
68
+ 'b' => 2,
69
+ 'RC' => 3,
70
+ '#' => 4,
71
+ 'p' => 5,
72
+ 'pl' => 5
73
+ }
74
+
75
+ # Loop through each segment in the version string
76
+ compare = 0
77
+ for i in 0..([ver_a.length, ver_b.length].min - 1)
78
+ # for (i = 0, $x = [ver_a.length, ver_b.length].min; i < $x; i++) {
79
+
80
+ next if ver_a[i] == ver_b[i]
81
+
82
+ i1 = ver_a[i]
83
+ i2 = ver_b[i]
84
+
85
+ i1_is_numeric = true if Float(i1) rescue false
86
+ i2_is_numeric = true if Float(i2) rescue false
87
+
88
+ if i1_is_numeric && i2_is_numeric
89
+ compare = (i1 < i2) ? -1 : 1
90
+ break
91
+ end
92
+
93
+ # We use the position of '#' in the versions list
94
+ # for numbers... (so take care of # in original string)
95
+ if i1 == '#'
96
+ i1 = ''
97
+ elsif i1_is_numeric
98
+ i1 = '#';
99
+ end
100
+
101
+ if i2 == '#'
102
+ i2 = ''
103
+ elsif i2_is_numeric
104
+ i2 = '#'
105
+ end
106
+
107
+ if !versions[i1].nil? && versions[i2].nil?
108
+ compare = versions[i1] < versions[i2] ? -1 : 1
109
+ elsif !versions[i1].nil?
110
+ compare = 1;
111
+ elsif !versions[i2].nil?
112
+ compare = -1;
113
+ else
114
+ compare = 0;
115
+ end
116
+
117
+ break;
118
+
119
+ end
120
+
121
+ # If previous loop didn't find anything, compare the "extra" segments
122
+ if compare == 0
123
+ if ver_b.length > ver_a.length
124
+ if !ver_b[i].nil && !versions[ver_b[i]].nil
125
+ compare = (versions[ver_b[i]] < 4) ? 1 : -1;
126
+ else
127
+ compare = -1;
128
+ end
129
+ elsif ver_b.length < ver_a.length
130
+ if !ver_a[i].nil && !versions[ver_a[i]].nil
131
+ compare = (versions[ver_a[i]] < 4) ? -1 : 1;
132
+ else
133
+ compare = 1;
134
+ end
135
+ end
136
+ end
137
+
138
+ # Compare the versions
139
+ case operator
140
+ when '>', 'gt'
141
+ return compare > 0
142
+ when '>=', 'ge'
143
+ return compare >= 0
144
+ when '<=', 'le'
145
+ return compare <= 0
146
+ when '==', '=', 'eq'
147
+ return compare == 0
148
+ when '<>', '!=', 'ne'
149
+ return compare != 0
150
+ when '', '<', 'lt'
151
+ return compare < 0
152
+ end
153
+
154
+ false
155
+ end
156
+
157
+ # @param VersionConstraint provider
158
+ # @param bool compare_branches
159
+ # @return bool
160
+ def match_specific(provider, compare_branches = false)
161
+ @@cache = {} unless @@cache
162
+ @@cache[@operator] = {} unless @@cache.key?(@operator)
163
+ @@cache[@operator][@version] = {} unless @@cache[@operator].key?(@version)
164
+ @@cache[@operator][@version][provider.operator] = {} unless @@cache[@operator][@version].key?(provider.operator)
165
+ @@cache[@operator][@version][provider.operator][provider.version] = {} unless @@cache[@operator][@version][provider.operator].key?(provider.version)
166
+
167
+ if @@cache[@operator][@version][provider.operator][provider.version].key?(compare_branches)
168
+ return @@cache[@operator][@version][provider.operator][provider.version][compare_branches]
169
+ end
170
+
171
+ (@@cache[@operator][@version][provider.operator][provider.version][compare_branches] = do_match_specific(provider, compare_branches))
172
+ end
173
+
174
+ def to_s
175
+ "#{@operator} #{@version}"
176
+ end
177
+
178
+ private
179
+
180
+ # /**
181
+ # * @param VersionConstraint provider
182
+ # * @param bool compare_branches
183
+ # * @return bool
184
+ def do_match_specific(provider, compare_branches = false)
185
+ self_op_ne = @operator.gsub('=', '')
186
+ provider_op_ne = provider.operator.gsub('=', '')
187
+
188
+ self_op_is_eq = '==' === @operator
189
+ self_op_is_ne = '!=' === @operator
190
+ provider_op_is_eq = '==' === provider.operator
191
+ provider_op_is_ne = '!=' === provider.operator
192
+
193
+ # '!=' operator is match when other operator is not '==' operator or version is not match
194
+ # these kinds of comparisons always have a solution
195
+ if self_op_is_ne || provider_op_is_ne
196
+ return !self_op_is_eq && !provider_op_is_eq ||
197
+ version_compare(provider.version, @version, '!=', compare_branches)
198
+ end
199
+
200
+ # an example for the condition is <= 2.0 & < 1.0
201
+ # these kinds of comparisons always have a solution
202
+ if @operator != '==' && self_op_ne == provider_op_ne
203
+ return true
204
+ end
205
+
206
+ if version_compare(provider.version, @version, @operator, compare_branches)
207
+ # special case, e.g. require >= 1.0 and provide < 1.0
208
+ # 1.0 >= 1.0 but 1.0 is outside of the provided interval
209
+ if provider.version == @version && provider.operator == provider_op_ne && @operator != self_op_ne
210
+ return false
211
+ end
212
+
213
+ return true
214
+ end
215
+
216
+ false
217
+ end
218
+ end
219
+ end
220
+ end
221
221
  end
@@ -1,316 +1,316 @@
1
- #
2
- # This file was ported to ruby from Composer php source code.
3
- # Original Source: Composer\Package\Loader\ArrayLoader.php
4
- #
5
- # (c) Nils Adermann <naderman@naderman.de>
6
- # Jordi Boggiano <j.boggiano@seld.be>
7
- #
8
- # For the full copyright and license information, please view the LICENSE
9
- # file that was distributed with this source code.
10
- #
11
-
12
- module Composer
13
- module Package
14
- module Loader
15
- # Loads a package from a hash
16
- #
17
- # PHP Authors:
18
- # Konstantin Kudryashiv <ever.zet@gmail.com>
19
- # Jordi Boggiano <j.boggiano@seld.be>
20
- #
21
- # Ruby Authors:
22
- # Ioannis Kappas <ikappas@devworks.gr>
23
- class HashLoader
24
- def initialize(parser = nil, load_options = false)
25
- parser = Composer::Package::Version::VersionParser.new unless parser
26
- @version_parser = parser
27
- @load_options = load_options
28
- end
29
-
30
- def load(config, class_name = 'Composer::Package::CompletePackage')
31
- unless config
32
- raise ArgumentError,
33
- 'Invalid package configuration supplied.'
34
- end
35
-
36
- unless config.key?('name')
37
- raise UnexpectedValueError,
38
- "Unknown package has no name defined (#{config.to_json})."
39
- end
40
-
41
- unless config.key?('version')
42
- raise UnexpectedValueError,
43
- "Package #{config['name']} has no version defined."
44
- end
45
-
46
- # handle already normalized versions
47
- if config.key?('version_normalized')
48
- version = config['version_normalized']
49
- else
50
- version = @version_parser.normalize(config['version'])
51
- end
52
-
53
- package = Object.const_get(class_name).new(
54
- config['name'],
55
- version,
56
- config['version']
57
- )
58
-
59
- # parse type
60
- if config.key?('type')
61
- package.type = config['type'].downcase
62
- else
63
- package.type = 'library'
64
- end
65
-
66
- # parse target-dir
67
- if config.key?('target-dir')
68
- package.target_dir = config['target-dir']
69
- end
70
-
71
- # parse extra
72
- if config.key?('extra') && config['extra'].is_a?(Hash)
73
- package.extra = config['extra']
74
- end
75
-
76
- # parse bin
77
- if config.key?('bin')
78
- unless config['bin'].is_a?(Array)
79
- raise UnexpectedValueError,
80
- "Package #{config['name']}'s bin key should be an hash, \
81
- #{config['bin'].class.name} given."
82
- end
83
- config['bin'].each do |bin|
84
- bin.gsub!(/^\/+/, '')
85
- end
86
- package.binaries = config['bin']
87
- end
88
-
89
- # parse installation source
90
- if config.key?('installation-source')
91
- package.installation_source = config['installation-source']
92
- end
93
-
94
- # parse source
95
- if config.key?('source')
96
- if [:type, :url, :reference].all? {|k| config['source'].key? k}
97
- raise UnexpectedValueError,
98
- "Package #{config['name']}'s source key should be \
99
- specified as \
100
- {\"type\": ..., \"url\": ..., \"reference\": ...}, \n
101
- #{config['source'].to_json} given."
102
- end
103
- package.source_type = config['source']['type']
104
- package.source_url = config['source']['url']
105
- package.source_reference = config['source']['reference']
106
- if config['source'].key?('mirrors')
107
- package.source_mirrors = config['source']['mirrors']
108
- end
109
- end
110
-
111
- #parse dist
112
- if config.key?('dist')
113
- if [:type, :url].all? {|k| config['dist'].key? k}
114
- raise UnexpectedValueError,
115
- "Package #{config['name']}'s dist key should be \
116
- specified as \
117
- {\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n
118
- #{config['dist'].to_json} given."
119
- end
120
- package.dist_type = config['dist']['type']
121
- package.dist_url = config['dist']['url']
122
-
123
- package.dist_reference = config['dist'].key?('reference') ?
124
- config['dist']['reference'] : nil
125
-
126
- package.dist_sha1_checksum = config['dist'].key?('shasum') ?
127
- config['dist']['shasum'] : nil
128
-
129
- if config['dist'].key?('mirrors')
130
- package.dist_mirrors = config['dist']['mirrors']
131
- end
132
- end
133
-
134
- # parse supported link types
135
- Composer::Package::BasePackage::SUPPORTED_LINK_TYPES.each do |type, opts|
136
- next if !config.key?(type)
137
- package.send(
138
- "#{opts['method']}=",
139
- @version_parser.parse_links(
140
- package.name,
141
- package.pretty_version,
142
- opts['description'],
143
- config[type]
144
- )
145
- )
146
- end
147
-
148
- # parse suggest
149
- if config.key?('suggest') && config['suggest'].is_a?(Hash)
150
- config['suggest'].each do |target, reason|
151
- if 'self.version' === reason.strip!
152
- config['suggest'][target] = package.pretty_version
153
- end
154
- end
155
- package.suggests = config['suggest']
156
- end
157
-
158
- # parse autoload
159
- if config.key? 'autoload'
160
- package.autoload = config['autoload']
161
- end
162
-
163
- # parse autoload-dev
164
- if config.key? 'autoload-dev'
165
- package.dev_autoload = config['autoload-dev']
166
- end
167
-
168
- # parse include-path
169
- if config.key? 'include-path'
170
- package.include_paths = config['include-path']
171
- end
172
-
173
- # parse time
174
- if !is_empty?(config, 'time')
175
- time = is_numeric?(config['time']) ? "@#{config['time']}" : config['time']
176
- begin
177
- date = Time.zone.parse(time)
178
- package.release_date = date
179
- rescue Exception => e
180
- log("Time Exception #{e}")
181
- end
182
- end
183
-
184
- # parse notification url
185
- if !is_empty?(config, 'notification-url')
186
- package.notification_url = config['notification-url']
187
- end
188
-
189
- # parse archive excludes
190
- if config.key?('archive') &&
191
- config['archive'].key?('exclude') &&
192
- !config['archive']['exclude'].empty?
193
- package.archive_excludes = config['archive']['exclude']
194
- end
195
-
196
- if package.instance_of?(Composer::Package::CompletePackage)
197
-
198
- # parse scripts
199
- if config.key?('scripts') && config['scripts'].is_a?(Array)
200
- config['scripts'].each do |event, listeners|
201
- config['scripts'][event] = Array(listeners)
202
- end
203
- package.scripts = config['scripts']
204
- end
205
-
206
- # parse description
207
- if !is_empty?(config, 'description') && config['description'].is_a?(String)
208
- package.description = config['description']
209
- end
210
-
211
- # parse homepage
212
- if !is_empty?(config, 'homepage') && config['homepage'].is_a?(String)
213
- package.homepage = config['homepage']
214
- end
215
-
216
- # parse keywords
217
- if !is_empty?(config, 'keywords') && config['keywords'].is_a?(Array)
218
- package.keywords = config['keywords']
219
- end
220
-
221
- # parse license
222
- if !is_empty?(config, 'license')
223
- package.license = config['license'].is_a?(Array) ? config['license'] : [config['license']]
224
- end
225
-
226
- # parse authors
227
- if !is_empty?(config, 'authors') && config['authors'].is_a?(Array)
228
- package.authors = config['authors']
229
- end
230
-
231
- # parse support
232
- if config.key?('support')
233
- package.support = config['support']
234
- end
235
-
236
- # parse abandoned
237
- if config.key?('abandoned')
238
- package.abandoned = config['abandoned']
239
- end
240
-
241
- end
242
-
243
- if alias_normalized = get_branch_alias(config)
244
- if package.instance_of?(Composer::Package::RootPackage)
245
- package = Composer::Package::RootAliasPackage.new(
246
- package,
247
- alias_normalized,
248
- alias_normalized.gsub(/(\.9{7})+/, '.x')
249
- )
250
- else
251
- package = Composer::Package::AliasPackage.new(
252
- package,
253
- alias_normalized,
254
- alias_normalized.gsub(/(\.9{7})+/, '.x')
255
- )
256
- end
257
- end
258
-
259
- if @load_options && config.key?('transport-options')
260
- package.transport_options = config['transport-options']
261
- end
262
-
263
- package
264
- end
265
-
266
- # Retrieves a branch alias
267
- # (dev-master => 1.0.x-dev for example) if it exists
268
- #
269
- # Params:
270
- # +config+ array The entire package config
271
- #
272
- # Returns:
273
- # string|nil normalized version of the branch alias
274
- # or null if there is none
275
- def get_branch_alias(config)
276
- return nil unless
277
- (config['version'].start_with?('dev-') || config['version'].end_with?('-dev')) &&
278
- config.key?('extra') &&
279
- config['extra'].key?('branch-alias') &&
280
- config['extra']['branch-alias'].is_a?(Hash)
281
-
282
- config['extra']['branch-alias'].each do |source_branch, target_branch|
283
- # ensure it is an alias to a -dev package
284
- next if !target_branch.end_with?('-dev')
285
-
286
- # normalize without -dev and ensure it's a numeric branch that is parseable
287
- validated_target_branch = @version_parser.normalize_branch(target_branch[0..-5])
288
- next if !validated_target_branch.end_with?('-dev')
289
-
290
- # ensure that it is the current branch aliasing itself
291
- next if config['version'].downcase != source_branch.downcase
292
-
293
- # If using numeric aliases ensure the alias is a valid subversion
294
- source_prefix = @version_parser.parse_numeric_alias_prefix(source_branch)
295
- target_prefix = @version_parser.parse_numeric_alias_prefix(target_branch)
296
- next if source_prefix && target_prefix && target_prefix.index(source_prefix) != 0 #(stripos($targetPrefix, $sourcePrefix) !== 0)
297
-
298
- return validated_target_branch
299
- end
300
- nil
301
- end
302
-
303
- private
304
-
305
- def is_numeric?(value)
306
- true if Float(value) rescue false
307
- end
308
-
309
- def is_empty?(config, key)
310
- config.key?(key) ? config[key].empty? : true
311
- end
312
-
313
- end
314
- end
315
- end
316
- end
1
+ #
2
+ # This file was ported to ruby from Composer php source code.
3
+ # Original Source: Composer\Package\Loader\ArrayLoader.php
4
+ #
5
+ # (c) Nils Adermann <naderman@naderman.de>
6
+ # Jordi Boggiano <j.boggiano@seld.be>
7
+ #
8
+ # For the full copyright and license information, please view the LICENSE
9
+ # file that was distributed with this source code.
10
+ #
11
+
12
+ module Composer
13
+ module Package
14
+ module Loader
15
+ # Loads a package from a hash
16
+ #
17
+ # PHP Authors:
18
+ # Konstantin Kudryashiv <ever.zet@gmail.com>
19
+ # Jordi Boggiano <j.boggiano@seld.be>
20
+ #
21
+ # Ruby Authors:
22
+ # Ioannis Kappas <ikappas@devworks.gr>
23
+ class HashLoader
24
+ def initialize(parser = nil, load_options = false)
25
+ parser = Composer::Package::Version::VersionParser.new unless parser
26
+ @version_parser = parser
27
+ @load_options = load_options
28
+ end
29
+
30
+ def load(config, class_name = 'Composer::Package::CompletePackage')
31
+ unless config
32
+ raise ArgumentError,
33
+ 'Invalid package configuration supplied.'
34
+ end
35
+
36
+ unless config.key?('name')
37
+ raise UnexpectedValueError,
38
+ "Unknown package has no name defined (#{config.to_json})."
39
+ end
40
+
41
+ unless config.key?('version')
42
+ raise UnexpectedValueError,
43
+ "Package #{config['name']} has no version defined."
44
+ end
45
+
46
+ # handle already normalized versions
47
+ if config.key?('version_normalized')
48
+ version = config['version_normalized']
49
+ else
50
+ version = @version_parser.normalize(config['version'])
51
+ end
52
+
53
+ package = Object.const_get(class_name).new(
54
+ config['name'],
55
+ version,
56
+ config['version']
57
+ )
58
+
59
+ # parse type
60
+ if config.key?('type')
61
+ package.type = config['type'].downcase
62
+ else
63
+ package.type = 'library'
64
+ end
65
+
66
+ # parse target-dir
67
+ if config.key?('target-dir')
68
+ package.target_dir = config['target-dir']
69
+ end
70
+
71
+ # parse extra
72
+ if config.key?('extra') && config['extra'].is_a?(Hash)
73
+ package.extra = config['extra']
74
+ end
75
+
76
+ # parse bin
77
+ if config.key?('bin')
78
+ unless config['bin'].is_a?(Array)
79
+ raise UnexpectedValueError,
80
+ "Package #{config['name']}'s bin key should be an hash, \
81
+ #{config['bin'].class.name} given."
82
+ end
83
+ config['bin'].each do |bin|
84
+ bin.gsub!(/^\/+/, '')
85
+ end
86
+ package.binaries = config['bin']
87
+ end
88
+
89
+ # parse installation source
90
+ if config.key?('installation-source')
91
+ package.installation_source = config['installation-source']
92
+ end
93
+
94
+ # parse source
95
+ if config.key?('source')
96
+ if [:type, :url, :reference].all? {|k| config['source'].key? k}
97
+ raise UnexpectedValueError,
98
+ "Package #{config['name']}'s source key should be \
99
+ specified as \
100
+ {\"type\": ..., \"url\": ..., \"reference\": ...}, \n
101
+ #{config['source'].to_json} given."
102
+ end
103
+ package.source_type = config['source']['type']
104
+ package.source_url = config['source']['url']
105
+ package.source_reference = config['source']['reference']
106
+ if config['source'].key?('mirrors')
107
+ package.source_mirrors = config['source']['mirrors']
108
+ end
109
+ end
110
+
111
+ #parse dist
112
+ if config.key?('dist')
113
+ if [:type, :url].all? {|k| config['dist'].key? k}
114
+ raise UnexpectedValueError,
115
+ "Package #{config['name']}'s dist key should be \
116
+ specified as \
117
+ {\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n
118
+ #{config['dist'].to_json} given."
119
+ end
120
+ package.dist_type = config['dist']['type']
121
+ package.dist_url = config['dist']['url']
122
+
123
+ package.dist_reference = config['dist'].key?('reference') ?
124
+ config['dist']['reference'] : nil
125
+
126
+ package.dist_sha1_checksum = config['dist'].key?('shasum') ?
127
+ config['dist']['shasum'] : nil
128
+
129
+ if config['dist'].key?('mirrors')
130
+ package.dist_mirrors = config['dist']['mirrors']
131
+ end
132
+ end
133
+
134
+ # parse supported link types
135
+ Composer::Package::BasePackage::SUPPORTED_LINK_TYPES.each do |type, opts|
136
+ next if !config.key?(type)
137
+ package.send(
138
+ "#{opts['method']}=",
139
+ @version_parser.parse_links(
140
+ package.name,
141
+ package.pretty_version,
142
+ opts['description'],
143
+ config[type]
144
+ )
145
+ )
146
+ end
147
+
148
+ # parse suggest
149
+ if config.key?('suggest') && config['suggest'].is_a?(Hash)
150
+ config['suggest'].each do |target, reason|
151
+ if 'self.version' === reason.strip!
152
+ config['suggest'][target] = package.pretty_version
153
+ end
154
+ end
155
+ package.suggests = config['suggest']
156
+ end
157
+
158
+ # parse autoload
159
+ if config.key? 'autoload'
160
+ package.autoload = config['autoload']
161
+ end
162
+
163
+ # parse autoload-dev
164
+ if config.key? 'autoload-dev'
165
+ package.dev_autoload = config['autoload-dev']
166
+ end
167
+
168
+ # parse include-path
169
+ if config.key? 'include-path'
170
+ package.include_paths = config['include-path']
171
+ end
172
+
173
+ # parse time
174
+ if !is_empty?(config, 'time')
175
+ time = is_numeric?(config['time']) ? "@#{config['time']}" : config['time']
176
+ begin
177
+ date = Time.zone.parse(time)
178
+ package.release_date = date
179
+ rescue Exception => e
180
+ log("Time Exception #{e}")
181
+ end
182
+ end
183
+
184
+ # parse notification url
185
+ if !is_empty?(config, 'notification-url')
186
+ package.notification_url = config['notification-url']
187
+ end
188
+
189
+ # parse archive excludes
190
+ if config.key?('archive') &&
191
+ config['archive'].key?('exclude') &&
192
+ !config['archive']['exclude'].empty?
193
+ package.archive_excludes = config['archive']['exclude']
194
+ end
195
+
196
+ if package.instance_of?(Composer::Package::CompletePackage)
197
+
198
+ # parse scripts
199
+ if config.key?('scripts') && config['scripts'].is_a?(Array)
200
+ config['scripts'].each do |event, listeners|
201
+ config['scripts'][event] = Array(listeners)
202
+ end
203
+ package.scripts = config['scripts']
204
+ end
205
+
206
+ # parse description
207
+ if !is_empty?(config, 'description') && config['description'].is_a?(String)
208
+ package.description = config['description']
209
+ end
210
+
211
+ # parse homepage
212
+ if !is_empty?(config, 'homepage') && config['homepage'].is_a?(String)
213
+ package.homepage = config['homepage']
214
+ end
215
+
216
+ # parse keywords
217
+ if !is_empty?(config, 'keywords') && config['keywords'].is_a?(Array)
218
+ package.keywords = config['keywords']
219
+ end
220
+
221
+ # parse license
222
+ if !is_empty?(config, 'license')
223
+ package.license = config['license'].is_a?(Array) ? config['license'] : [config['license']]
224
+ end
225
+
226
+ # parse authors
227
+ if !is_empty?(config, 'authors') && config['authors'].is_a?(Array)
228
+ package.authors = config['authors']
229
+ end
230
+
231
+ # parse support
232
+ if config.key?('support')
233
+ package.support = config['support']
234
+ end
235
+
236
+ # parse abandoned
237
+ if config.key?('abandoned')
238
+ package.abandoned = config['abandoned']
239
+ end
240
+
241
+ end
242
+
243
+ if alias_normalized = get_branch_alias(config)
244
+ if package.instance_of?(Composer::Package::RootPackage)
245
+ package = Composer::Package::RootAliasPackage.new(
246
+ package,
247
+ alias_normalized,
248
+ alias_normalized.gsub(/(\.9{7})+/, '.x')
249
+ )
250
+ else
251
+ package = Composer::Package::AliasPackage.new(
252
+ package,
253
+ alias_normalized,
254
+ alias_normalized.gsub(/(\.9{7})+/, '.x')
255
+ )
256
+ end
257
+ end
258
+
259
+ if @load_options && config.key?('transport-options')
260
+ package.transport_options = config['transport-options']
261
+ end
262
+
263
+ package
264
+ end
265
+
266
+ # Retrieves a branch alias
267
+ # (dev-master => 1.0.x-dev for example) if it exists
268
+ #
269
+ # Params:
270
+ # +config+ array The entire package config
271
+ #
272
+ # Returns:
273
+ # string|nil normalized version of the branch alias
274
+ # or null if there is none
275
+ def get_branch_alias(config)
276
+ return nil unless
277
+ (config['version'].start_with?('dev-') || config['version'].end_with?('-dev')) &&
278
+ config.key?('extra') &&
279
+ config['extra'].key?('branch-alias') &&
280
+ config['extra']['branch-alias'].is_a?(Hash)
281
+
282
+ config['extra']['branch-alias'].each do |source_branch, target_branch|
283
+ # ensure it is an alias to a -dev package
284
+ next if !target_branch.end_with?('-dev')
285
+
286
+ # normalize without -dev and ensure it's a numeric branch that is parseable
287
+ validated_target_branch = @version_parser.normalize_branch(target_branch[0..-5])
288
+ next if !validated_target_branch.end_with?('-dev')
289
+
290
+ # ensure that it is the current branch aliasing itself
291
+ next if config['version'].downcase != source_branch.downcase
292
+
293
+ # If using numeric aliases ensure the alias is a valid subversion
294
+ source_prefix = @version_parser.parse_numeric_alias_prefix(source_branch)
295
+ target_prefix = @version_parser.parse_numeric_alias_prefix(target_branch)
296
+ next if source_prefix && target_prefix && target_prefix.index(source_prefix) != 0 #(stripos($targetPrefix, $sourcePrefix) !== 0)
297
+
298
+ return validated_target_branch
299
+ end
300
+ nil
301
+ end
302
+
303
+ private
304
+
305
+ def is_numeric?(value)
306
+ true if Float(value) rescue false
307
+ end
308
+
309
+ def is_empty?(config, key)
310
+ config.key?(key) ? config[key].empty? : true
311
+ end
312
+
313
+ end
314
+ end
315
+ end
316
+ end