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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/helpers/test/run.rb +3 -0
  4. data/lib/dependabot/file_fetchers.rb +0 -2
  5. data/lib/dependabot/file_parsers.rb +0 -2
  6. data/lib/dependabot/file_updaters.rb +0 -2
  7. data/lib/dependabot/file_updaters/go/dep/lockfile_updater.rb +11 -8
  8. data/lib/dependabot/metadata_finders.rb +0 -2
  9. data/lib/dependabot/shared_helpers.rb +47 -24
  10. data/lib/dependabot/update_checkers.rb +0 -2
  11. data/lib/dependabot/update_checkers/go/dep/version_resolver.rb +11 -7
  12. data/lib/dependabot/utils.rb +0 -4
  13. data/lib/dependabot/version.rb +1 -1
  14. metadata +2 -25
  15. data/helpers/php/.php_cs +0 -34
  16. data/helpers/php/bin/run.php +0 -84
  17. data/helpers/php/composer.json +0 -14
  18. data/helpers/php/composer.lock +0 -1528
  19. data/helpers/php/composer.phar +0 -0
  20. data/helpers/php/setup.sh +0 -4
  21. data/helpers/php/src/DependabotInstallationManager.php +0 -61
  22. data/helpers/php/src/DependabotPluginManager.php +0 -23
  23. data/helpers/php/src/ExceptionIO.php +0 -25
  24. data/helpers/php/src/Hasher.php +0 -21
  25. data/helpers/php/src/UpdateChecker.php +0 -123
  26. data/helpers/php/src/Updater.php +0 -97
  27. data/lib/dependabot/file_fetchers/php/composer.rb +0 -131
  28. data/lib/dependabot/file_parsers/php/composer.rb +0 -177
  29. data/lib/dependabot/file_updaters/php/composer.rb +0 -78
  30. data/lib/dependabot/file_updaters/php/composer/lockfile_updater.rb +0 -269
  31. data/lib/dependabot/file_updaters/php/composer/manifest_updater.rb +0 -70
  32. data/lib/dependabot/metadata_finders/php/composer.rb +0 -66
  33. data/lib/dependabot/update_checkers/php/composer.rb +0 -175
  34. data/lib/dependabot/update_checkers/php/composer/requirements_updater.rb +0 -258
  35. data/lib/dependabot/update_checkers/php/composer/version_resolver.rb +0 -216
  36. data/lib/dependabot/utils/php/requirement.rb +0 -97
  37. 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