php-composer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +1006 -0
  5. data/Gemfile +15 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +35 -0
  8. data/Rakefile +1 -0
  9. data/lib/composer.rb +52 -0
  10. data/lib/composer/error.rb +8 -0
  11. data/lib/composer/json/json_file.rb +270 -0
  12. data/lib/composer/json/json_formatter.rb +159 -0
  13. data/lib/composer/json/json_validaton_error.rb +29 -0
  14. data/lib/composer/manager.rb +79 -0
  15. data/lib/composer/package/alias_package.rb +273 -0
  16. data/lib/composer/package/base_package.rb +130 -0
  17. data/lib/composer/package/complete_package.rb +55 -0
  18. data/lib/composer/package/dumper/hash_dumper.rb +169 -0
  19. data/lib/composer/package/link.rb +51 -0
  20. data/lib/composer/package/link_constraint/base_constraint.rb +36 -0
  21. data/lib/composer/package/link_constraint/empty_constraint.rb +35 -0
  22. data/lib/composer/package/link_constraint/multi_constraint.rb +67 -0
  23. data/lib/composer/package/link_constraint/specific_constraint.rb +41 -0
  24. data/lib/composer/package/link_constraint/version_constraint.rb +221 -0
  25. data/lib/composer/package/loader/hash_loader.rb +316 -0
  26. data/lib/composer/package/loader/json_loader.rb +47 -0
  27. data/lib/composer/package/loader/project_attributes_loader.rb +71 -0
  28. data/lib/composer/package/loader/project_root_package_loader.rb +28 -0
  29. data/lib/composer/package/package.rb +118 -0
  30. data/lib/composer/package/root_alias_package.rb +37 -0
  31. data/lib/composer/package/root_package.rb +37 -0
  32. data/lib/composer/package/version/version_parser.rb +583 -0
  33. data/lib/composer/package/version/version_selector.rb +106 -0
  34. data/lib/composer/provider.rb +94 -0
  35. data/lib/composer/repository/array_repository.rb +195 -0
  36. data/lib/composer/repository/filesystem_repository.rb +86 -0
  37. data/lib/composer/repository/writeable_array_repository.rb +60 -0
  38. data/lib/composer/version.rb +3 -0
  39. data/php-composer.gemspec +31 -0
  40. data/resources/composer-schema.json +421 -0
  41. metadata +188 -0
