php-composer 0.4.5 → 1.0.0.pre.alpha11

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1 @@
1
+ 2.1.7
data/Gemfile CHANGED
@@ -2,12 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in composer.gemspec
4
4
  gemspec
5
-
6
- gem 'json', '>= 1.8', :platforms => [:mri_18, :mri_19]
7
- gem 'json-schema', '>= 2.5.0'
8
-
9
- group :development, :test do
10
- gem 'rubocop', '>= 0.35.0', require: false
11
- gem 'rspec'
12
- gem 'simplecov', '>= 0.10.0'
13
- end
data/Rakefile CHANGED
@@ -1 +1,12 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ desc 'Run all specs'
6
+ RSpec::Core::RakeTask.new
7
+
8
+ desc 'Run RuboCop'
9
+ RuboCop::RakeTask.new
10
+
11
+ task(:default).clear
12
+ task default: [:rubocop, :spec]
@@ -1,54 +1,57 @@
1
1
  # external
2
2
  require 'json'
3
- require 'json-schema'
4
-
5
- # /
6
- require 'composer/version'
7
- require 'composer/error'
8
-
9
- # /json
10
- require 'composer/json/json_validaton_error'
11
- require 'composer/json/json_file'
12
- require 'composer/json/json_formatter'
13
-
14
- # /package
15
- require 'composer/package/base_package'
16
- require 'composer/package/package'
17
- require 'composer/package/complete_package'
18
- require 'composer/package/alias_package'
19
- require 'composer/package/root_alias_package'
20
- require 'composer/package/root_package'
21
- require 'composer/package/link'
22
-
23
- # /package/dumper
24
- require 'composer/package/dumper/hash_dumper'
25
-
26
- # /package/link_constraint
27
- require 'composer/package/link_constraint/base_constraint'
28
- require 'composer/package/link_constraint/empty_constraint'
29
- require 'composer/package/link_constraint/specific_constraint'
30
- require 'composer/package/link_constraint/version_constraint'
31
- require 'composer/package/link_constraint/multi_constraint'
32
-
33
- # /package/loader
34
- require 'composer/package/loader/hash_loader'
35
- require 'composer/package/loader/json_loader'
36
-
37
- # /package/version
38
- require 'composer/package/version/version_parser'
39
- require 'composer/package/version/version_selector'
40
-
41
- # Dir[File.join(File.dirname(__FILE__), "composer/package/dumper/*.rb")].each {|file| require file }
42
- # Dir[File.join(File.dirname(__FILE__), "composer/package/link_constraint/*.rb")].each {|file| require file }
43
- # Dir[File.join(File.dirname(__FILE__), "composer/package/loader/*.rb")].each {|file| require file }
44
- # Dir[File.join(File.dirname(__FILE__), "composer/package/version/*.rb")].each {|file| require file }
45
-
46
- # /repository
47
- require 'composer/repository/base_repository'
48
- require 'composer/repository/hash_repository'
49
- require 'composer/repository/writeable_hash_repository'
50
- require 'composer/repository/filesystem_repository'
51
- require 'composer/repository/composite_repository'
52
3
 
4
+ # project
53
5
  module Composer
6
+
7
+ GEM_VERSION = '1.0.0-alpha11'
8
+
9
+ class Error < ::StandardError; end
10
+ class ArgumentError < Error; end
11
+ class TypeError < Error; end
12
+ class UnexpectedValueError < Error; end
13
+ class LogicError < Error; end
14
+ class InvalidRepositoryError < Error; end
15
+
16
+ module Json
17
+ autoload :JsonFile, 'composer/json/json_file'
18
+ autoload :JsonFormatter, 'composer/json/json_formatter'
19
+ autoload :JsonValidationError, 'composer/json/json_validation_error'
20
+ end
21
+
22
+ module Package
23
+ autoload :Package, 'composer/package/package'
24
+ autoload :CompletePackage, 'composer/package/complete_package'
25
+ autoload :AliasPackage, 'composer/package/alias_package'
26
+ autoload :RootAliasPackage, 'composer/package/root_alias_package'
27
+ autoload :RootPackage, 'composer/package/root_package'
28
+ autoload :Link, 'composer/package/link'
29
+
30
+ module Dumper
31
+ autoload :HashDumper,'composer/package/dumper/hash_dumper'
32
+ end
33
+
34
+ module Loader
35
+ autoload :HashLoader, 'composer/package/loader/hash_loader'
36
+ autoload :JsonLoader, 'composer/package/loader/json_loader'
37
+ end
38
+
39
+ module Version
40
+ autoload :VersionParser, 'composer/package/version/version_parser'
41
+ autoload :VersionSelector, 'composer/package/version/version_selector'
42
+ end
43
+ end
44
+
45
+ module Repository
46
+ autoload :BaseRepository, 'composer/repository/base_repository'
47
+ autoload :HashRepository, 'composer/repository/hash_repository'
48
+ autoload :WritableHashRepository, 'composer/repository/writeable_hash_repository'
49
+ autoload :FilesystemRepository, 'composer/repository/filesystem_repository'
50
+ autoload :CompositeRepository, 'composer/repository/composite_repository'
51
+ end
52
+
53
+ module Util
54
+ autoload :ComposerMirror, 'composer/util/composer_mirror'
55
+ end
56
+
54
57
  end
