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
data/.ruby-version
ADDED
@@ -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
data/lib/composer.rb
CHANGED
@@ -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
|
-
|
29
|
-
|
30
|
-
|
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
|
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
|
-
#
|
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
|
-
#
|
67
|
+
# RuntimeError on error.
|
63
68
|
#
|
64
69
|
# Returns:
|
65
|
-
#
|
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
|
-
|
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
|
-
|
76
|
-
|
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
|
-
|
113
|
+
|
114
|
+
file_ending = ((options & JSON_PRETTY_PRINT).equal? JSON_PRETTY_PRINT) ? "\n" : ''
|
94
115
|
File.open(@path, 'w') do |f|
|
95
|
-
content =
|
116
|
+
content = self.class.encode(hash, options) + file_ending
|
96
117
|
f.write(content)
|
97
118
|
end
|
98
119
|
break
|
99
120
|
|
100
|
-
rescue
|
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
|
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['
|
135
|
-
schema_data['properties']['
|
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
|
-
{:
|
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
|
-
"
|
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
|
-
#
|
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
|
-
|
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?
|
195
|
+
elsif data.is_a? TrueClass
|
193
196
|
return 'true'
|
194
|
-
elsif data.is_a?
|
197
|
+
elsif data.is_a? FalseClass
|
195
198
|
return 'false'
|
196
|
-
elsif data.is_a?
|
199
|
+
elsif data.is_a? Integer
|
197
200
|
return Integer(data)
|
198
|
-
elsif data.is_a?
|
201
|
+
elsif data.is_a? Float
|
199
202
|
return Float(data)
|
200
203
|
else
|
201
204
|
begin
|
202
|
-
json = JSON.generate
|
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
|
-
|
206
|
-
|
207
|
-
|
208
|
-
json =
|
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
|
-
|
224
|
+
unless json_last_error.nil?
|
225
|
+
raise RuntimeError, json_last_error.message
|
226
|
+
end
|
215
227
|
|
216
|
-
|
217
|
-
|
218
|
-
|
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
|
-
|
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
|
237
|
-
rescue => e
|
238
|
-
|
252
|
+
data = JSON.parse json
|
253
|
+
rescue JSON::ParserError => e
|
254
|
+
@json_last_error = e
|
239
255
|
end
|
240
256
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
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(
|
253
|
-
|
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
|