dependabot-core 0.88.3 → 0.89.0
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/CHANGELOG.md +6 -0
- data/helpers/test/run.rb +3 -0
- data/lib/dependabot/file_fetchers.rb +0 -2
- data/lib/dependabot/file_parsers.rb +0 -2
- data/lib/dependabot/file_updaters.rb +0 -2
- data/lib/dependabot/file_updaters/go/dep/lockfile_updater.rb +11 -8
- data/lib/dependabot/metadata_finders.rb +0 -2
- data/lib/dependabot/shared_helpers.rb +47 -24
- data/lib/dependabot/update_checkers.rb +0 -2
- data/lib/dependabot/update_checkers/go/dep/version_resolver.rb +11 -7
- data/lib/dependabot/utils.rb +0 -4
- data/lib/dependabot/version.rb +1 -1
- metadata +2 -25
- data/helpers/php/.php_cs +0 -34
- data/helpers/php/bin/run.php +0 -84
- data/helpers/php/composer.json +0 -14
- data/helpers/php/composer.lock +0 -1528
- data/helpers/php/composer.phar +0 -0
- data/helpers/php/setup.sh +0 -4
- data/helpers/php/src/DependabotInstallationManager.php +0 -61
- data/helpers/php/src/DependabotPluginManager.php +0 -23
- data/helpers/php/src/ExceptionIO.php +0 -25
- data/helpers/php/src/Hasher.php +0 -21
- data/helpers/php/src/UpdateChecker.php +0 -123
- data/helpers/php/src/Updater.php +0 -97
- data/lib/dependabot/file_fetchers/php/composer.rb +0 -131
- data/lib/dependabot/file_parsers/php/composer.rb +0 -177
- data/lib/dependabot/file_updaters/php/composer.rb +0 -78
- data/lib/dependabot/file_updaters/php/composer/lockfile_updater.rb +0 -269
- data/lib/dependabot/file_updaters/php/composer/manifest_updater.rb +0 -70
- data/lib/dependabot/metadata_finders/php/composer.rb +0 -66
- data/lib/dependabot/update_checkers/php/composer.rb +0 -175
- data/lib/dependabot/update_checkers/php/composer/requirements_updater.rb +0 -258
- data/lib/dependabot/update_checkers/php/composer/version_resolver.rb +0 -216
- data/lib/dependabot/utils/php/requirement.rb +0 -97
- data/lib/dependabot/utils/php/version.rb +0 -24
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "dependabot/file_updaters/php/composer"
|
|
4
|
-
|
|
5
|
-
module Dependabot
|
|
6
|
-
module FileUpdaters
|
|
7
|
-
module Php
|
|
8
|
-
class Composer
|
|
9
|
-
class ManifestUpdater
|
|
10
|
-
def initialize(dependencies:, manifest:)
|
|
11
|
-
@dependencies = dependencies
|
|
12
|
-
@manifest = manifest
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def updated_manifest_content
|
|
16
|
-
dependencies.reduce(manifest.content.dup) do |content, dep|
|
|
17
|
-
updated_content = content
|
|
18
|
-
updated_requirements(dep).each do |new_req|
|
|
19
|
-
old_req = old_requirement(dep, new_req).fetch(:requirement)
|
|
20
|
-
updated_req = new_req.fetch(:requirement)
|
|
21
|
-
|
|
22
|
-
regex =
|
|
23
|
-
/
|
|
24
|
-
"#{Regexp.escape(dep.name)}"\s*:\s*
|
|
25
|
-
"#{Regexp.escape(old_req)}"
|
|
26
|
-
/x
|
|
27
|
-
|
|
28
|
-
updated_content = content.gsub(regex) do |declaration|
|
|
29
|
-
declaration.gsub(%("#{old_req}"), %("#{updated_req}"))
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
if content == updated_content
|
|
33
|
-
raise "Expected content to change!"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
updated_content
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
attr_reader :dependencies, :manifest
|
|
44
|
-
|
|
45
|
-
def new_requirements(dependency)
|
|
46
|
-
dependency.requirements.select { |r| r[:file] == manifest.name }
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def old_requirement(dependency, new_requirement)
|
|
50
|
-
dependency.previous_requirements.
|
|
51
|
-
select { |r| r[:file] == manifest.name }.
|
|
52
|
-
find { |r| r[:groups] == new_requirement[:groups] }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def updated_requirements(dependency)
|
|
56
|
-
new_requirements(dependency).
|
|
57
|
-
reject { |r| dependency.previous_requirements.include?(r) }
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def requirement_changed?(file, dependency)
|
|
61
|
-
changed_requirements =
|
|
62
|
-
dependency.requirements - dependency.previous_requirements
|
|
63
|
-
|
|
64
|
-
changed_requirements.any? { |f| f[:file] == file.name }
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "excon"
|
|
4
|
-
require "dependabot/metadata_finders/base"
|
|
5
|
-
require "dependabot/shared_helpers"
|
|
6
|
-
require "dependabot/utils"
|
|
7
|
-
|
|
8
|
-
module Dependabot
|
|
9
|
-
module MetadataFinders
|
|
10
|
-
module Php
|
|
11
|
-
class Composer < Dependabot::MetadataFinders::Base
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
def look_up_source
|
|
15
|
-
source_from_dependency || look_up_source_from_packagist
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def source_from_dependency
|
|
19
|
-
source_url =
|
|
20
|
-
dependency.requirements.
|
|
21
|
-
map { |r| r.fetch(:source) }.compact.
|
|
22
|
-
first&.fetch(:url, nil)
|
|
23
|
-
|
|
24
|
-
Source.from_url(source_url)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def look_up_source_from_packagist
|
|
28
|
-
return nil if packagist_listing&.fetch("packages", nil) == []
|
|
29
|
-
unless packagist_listing&.dig("packages", dependency.name.downcase)
|
|
30
|
-
return nil
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
version_listings =
|
|
34
|
-
packagist_listing["packages"][dependency.name.downcase].
|
|
35
|
-
select { |version, _| Utils::Php::Version.correct?(version) }.
|
|
36
|
-
sort_by { |version, _| Utils::Php::Version.new(version) }.
|
|
37
|
-
map { |_, listing| listing }.
|
|
38
|
-
reverse
|
|
39
|
-
|
|
40
|
-
potential_source_urls =
|
|
41
|
-
version_listings.
|
|
42
|
-
flat_map { |info| [info["homepage"], info.dig("source", "url")] }.
|
|
43
|
-
compact
|
|
44
|
-
|
|
45
|
-
source_url = potential_source_urls.find { |url| Source.from_url(url) }
|
|
46
|
-
|
|
47
|
-
Source.from_url(source_url)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def packagist_listing
|
|
51
|
-
return @packagist_listing unless @packagist_listing.nil?
|
|
52
|
-
|
|
53
|
-
response = Excon.get(
|
|
54
|
-
"https://packagist.org/p/#{dependency.name.downcase}.json",
|
|
55
|
-
idempotent: true,
|
|
56
|
-
**SharedHelpers.excon_defaults
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
return nil unless response.status == 200
|
|
60
|
-
|
|
61
|
-
@packagist_listing = JSON.parse(response.body)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "excon"
|
|
4
|
-
require "dependabot/update_checkers/base"
|
|
5
|
-
require "dependabot/shared_helpers"
|
|
6
|
-
require "dependabot/errors"
|
|
7
|
-
|
|
8
|
-
require "json"
|
|
9
|
-
|
|
10
|
-
module Dependabot
|
|
11
|
-
module UpdateCheckers
|
|
12
|
-
module Php
|
|
13
|
-
class Composer < Dependabot::UpdateCheckers::Base
|
|
14
|
-
require_relative "composer/requirements_updater"
|
|
15
|
-
require_relative "composer/version_resolver"
|
|
16
|
-
|
|
17
|
-
def latest_version
|
|
18
|
-
return nil if path_dependency?
|
|
19
|
-
|
|
20
|
-
# Fall back to latest_resolvable_version if no listings found
|
|
21
|
-
latest_version_from_registry || latest_resolvable_version
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def latest_resolvable_version
|
|
25
|
-
return nil if path_dependency?
|
|
26
|
-
|
|
27
|
-
@latest_resolvable_version ||=
|
|
28
|
-
VersionResolver.new(
|
|
29
|
-
credentials: credentials,
|
|
30
|
-
dependency: dependency,
|
|
31
|
-
dependency_files: dependency_files,
|
|
32
|
-
latest_allowable_version: latest_version_from_registry,
|
|
33
|
-
requirements_to_unlock: :own
|
|
34
|
-
).latest_resolvable_version
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def latest_resolvable_version_with_no_unlock
|
|
38
|
-
return nil if path_dependency?
|
|
39
|
-
|
|
40
|
-
@latest_resolvable_version_with_no_unlock ||=
|
|
41
|
-
VersionResolver.new(
|
|
42
|
-
credentials: credentials,
|
|
43
|
-
dependency: dependency,
|
|
44
|
-
dependency_files: dependency_files,
|
|
45
|
-
latest_allowable_version: latest_version_from_registry,
|
|
46
|
-
requirements_to_unlock: :none
|
|
47
|
-
).latest_resolvable_version
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def updated_requirements
|
|
51
|
-
RequirementsUpdater.new(
|
|
52
|
-
requirements: dependency.requirements,
|
|
53
|
-
latest_version: latest_version&.to_s,
|
|
54
|
-
latest_resolvable_version: latest_resolvable_version&.to_s,
|
|
55
|
-
update_strategy: requirements_update_strategy
|
|
56
|
-
).updated_requirements
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def requirements_update_strategy
|
|
60
|
-
# If passed in as an option (in the base class) honour that option
|
|
61
|
-
if @requirements_update_strategy
|
|
62
|
-
return @requirements_update_strategy.to_sym
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Otherwise, widen ranges for libraries and bump versions for apps
|
|
66
|
-
library? ? :widen_ranges : :bump_versions_if_necessary
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
def latest_version_resolvable_with_full_unlock?
|
|
72
|
-
# Full unlock checks aren't implemented for Composer (yet)
|
|
73
|
-
false
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def latest_version_from_registry
|
|
77
|
-
versions =
|
|
78
|
-
registry_versions.
|
|
79
|
-
select { |version| version_class.correct?(version.gsub(/^v/, "")) }.
|
|
80
|
-
map { |version| version_class.new(version.gsub(/^v/, "")) }
|
|
81
|
-
|
|
82
|
-
versions.reject!(&:prerelease?) unless wants_prerelease?
|
|
83
|
-
versions.reject! { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }
|
|
84
|
-
versions.max
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def wants_prerelease?
|
|
88
|
-
current_version = dependency.version
|
|
89
|
-
if current_version && version_class.new(current_version).prerelease?
|
|
90
|
-
return true
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
dependency.requirements.any? do |req|
|
|
94
|
-
req[:requirement].match?(/\d-[A-Za-z]/)
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def updated_dependencies_after_full_unlock
|
|
99
|
-
raise NotImplementedError
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def path_dependency?
|
|
103
|
-
dependency.requirements.any? { |r| r.dig(:source, :type) == "path" }
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def composer_file
|
|
107
|
-
composer_file =
|
|
108
|
-
dependency_files.find { |f| f.name == "composer.json" }
|
|
109
|
-
raise "No composer.json!" unless composer_file
|
|
110
|
-
|
|
111
|
-
composer_file
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def lockfile
|
|
115
|
-
dependency_files.find { |f| f.name == "composer.lock" }
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def registry_versions
|
|
119
|
-
return @registry_versions unless @registry_versions.nil?
|
|
120
|
-
|
|
121
|
-
repositories =
|
|
122
|
-
JSON.parse(composer_file.content).
|
|
123
|
-
fetch("repositories", []).
|
|
124
|
-
select { |r| r.is_a?(Hash) }
|
|
125
|
-
|
|
126
|
-
urls = repositories.
|
|
127
|
-
select { |h| h["type"] == "composer" }.
|
|
128
|
-
map { |h| h["url"] }.compact.
|
|
129
|
-
map { |url| url.gsub(%r{\/$}, "") + "/packages.json" }
|
|
130
|
-
|
|
131
|
-
unless repositories.any? { |rep| rep["packagist.org"] == false }
|
|
132
|
-
urls << "https://packagist.org/p/#{dependency.name.downcase}.json"
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
@registry_versions = []
|
|
136
|
-
urls.each do |url|
|
|
137
|
-
@registry_versions += fetch_registry_versions_from_url(url)
|
|
138
|
-
end
|
|
139
|
-
@registry_versions.uniq
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def fetch_registry_versions_from_url(url)
|
|
143
|
-
cred = registry_credentials.find { |c| url.include?(c["registry"]) }
|
|
144
|
-
|
|
145
|
-
response = Excon.get(
|
|
146
|
-
url,
|
|
147
|
-
idempotent: true,
|
|
148
|
-
user: cred&.fetch("username", nil),
|
|
149
|
-
password: cred&.fetch("password", nil),
|
|
150
|
-
**SharedHelpers.excon_defaults
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
return [] unless response.status == 200
|
|
154
|
-
|
|
155
|
-
listing = JSON.parse(response.body)
|
|
156
|
-
return [] if listing.nil?
|
|
157
|
-
return [] if listing.fetch("packages", []) == []
|
|
158
|
-
return [] unless listing.dig("packages", dependency.name.downcase)
|
|
159
|
-
|
|
160
|
-
listing.dig("packages", dependency.name.downcase).keys
|
|
161
|
-
rescue Excon::Error::Socket, Excon::Error::Timeout
|
|
162
|
-
[]
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def library?
|
|
166
|
-
JSON.parse(composer_file.content)["type"] == "library"
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def registry_credentials
|
|
170
|
-
credentials.select { |cred| cred["type"] == "composer_repository" }
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
################################################################################
|
|
4
|
-
# For more details on Composer version constraints, see: #
|
|
5
|
-
# https://getcomposer.org/doc/articles/versions.md#writing-version-constraints #
|
|
6
|
-
################################################################################
|
|
7
|
-
|
|
8
|
-
require "dependabot/update_checkers/php/composer"
|
|
9
|
-
require "dependabot/utils/php/version"
|
|
10
|
-
require "dependabot/utils/php/requirement"
|
|
11
|
-
|
|
12
|
-
module Dependabot
|
|
13
|
-
module UpdateCheckers
|
|
14
|
-
module Php
|
|
15
|
-
class Composer
|
|
16
|
-
class RequirementsUpdater
|
|
17
|
-
ALIAS_REGEX = /[a-z0-9\-_\.]*\sas\s+/.freeze
|
|
18
|
-
VERSION_REGEX =
|
|
19
|
-
/(?:#{ALIAS_REGEX})?[0-9]+(?:\.[a-zA-Z0-9*\-]+)*/.freeze
|
|
20
|
-
AND_SEPARATOR =
|
|
21
|
-
/(?<=[a-zA-Z0-9*])(?<!\sas)[\s,]+(?![\s,]*[|-]|as)/.freeze
|
|
22
|
-
OR_SEPARATOR = /(?<=[a-zA-Z0-9*])[\s,]*\|\|?\s*/.freeze
|
|
23
|
-
SEPARATOR = /(?:#{AND_SEPARATOR})|(?:#{OR_SEPARATOR})/.freeze
|
|
24
|
-
ALLOWED_UPDATE_STRATEGIES =
|
|
25
|
-
%i(widen_ranges bump_versions bump_versions_if_necessary).freeze
|
|
26
|
-
|
|
27
|
-
def initialize(requirements:, update_strategy:,
|
|
28
|
-
latest_version:, latest_resolvable_version:)
|
|
29
|
-
@requirements = requirements
|
|
30
|
-
@update_strategy = update_strategy
|
|
31
|
-
|
|
32
|
-
check_update_strategy
|
|
33
|
-
|
|
34
|
-
if latest_version
|
|
35
|
-
@latest_version = version_class.new(latest_version)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
return unless latest_resolvable_version
|
|
39
|
-
|
|
40
|
-
@latest_resolvable_version =
|
|
41
|
-
version_class.new(latest_resolvable_version)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def updated_requirements
|
|
45
|
-
return requirements unless latest_resolvable_version
|
|
46
|
-
|
|
47
|
-
requirements.map { |req| updated_requirement(req) }
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
|
|
52
|
-
attr_reader :requirements, :update_strategy,
|
|
53
|
-
:latest_version, :latest_resolvable_version
|
|
54
|
-
|
|
55
|
-
def check_update_strategy
|
|
56
|
-
return if ALLOWED_UPDATE_STRATEGIES.include?(update_strategy)
|
|
57
|
-
|
|
58
|
-
raise "Unknown update strategy: #{update_strategy}"
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
62
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
63
|
-
def updated_requirement(req)
|
|
64
|
-
req_string = req[:requirement].strip
|
|
65
|
-
or_string_reqs = req_string.split(OR_SEPARATOR)
|
|
66
|
-
or_separator = req_string.match(OR_SEPARATOR)&.to_s || " || "
|
|
67
|
-
numeric_or_string_reqs = or_string_reqs.
|
|
68
|
-
reject { |r| r.start_with?("dev-") }
|
|
69
|
-
branch_or_string_reqs = or_string_reqs.
|
|
70
|
-
select { |r| r.start_with?("dev-") }
|
|
71
|
-
|
|
72
|
-
return req unless req_string.match?(/\d/)
|
|
73
|
-
return req if numeric_or_string_reqs.none?
|
|
74
|
-
return updated_alias(req) if req_string.match?(ALIAS_REGEX)
|
|
75
|
-
return req if req_satisfied_by_latest_resolvable?(req_string) &&
|
|
76
|
-
update_strategy != :bump_versions
|
|
77
|
-
|
|
78
|
-
new_req =
|
|
79
|
-
case update_strategy
|
|
80
|
-
when :widen_ranges
|
|
81
|
-
widen_requirement(req, or_separator)
|
|
82
|
-
when :bump_versions, :bump_versions_if_necessary
|
|
83
|
-
update_requirement_version(req, or_separator)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
new_req_string =
|
|
87
|
-
[new_req[:requirement], *branch_or_string_reqs].join(or_separator)
|
|
88
|
-
new_req.merge(requirement: new_req_string)
|
|
89
|
-
end
|
|
90
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
91
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
92
|
-
|
|
93
|
-
def updated_alias(req)
|
|
94
|
-
req_string = req[:requirement]
|
|
95
|
-
real_version = req_string.split(/\sas\s/).first.strip
|
|
96
|
-
|
|
97
|
-
# If the version we're aliasing isn't a version then we don't know
|
|
98
|
-
# how to update it, so we just return the existing requirement.
|
|
99
|
-
return req unless version_class.correct?(real_version)
|
|
100
|
-
|
|
101
|
-
new_version_string = latest_resolvable_version.to_s
|
|
102
|
-
new_req = req_string.sub(real_version, new_version_string)
|
|
103
|
-
req.merge(requirement: new_req)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def widen_requirement(req, or_separator)
|
|
107
|
-
current_requirement = req[:requirement]
|
|
108
|
-
reqs = current_requirement.strip.split(SEPARATOR).map(&:strip)
|
|
109
|
-
|
|
110
|
-
updated_requirement =
|
|
111
|
-
if reqs.any? { |r| r.start_with?("^") }
|
|
112
|
-
update_caret_requirement(current_requirement, or_separator)
|
|
113
|
-
elsif reqs.any? { |r| r.start_with?("~") }
|
|
114
|
-
update_tilda_requirement(current_requirement, or_separator)
|
|
115
|
-
elsif reqs.any? { |r| r.include?("*") }
|
|
116
|
-
update_wildcard_requirement(current_requirement, or_separator)
|
|
117
|
-
elsif reqs.any? { |r| r.match?(/<|(\s+-\s+)/) }
|
|
118
|
-
update_range_requirement(current_requirement, or_separator)
|
|
119
|
-
else
|
|
120
|
-
update_version_string(current_requirement)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
req.merge(requirement: updated_requirement)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def update_requirement_version(req, or_separator)
|
|
127
|
-
current_requirement = req[:requirement]
|
|
128
|
-
reqs = current_requirement.strip.split(SEPARATOR).map(&:strip)
|
|
129
|
-
|
|
130
|
-
updated_requirement =
|
|
131
|
-
if reqs.count > 1
|
|
132
|
-
"^#{latest_resolvable_version}"
|
|
133
|
-
elsif reqs.any? { |r| r.match?(/<|(\s+-\s+)/) }
|
|
134
|
-
update_range_requirement(current_requirement, or_separator)
|
|
135
|
-
elsif reqs.any? { |r| r.match?(/>[^=]/) }
|
|
136
|
-
current_requirement
|
|
137
|
-
else
|
|
138
|
-
update_version_string(current_requirement)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
req.merge(requirement: updated_requirement)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def req_satisfied_by_latest_resolvable?(requirement_string)
|
|
145
|
-
ruby_requirements(requirement_string).
|
|
146
|
-
any? { |r| r.satisfied_by?(latest_resolvable_version) }
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def update_version_string(req_string)
|
|
150
|
-
req_string.
|
|
151
|
-
sub(VERSION_REGEX) do |old_version|
|
|
152
|
-
unless req_string.match?(/[~*\^]/)
|
|
153
|
-
next latest_resolvable_version.to_s
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
old_parts = old_version.split(".")
|
|
157
|
-
new_parts = latest_resolvable_version.to_s.split(".").
|
|
158
|
-
first(old_parts.count)
|
|
159
|
-
new_parts.map.with_index do |part, i|
|
|
160
|
-
old_parts[i] == "*" ? "*" : part
|
|
161
|
-
end.join(".")
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def ruby_requirements(requirement_string)
|
|
166
|
-
Utils::Php::Requirement.requirements_array(requirement_string)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def update_caret_requirement(req_string, or_separator)
|
|
170
|
-
caret_requirements =
|
|
171
|
-
req_string.split(SEPARATOR).select { |r| r.start_with?("^") }
|
|
172
|
-
version_parts = latest_resolvable_version.segments
|
|
173
|
-
|
|
174
|
-
min_existing_precision =
|
|
175
|
-
caret_requirements.map { |r| r.split(".").count }.min
|
|
176
|
-
first_non_zero_index =
|
|
177
|
-
version_parts.count.times.find { |i| version_parts[i] != 0 }
|
|
178
|
-
|
|
179
|
-
precision = [min_existing_precision, first_non_zero_index + 1].max
|
|
180
|
-
version = version_parts.first(precision).map.with_index do |part, i|
|
|
181
|
-
i <= first_non_zero_index ? part : 0
|
|
182
|
-
end.join(".")
|
|
183
|
-
|
|
184
|
-
req_string + "#{or_separator}^#{version}"
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def update_tilda_requirement(req_string, or_separator)
|
|
188
|
-
tilda_requirements =
|
|
189
|
-
req_string.split(SEPARATOR).select { |r| r.start_with?("~") }
|
|
190
|
-
precision = tilda_requirements.map { |r| r.split(".").count }.min
|
|
191
|
-
|
|
192
|
-
version_parts = latest_resolvable_version.segments.first(precision)
|
|
193
|
-
version_parts[-1] = 0
|
|
194
|
-
version = version_parts.join(".")
|
|
195
|
-
|
|
196
|
-
req_string + "#{or_separator}~#{version}"
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def update_wildcard_requirement(req_string, or_separator)
|
|
200
|
-
wildcard_requirements =
|
|
201
|
-
req_string.split(SEPARATOR).select { |r| r.include?("*") }
|
|
202
|
-
precision = wildcard_requirements.map do |r|
|
|
203
|
-
r.split(".").reject { |s| s == "*" }.count
|
|
204
|
-
end.min
|
|
205
|
-
wildcard_count = wildcard_requirements.map do |r|
|
|
206
|
-
r.split(".").select { |s| s == "*" }.count
|
|
207
|
-
end.min
|
|
208
|
-
|
|
209
|
-
version_parts = latest_resolvable_version.segments.first(precision)
|
|
210
|
-
version = version_parts.join(".")
|
|
211
|
-
|
|
212
|
-
req_string + "#{or_separator}#{version}#{'.*' * wildcard_count}"
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def update_range_requirement(req_string, or_separator)
|
|
216
|
-
range_requirements =
|
|
217
|
-
req_string.split(SEPARATOR).select { |r| r.match?(/<|(\s+-\s+)/) }
|
|
218
|
-
|
|
219
|
-
if range_requirements.count == 1
|
|
220
|
-
range_requirement = range_requirements.first
|
|
221
|
-
versions = range_requirement.scan(VERSION_REGEX)
|
|
222
|
-
upper_bound = versions.map { |v| version_class.new(v) }.max
|
|
223
|
-
new_upper_bound = update_greatest_version(
|
|
224
|
-
upper_bound,
|
|
225
|
-
latest_resolvable_version
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
req_string.sub(upper_bound.to_s, new_upper_bound.to_s)
|
|
229
|
-
else
|
|
230
|
-
req_string + "#{or_separator}^#{latest_resolvable_version}"
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def update_greatest_version(old_version, version_to_be_permitted)
|
|
235
|
-
version = version_class.new(old_version)
|
|
236
|
-
version = version.release if version.prerelease?
|
|
237
|
-
|
|
238
|
-
index_to_update =
|
|
239
|
-
version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max
|
|
240
|
-
|
|
241
|
-
version.segments.map.with_index do |_, index|
|
|
242
|
-
if index < index_to_update
|
|
243
|
-
version_to_be_permitted.segments[index]
|
|
244
|
-
elsif index == index_to_update
|
|
245
|
-
version_to_be_permitted.segments[index] + 1
|
|
246
|
-
else 0
|
|
247
|
-
end
|
|
248
|
-
end.join(".")
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
def version_class
|
|
252
|
-
Utils::Php::Version
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
end
|