@@ -0,0 +1,106 @@
1
+ #
2
+ # This file was ported to ruby from Composer php source code file.
3
+ # Original Source: Composer\Package\Version\VersionParser.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 Version
15
+ # Selects the best possible version for a package
16
+ #
17
+ # PHP Authors:
18
+ # Ryan Weaver <ryan@knpuniversity.com>
19
+ #
20
+ # Ruby Authors:
21
+ # Ioannis Kappas <ikappas@devworks.gr>
22
+ class VersionSelector
23
+
24
+ def initialize(pool)
25
+ @pool = pool
26
+ end
27
+
28
+
29
+ # Given a concrete version, this returns a ~ constraint (when possible)
30
+ # that should be used, for example, in composer.json.
31
+ #
32
+ # For example:
33
+ # * 1.2.1 -> ~1.2
34
+ # * 1.2 -> ~1.2
35
+ # * v3.2.1 -> ~3.2
36
+ # * 2.0-beta.1 -> ~2.0@beta
37
+ # * dev-master -> ~2.1@dev (dev version with alias)
38
+ # * dev-master -> dev-master (dev versions are untouched)
39
+ #
40
+ # @param Package package
41
+ # @return string
42
+ def find_recommended_require_version(package)
43
+ version = package.version
44
+ if !package.is_dev
45
+ return transform_version(version, package.pretty_version, package.stability)
46
+ end
47
+
48
+ loader = Composer::Package::Loader::HashLoader.new(parser)
49
+ dumper = Composer::Package::Dumper::HashDumper.new
50
+
51
+ if (extra = loader.get_branch_alias(dumper.dump(package)))
52
+ if match = /^(\d+\.\d+\.\d+)(\.9999999)-dev$/.match(extra)
53
+ extra = "#{match[1]}.0"
54
+ extra.gsub!('.9999999', '.0')
55
+ return transform_version(extra, extra, 'dev')
56
+ end
57
+ end
58
+
59
+ package.pretty_version
60
+ end
61
+
62
+ private
63
+
64
+ def transform_version(version, pretty_version, stability)
65
+ # attempt to transform 2.1.1 to 2.1
66
+ # this allows you to upgrade through minor versions
67
+ semantic_version_parts = version.split('.')
68
+ op = '~'
69
+
70
+ # check to see if we have a semver-looking version
71
+ if semantic_version_parts.length == 4 && /^0\D?/.match(semantic_version_parts[3])
72
+ # remove the last parts (i.e. the patch version number and any extra)
73
+ if semantic_version_parts[0] === '0'
74
+ if semantic_version_parts[1] === '0'
75
+ semantic_version_parts[3] = '*'
76
+ else
77
+ semantic_version_parts[2] = '*'
78
+ semantic_version_parts.delete_at(3)
79
+ end
80
+ op = ''
81
+ else
82
+ semantic_version_parts.delete_at(3)
83
+ semantic_version_parts.delete_at(2)
84
+ end
85
+ version = semantic_version_parts.join('.')
86
+ else
87
+ return pretty_version
88
+ end
89
+
90
+ # append stability flag if not default
91
+ if stability != 'stable'
92
+ version << "@#{stability}"
93
+ end
94
+
95
+ # 2.1 -> ~2.1
96
+ op + version
97
+ end
98
+
99
+ def parser
100
+ @parser ||= Composer::Package::Version::VersionParser.new
101
+ @parser
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,94 @@
1
+ module Composer
2
+ class Provider
3
+
4
+ BLANK_PROVIDER = { "packages"=>{} }
5
+
6
+ def initialize(project)
7
+ @project = project
8
+ @package_dumper = Composer::Package::Dumper::HashDumper.new
9
+ end
10
+
11
+ def add_package(package)
12
+
13
+ raise ArgumentError, 'package must be specified' unless package
14
+ # raise TypeError, 'package must be a subclass of Composer::Package::Package' unless package.kind_of?(Composer::Package::Package)
15
+
16
+ name = package.name
17
+ pretty_version = package.pretty_version
18
+
19
+ packages[name] ||= {}
20
+ packages[name][pretty_version] = @package_dumper.dump(package)
21
+
22
+ if packages[name].length >= 2
23
+ packages[name].keys.sort.each { |k| packages[name][k] = packages[name].delete k }
24
+ end
25
+
26
+ end
27
+
28
+ def rm_package(package)
29
+
30
+ raise ArgumentError, 'package must be specified' unless package
31
+ # raise TypeError, 'package must be a subclass of Composer::Package::Package' unless package.kind_of?(Composer::Package::Package)
32
+
33
+ name = package.name
34
+ pretty_version = package.pretty_version
35
+
36
+ if has_package?(name, pretty_version)
37
+ packages[name].delete(pretty_version)
38
+ if packages[name].empty?
39
+ packages.delete(name)
40
+ elsif packages[name].length >= 2
41
+ packages[name].keys.sort.each { |k| packages[name][k] = packages[name].delete k }
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ def clear_packages
48
+ @packages = {}
49
+ end
50
+
51
+ def has_package?(name, pretty_version=nil)
52
+ if pretty_version
53
+ packages.key?(name) ? packages[name].key?(pretty_version) : false
54
+ else
55
+ packages.key?(name)
56
+ end
57
+ end
58
+
59
+ def has_packages?
60
+ !packages.empty?
61
+ end
62
+
63
+ def save_or_delete
64
+ if has_packages?
65
+ File.open(filepath, "w") { |f| f.write(content) }
66
+ else
67
+ File.delete(filepath) unless not File.exist?(filepath)
68
+ end
69
+ end
70
+
71
+ def filename
72
+ "project-#{@project.id}.json"
73
+ end
74
+
75
+ def sha1
76
+ Digest::SHA1.hexdigest content
77
+ end
78
+
79
+ private
80
+
81
+ def packages
82
+ @packages ||= File.exist?(filepath) ? File.open(filepath, "r") { |f| ActiveSupport::JSON.decode(f.read)["packages"] rescue {} } : {}
83
+ end
84
+
85
+ def content
86
+ { 'packages' => packages }.to_json
87
+ end
88
+
89
+ def filepath
90
+ File.join(File.realpath(Rails.root.join('public', 'p')), filename)
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,195 @@
1
+ #
2
+ # This file was ported to ruby from Composer php source code.
3
+ # Original Source: Composer\Repository\ArrayRepository.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 Repository
14
+ class ArrayRepository
15
+ def initialize(packages = [])
16
+ packages.each do |package|
17
+ add_package(package)
18
+ end
19
+ end
20
+
21
+ def find_package(name, version = nil)
22
+ # normalize name
23
+ name = name.downcase
24
+
25
+ # normalize version
26
+ if version != nil
27
+ version_parser = Composer::Package::Verision::VersionParser.new
28
+ version = version_parser.normalize(version)
29
+ end
30
+
31
+ packages.each do |package|
32
+ if package.name === name && (nil === $version || version === package.version)
33
+ return package
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ def find_packages(name, version = nil)
40
+ # normalize name
41
+ name = name.downcase
42
+
43
+ # normalize version
44
+ if version != nil
45
+ version_parser = Composer::Package::Verision::VersionParser.new
46
+ version = version_parser.normalize(version)
47
+ end
48
+
49
+ matches = []
50
+ packages.each do |package|
51
+ if package.name === name && (nil === $version || version === package.version)
52
+ matches << package
53
+ end
54
+ end
55
+ matches
56
+ end
57
+
58
+ def search(query, full_search = false)
59
+ regex = /(?:#{query.split(/\s+/).join('|')})/i
60
+ matches = {}
61
+ packages.each do |package|
62
+ name = package.name
63
+
64
+ # allready matched
65
+ next if matches['name']
66
+
67
+ # search
68
+ if full_search
69
+ next unless (
70
+ package.instance_of(Composer::Package::CompletePackage) &&
71
+ regex.match("#{package.keywords.join(' ')} #{package.description}")
72
+ )
73
+ else
74
+ next unless (
75
+ full_search == false &&
76
+ regex.match(name)
77
+ )
78
+ end
79
+
80
+ matches[name] = {
81
+ 'name' => package.pretty_name,
82
+ 'description' => $package.description,
83
+ }
84
+ end
85
+ matches
86
+ end
87
+
88
+ def package?(package)
89
+ unless package
90
+ raise ArgumentError,
91
+ 'package must be specified'
92
+ end
93
+ unless package.is_a(Composer::Package::BasePackage)
94
+ raise TypeError,
95
+ 'package must be a class or superclass of \
96
+ Composer::Package::Package'
97
+ end
98
+
99
+ package_id = package.unique_name
100
+ packages.each do |repo_package|
101
+ return true if repo_package.unique_name === package_id
102
+ end
103
+
104
+ false
105
+ end
106
+
107
+ # Adds a new package to the repository
108
+ #
109
+ # Params:
110
+ # +package+ Package The package to add
111
+ def add_package(package)
112
+ unless package
113
+ raise ArgumentError,
114
+ 'package must be specified'
115
+ end
116
+ unless package.is_a(Composer::Package::BasePackage)
117
+ raise TypeError,
118
+ 'package must be a class or superclass of \
119
+ Composer::Package::Package'
120
+ end
121
+
122
+ initialize_repository unless @packages
123
+
124
+ package.repository = self
125
+
126
+ @packages << package
127
+
128
+ if package.instance_of(Composer::Package::AliasPackage)
129
+ aliased_package = package.alias_of
130
+ if aliased_package.repository === nil
131
+ add_package(aliased_package)
132
+ end
133
+ end
134
+ end
135
+
136
+ # Removes package from repository.
137
+ #
138
+ # Params:
139
+ # +package+ package instance to remove
140
+ def remove_package(package)
141
+ unless package
142
+ raise ArgumentError,
143
+ 'package must be specified'
144
+ end
145
+ unless package.is_a(Composer::Package::BasePackage)
146
+ raise TypeError,
147
+ 'package must be a class or superclass of \
148
+ Composer::Package::Package'
149
+ end
150
+
151
+ package_id = package.unique_name
152
+
153
+ index = 0
154
+ packages.each do |repo_package|
155
+ if repo_package.unique_name === package_id
156
+ @packages.delete_at(index)
157
+ return
158
+ end
159
+ index = index + 1
160
+ end
161
+ end
162
+
163
+ def packages
164
+ initialize_repository unless @packages
165
+ @packages
166
+ end
167
+
168
+ def count
169
+ @packages.lenght
170
+ end
171
+
172
+ protected
173
+
174
+ # Initializes the packages array.
175
+ # Mostly meant as an extension point.
176
+ def initialize_repository
177
+ @packages = []
178
+ end
179
+
180
+ def create_alias_package(package, version, pretty_version)
181
+ if package.instance_of(Composer::Package::AliasPackage)
182
+ alias_of = package.alias_of
183
+ else
184
+ alias_of = package
185
+ end
186
+ Composer::Package::AliasPackage.new(
187
+ alias_of,
188
+ version,
189
+ pretty_version
190
+ )
191
+ end
192
+
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,86 @@
1
+ #
2
+ # This file was ported to ruby from Composer php source code.
3
+ # Original Source: Composer\Repository\FilesystemRepository.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 Repository
14
+ # Filesystem repository.
15
+ #
16
+ # PHP Authors:
17
+ # Konstantin Kudryashov <ever.zet@gmail.com>
18
+ # Jordi Boggiano <j.boggiano@seld.be>
19
+ #
20
+ # Ruby Authors:
21
+ # Ioannis Kappas <ikappas@devworks.gr>
22
+ class FilesystemRepository < Composer::Repository::WritableArrayRepository
23
+
24
+ # Initializes filesystem repository.
25
+ # @param [Composer::Json::JsonFile] repository_file repository json file
26
+ def initialize(repository_file)
27
+ unless repository_file
28
+ raise ArgumentError,
29
+ 'repository_file must be specified'
30
+ end
31
+ unless repository_file.is_a(Composer::Json::JsonFile)
32
+ raise TypeError,
33
+ 'repository_file type must be a \
34
+ Composer::Json::JsonFile or superclass'
35
+ end
36
+ super([])
37
+ @file = repository_file
38
+ end
39
+
40
+
41
+ def reload
42
+ @packages = nil
43
+ configure
44
+ end
45
+
46
+ # Writes writable repository.
47
+ def write
48
+ data = []
49
+ dumper = Composer::Package::Dumper::HashDumper.new
50
+
51
+ canonical_packages.each { |package| data << dumper.dump(package) }
52
+
53
+ @file.write(data)
54
+ end
55
+
56
+ protected
57
+
58
+ # Initializes repository (reads file, or remote address).
59
+ def initialize_repository
60
+ super
61
+ return unless @file.exists
62
+
63
+ begin
64
+ packages_data = @file.read
65
+ unless packages_data.is_a(Hash)
66
+ raise UnexpectedValueError,
67
+ 'Could not parse package list from the repository'
68
+ end
69
+ rescue Exception => e
70
+ raise InvalidRepositoryError,
71
+ "Invalid repository data in #{@file.path}, \
72
+ packages could not be loaded: \
73
+ [#{e.class}] #{e.message}"
74
+ end
75
+
76
+ loader = Composer::Package::Loader::ArrayLoader.new(nil, true)
77
+ packages_data.each do |package_data|
78
+ package = loader.load(package_data)
79
+ add_package(package)
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+ end