@@ -1,6 +1,8 @@
1
1
  #
2
2
  # This file was ported to ruby from Composer php source code file.
3
+ #
3
4
  # Original Source: Composer\Json\JsonFile.php
5
+ # Ref SHA: ce085826711a6354024203c6530ee0b56fea9c13
4
6
  #
5
7
  # (c) Nils Adermann <naderman@naderman.de>
6
8
  # Jordi Boggiano <j.boggiano@seld.be>
@@ -9,8 +11,11 @@
9
11
  # file that was distributed with this source code.
10
12
  #
11
13
 
14
+ require 'json-schema'
15
+
12
16
  module Composer
13
17
  module Json
18
+
14
19
  # Reads/writes json files.
15
20
  #
16
21
  # PHP Authors:
@@ -20,38 +25,38 @@ module Composer
20
25
  # Ruby Authors:
21
26
  # Ioannis Kappas <ikappas@devworks.gr>
22
27
  class JsonFile
28
+
23
29
  attr_reader :path
30
+ attr :rfs, :json_last_error
31
+
32
+ private :rfs, :json_last_error
24
33
 
25
34
  LAX_SCHEMA = 1
26
35
  STRICT_SCHEMA = 2
27
36
 
28
- JSON_ERROR_NONE = 0
29
- JSON_ERROR_DEPTH = 1
30
- JSON_ERROR_STATE_MISMATCH = 2
31
- JSON_ERROR_CTRL_CHAR = 3
32
- JSON_ERROR_SYNTAX = 4
33
- JSON_ERROR_UTF8 = 5
34
- JSON_ERROR_RECURSION = 6
35
- JSON_ERROR_INF_OR_NAN = 7
36
- JSON_ERROR_UNSUPPORTED_TYPE = 8
37
+ JSON_UNESCAPED_SLASHES = 64
38
+ JSON_PRETTY_PRINT = 128
39
+ JSON_UNESCAPED_UNICODE = 256
37
40
 
38
41
  # Initializes json file reader/parser.
42
+ #
39
43
  # @param [String] path path to a json file
40
44
  # @param [RemoteFileSystem] rfs The remote filesystem to use for http/https json files
41
45
  # @raise [ArgumentError]
42
46
  def initialize(path, rfs = nil)
43
47
  @path = path
44
- if rfs === nil && /^https?:\/\//i.match(path)
48
+ if rfs.nil? && /^https?:\/\//i.match(path)
45
49
  raise ArgumentError,
46
50
  'http urls require a RemoteFilesystem instance to be passed'
47
51
  end
48
52
  @rfs = rfs
53
+ @json_last_error = nil
49
54
  end
50
55
 
51
56
  # Checks whether this json file exists.
52
57
  #
53
58
  # Returns:
54
- # true if this json file exists; otherwise false.
59
+ # true if this json file exists; otherwise false.
55
60
  def exists?
56
61
  File.exists?(@path)
57
62
  end
@@ -59,45 +64,61 @@ module Composer
59
64
  # Reads the json file.
60
65
  #
61
66
  # Raises:
62
- # RuntimeError
67
+ # RuntimeError on error.
63
68
  #
64
69
  # Returns:
65
- # mixed
70
+ # mixed
66
71
  def read
67
- if @rfs
68
- json = @rfs.get_contents(@path, @path, false)
69
- else
70
- json = File.open(@path, 'r') { |f| f.read }
71
- end
72
72
 
73
- JsonFile::parse_json(json, @path)
73
+ begin
74
+
75
+ if @rfs
76
+ json = @rfs.get_contents(@path, @path, false)
77
+ else
78
+ json = File.open(@path, 'r') { |f| f.read }
79
+ end
80
+
81
+ # rescue TransportError => e
82
+ # raise RuntimeError, e.message
74
83
 
75
- rescue Exception => e
76
- raise e
84
+ rescue => e
85
+ raise RuntimeError,
86
+ "Could not read #{@path}\n\n #{e.message}"
87
+ end
88
+
89
+ ::Composer::Json::JsonFile::parse_json(json, @path)
77
90
  end
78
91
 
92
+ # Writes the json file.
93
+ #
94
+ # @param hash The hash to write to the json file.
95
+ # @param options The options to use
79
96
  def write(hash, options = 448)
80
- dir = File.dirname(@path)
81
97
 
98
+ dir = File.dirname(@path)
82
99
  unless File.directory?(dir)
83
100
  if File.exists?(dir)
84
- raise UnexpectedValueError,
101
+ raise ::Composer::UnexpectedValueError,
85
102
  "#{dir} exists and is not a directory."
86
103
  end
87
- FileUtils.mkdir_p(dir, mode: 0777)
104
+ unless FileUtils.mkdir_p(dir, mode: 0777) == 0
105
+ raise ::Composer::UnexpectedValueError,
106
+ "#{dir} does not exist and could not be created."
107
+ end
88
108
  end
89
109
 
90
110
  retries = 3
91
111
  while retries >= 0
92
112
  begin
93
- file_ending = options & JsonFormatter::JSON_PRETTY_PRINT ? "\n" : ''
113
+
114
+ file_ending = ((options & JSON_PRETTY_PRINT).equal? JSON_PRETTY_PRINT) ? "\n" : ''
94
115
  File.open(@path, 'w') do |f|
95
- content = JsonFile::encode(hash, options) + file_ending
116
+ content = self.class.encode(hash, options) + file_ending
96
117
  f.write(content)
97
118
  end
98
119
  break
99
120
 
100
- rescue Exception => e
121
+ rescue => e
101
122
  raise e unless retries > 0
102
123
  retries -= 1
103
124
  sleep 0.5
@@ -113,10 +134,11 @@ module Composer
113
134
  # @return bool true if schema is valid; Otherwise false.
114
135
  # @throw Composer::Json::JsonValidationError
115
136
  def validate_schema(schema = STRICT_SCHEMA)
137
+
116
138
  content = File.open(@path, 'r') { |f| f.read }
117
139
  data = JSON.parse(content)
118
140
 
119
- if data == nil && content != 'null'
141
+ if data.nil? && content != 'null'
120
142
  self::validate_syntax(content, @path)
121
143
  end
122
144
 
@@ -131,14 +153,15 @@ module Composer
131
153
 
132
154
  if schema === LAX_SCHEMA
133
155
  schema_data['additionalProperties'] = true
134
- schema_data['properties']['name']['required'] = false
135
- schema_data['properties']['description']['required'] = false
156
+ schema_data['required'] = [] # TODO: Check this!
157
+ # schema_data['properties']['name']['required'] = false
158
+ # schema_data['properties']['description']['required'] = false
136
159
  end
137
160
 
138
161
  errors = JSON::Validator.fully_validate(
139
162
  schema_data,
140
163
  data,
141
- {:errors_as_objects => true}
164
+ { errors_as_objects: true }
142
165
  )
143
166
 
144
167
  unless errors.empty?
@@ -147,8 +170,8 @@ module Composer
147
170
  prefix = error[:fragment] ? "#{error[:fragment]} : " : ''
148
171
  processed_errors.push( prefix + error[:message])
149
172
  end
150
- raise Composer::Json::JsonValidationError.new(processed_errors),
151
- "\"#{@path}\" does not match the expected JSON schema"
173
+ raise ::Composer::Json::JsonValidationError.new(processed_errors),
174
+ %Q("#{@path}" does not match the expected JSON schema)
152
175
  end
153
176
 
154
177
  true
@@ -163,62 +186,51 @@ module Composer
163
186
  # @return string Encoded json
164
187
  def encode(data, options = 448)
165
188
 
166
- # if (version_compare(PHP_VERSION, '5.4', '>=')) {
167
- # $json = json_encode(data, options);
168
-
169
- # # compact brackets to follow recent php versions
170
- # if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512) || (defined('JSON_C_VERSION') && version_compare(phpversion('json'), '1.3.6', '<'))) {
171
- # $json = preg_replace('/\[\s+\]/', '[]', $json);
172
- # $json = preg_replace('/\{\s+\}/', '{}', $json);
173
- # }
174
-
175
- # return $json;
176
- # }
189
+ # WARNING: This function deviates from the original!
177
190
 
178
- # * *indent*: a string used to indent levels (default: ''),
179
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
180
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
181
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
182
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
183
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
184
- # generated, otherwise an exception is thrown if these values are
185
- # encountered. This options defaults to false.
186
- # * *max_nesting*: The maximum depth of nesting allowed in the data
187
- # structures from which JSON is to be generated. Disable depth checking
188
- # with :max_nesting => false, it defaults to 100.
191
+ json_last_error = nil
189
192
 
190
193
  if data.nil?
191
194
  return 'null'
192
- elsif data.is_a?(TrueClass)
195
+ elsif data.is_a? TrueClass
193
196
  return 'true'
194
- elsif data.is_a?(FalseClass)
197
+ elsif data.is_a? FalseClass
195
198
  return 'false'
196
- elsif data.is_a?(Integer)
199
+ elsif data.is_a? Integer
197
200
  return Integer(data)
198
- elsif data.is_a?(Float)
201
+ elsif data.is_a? Float
199
202
  return Float(data)
200
203
  else
201
204
  begin
202
- json = JSON.generate(data, { quirks_mode: false })
205
+ json = JSON.generate data, quirks_mode: false
203
206
  rescue JSON::GeneratorError => e
207
+ json_last_error = e
204
208
  if e.message === 'only generation of JSON objects or arrays allowed'
205
- #trick into parsing scalar values by wrapping them in an array
206
- scalar = data.gsub("\\\\", "\\\\\\")
207
- if json = JSON::generate([scalar], { quirks_mode: false })
208
- json = json[1..(json.length - 2)]
209
+ begin
210
+ #trick into parsing scalar values by wrapping them in an array
211
+ scalar = data.gsub("\\\\", "\\\\\\")
212
+ json = JSON::generate [scalar], quirks_mode: false
213
+ unless json.nil?
214
+ json = json[1..(json.length - 2)]
215
+ json_last_error = nil
216
+ end
217
+ rescue
218
+ # don't do anything (will report original error)
209
219
  end
210
220
  end
211
221
  end
212
222
  end
213
223
 
214
- return json unless options != 0
224
+ unless json_last_error.nil?
225
+ raise RuntimeError, json_last_error.message
226
+ end
215
227
 
216
- result = Composer::Json::JsonFormatter::format(
217
- json,
218
- options
219
- )
228
+ pretty_print = ( options & JSON_PRETTY_PRINT ).equal? JSON_PRETTY_PRINT
229
+ unescape_unicode = ( options & JSON_UNESCAPED_UNICODE ).equal? JSON_UNESCAPED_UNICODE
230
+ unescape_slashes = ( options & JSON_UNESCAPED_SLASHES ).equal? JSON_UNESCAPED_SLASHES
220
231
 
221
- result
232
+ return json unless pretty_print or unescape_unicode or unescape_slashes
233
+ ::Composer::Json::JsonFormatter::format(json, unescape_unicode, unescape_slashes)
222
234
  end
223
235
 
224
236
  # Parses json string and returns hash.
@@ -230,27 +242,31 @@ module Composer
230
242
  # Returns:
231
243
  # mixed
232
244
  def parse_json(json, file = nil)
233
- last_error = JSON_ERROR_NONE
234
245
 
246
+ # WARNING: This function deviates from the original!
247
+
248
+ return if json.nil?
249
+
250
+ @json_last_error = nil
235
251
  begin
236
- data = JSON.parse(json)
237
- rescue => e
238
- last_error = e
252
+ data = JSON.parse json
253
+ rescue JSON::ParserError => e
254
+ @json_last_error = e
239
255
  end
240
256
 
241
-
242
- if data.nil? && last_error != JSON_ERROR_NONE
243
- JsonFile::validate_syntax(json, file)
244
- raise JSON::ParserError,
245
- "\"#{file}\" does not contain valid JSON\n
246
- #{last_error.message}"
257
+ if data.nil? && !@json_last_error.nil?
258
+ validate_syntax(json, file)
259
+ else
260
+ data
247
261
  end
248
262
 
249
- data
250
263
  end
251
264
 
252
- def validate_syntax(json, file)
253
- # JSON::
265
+ def validate_syntax(_json, file = nil)
266
+
267
+ # WARNING: This function deviates from the original!
268
+
269
+ # TODO:
254
270
  # parser = Composer::Json::JsonParser.new
255
271
  # if (result = parser.lint(json))
256
272
  # raise ParsingError,
@@ -260,6 +276,17 @@ module Composer
260
276
  # if (defined('JSON_ERROR_UTF8') && JSON_ERROR_UTF8 === json_last_error()) {
261
277
  # throw new \UnexpectedValueException('"'.$file.'" is not UTF-8, could not parse as JSON');
262
278
  # }
279
+
280
+ unless @json_last_error.nil?
281
+ if file.nil?
282
+ error_msg = %Q("#{file}" does not contain valid JSON\n#{@json_last_error.message})
283
+ else
284
+ error_msg = %Q("JSON string does not contain valid JSON\n#{@json_last_error.message})
285
+ end
286
+
287
+ raise JSON::ParserError, error_msg
288
+ end
289
+
263
290
  true
264
291
  end
265
292
  end