dependabot-composer 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 +7 -0
- data/helpers/.php_cs +32 -0
- data/helpers/bin/run.php +84 -0
- data/helpers/build +14 -0
- data/helpers/composer.json +14 -0
- data/helpers/composer.lock +1528 -0
- data/helpers/php/.php_cs +34 -0
- data/helpers/setup.sh +4 -0
- data/helpers/src/DependabotInstallationManager.php +61 -0
- data/helpers/src/DependabotPluginManager.php +23 -0
- data/helpers/src/ExceptionIO.php +25 -0
- data/helpers/src/Hasher.php +21 -0
- data/helpers/src/UpdateChecker.php +123 -0
- data/helpers/src/Updater.php +97 -0
- data/lib/dependabot/composer.rb +11 -0
- data/lib/dependabot/composer/file_fetcher.rb +132 -0
- data/lib/dependabot/composer/file_parser.rb +179 -0
- data/lib/dependabot/composer/file_updater.rb +78 -0
- data/lib/dependabot/composer/file_updater/lockfile_updater.rb +267 -0
- data/lib/dependabot/composer/file_updater/manifest_updater.rb +66 -0
- data/lib/dependabot/composer/metadata_finder.rb +68 -0
- data/lib/dependabot/composer/native_helpers.rb +20 -0
- data/lib/dependabot/composer/requirement.rb +98 -0
- data/lib/dependabot/composer/update_checker.rb +176 -0
- data/lib/dependabot/composer/update_checker/requirements_updater.rb +253 -0
- data/lib/dependabot/composer/update_checker/version_resolver.rb +214 -0
- data/lib/dependabot/composer/version.rb +26 -0
- metadata +195 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dependabot/shared_helpers"
|
4
|
+
require "dependabot/composer/update_checker"
|
5
|
+
require "dependabot/composer/version"
|
6
|
+
require "dependabot/composer/native_helpers"
|
7
|
+
|
8
|
+
module Dependabot
|
9
|
+
module Composer
|
10
|
+
class UpdateChecker
|
11
|
+
class VersionResolver
|
12
|
+
VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
|
13
|
+
SOURCE_TIMED_OUT_REGEX =
|
14
|
+
/The "(?<url>[^"]+packages\.json)".*timed out/.freeze
|
15
|
+
|
16
|
+
def initialize(credentials:, dependency:, dependency_files:,
|
17
|
+
requirements_to_unlock:, latest_allowable_version:)
|
18
|
+
@credentials = credentials
|
19
|
+
@dependency = dependency
|
20
|
+
@dependency_files = dependency_files
|
21
|
+
@requirements_to_unlock = requirements_to_unlock
|
22
|
+
@latest_allowable_version = latest_allowable_version
|
23
|
+
end
|
24
|
+
|
25
|
+
def latest_resolvable_version
|
26
|
+
@latest_resolvable_version ||= fetch_latest_resolvable_version
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :credentials, :dependency, :dependency_files,
|
32
|
+
:requirements_to_unlock, :latest_allowable_version
|
33
|
+
|
34
|
+
def fetch_latest_resolvable_version
|
35
|
+
version = fetch_latest_resolvable_version_string
|
36
|
+
return if version.nil?
|
37
|
+
return unless Composer::Version.correct?(version)
|
38
|
+
|
39
|
+
Composer::Version.new(version)
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch_latest_resolvable_version_string
|
43
|
+
base_directory = dependency_files.first.directory
|
44
|
+
SharedHelpers.in_a_temporary_directory(base_directory) do
|
45
|
+
File.write("composer.json", prepared_composer_json_content)
|
46
|
+
File.write("composer.lock", lockfile.content) if lockfile
|
47
|
+
|
48
|
+
run_update_checker
|
49
|
+
end
|
50
|
+
rescue SharedHelpers::HelperSubprocessFailed => error
|
51
|
+
retry_count ||= 0
|
52
|
+
retry_count += 1
|
53
|
+
retry if retry_count < 2 && error.message.include?("404 Not Found")
|
54
|
+
retry if retry_count < 2 && error.message.include?("timed out")
|
55
|
+
handle_composer_errors(error)
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_update_checker
|
59
|
+
SharedHelpers.with_git_configured(credentials: credentials) do
|
60
|
+
SharedHelpers.run_helper_subprocess(
|
61
|
+
command: "php -d memory_limit=-1 #{php_helper_path}",
|
62
|
+
function: "get_latest_resolvable_version",
|
63
|
+
args: [
|
64
|
+
Dir.pwd,
|
65
|
+
dependency.name.downcase,
|
66
|
+
git_credentials,
|
67
|
+
registry_credentials
|
68
|
+
]
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def prepared_composer_json_content
|
74
|
+
content = composer_file.content
|
75
|
+
|
76
|
+
content.gsub(
|
77
|
+
/"#{Regexp.escape(dependency.name)}"\s*:\s*".*"/,
|
78
|
+
%("#{dependency.name}": "#{updated_version_requirement_string}")
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def updated_version_requirement_string
|
83
|
+
lower_bound =
|
84
|
+
if requirements_to_unlock == :none
|
85
|
+
dependency.requirements.first&.fetch(:requirement) || ">= 0"
|
86
|
+
elsif dependency.version
|
87
|
+
">= #{dependency.version}"
|
88
|
+
else
|
89
|
+
version_for_requirement =
|
90
|
+
dependency.requirements.map { |r| r[:requirement] }.compact.
|
91
|
+
reject { |req_string| req_string.start_with?("<") }.
|
92
|
+
select { |req_string| req_string.match?(VERSION_REGEX) }.
|
93
|
+
map { |req_string| req_string.match(VERSION_REGEX) }.
|
94
|
+
select { |version| Gem::Version.correct?(version) }.
|
95
|
+
max_by { |version| Gem::Version.new(version) }
|
96
|
+
|
97
|
+
">= #{version_for_requirement || 0}"
|
98
|
+
end
|
99
|
+
|
100
|
+
# Add the latest_allowable_version as an upper bound. This means
|
101
|
+
# ignore conditions are considered when checking for the latest
|
102
|
+
# resolvable version.
|
103
|
+
#
|
104
|
+
# NOTE: This isn't perfect. If v2.x is ignored and v3 is out but
|
105
|
+
# unresolvable then the `latest_allowable_version` will be v3, and
|
106
|
+
# we won't be ignoring v2.x releases like we should be.
|
107
|
+
return lower_bound unless latest_allowable_version
|
108
|
+
|
109
|
+
lower_bound + ", <= #{latest_allowable_version}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
113
|
+
# rubocop:disable Metrics/AbcSize
|
114
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
115
|
+
# rubocop:disable Metrics/MethodLength
|
116
|
+
def handle_composer_errors(error)
|
117
|
+
if error.message.start_with?("Failed to execute git clone")
|
118
|
+
dependency_url =
|
119
|
+
error.message.match(/--mirror '(?<url>.*?)'/).
|
120
|
+
named_captures.fetch("url")
|
121
|
+
raise Dependabot::GitDependenciesNotReachable, dependency_url
|
122
|
+
elsif error.message.start_with?("Failed to clone")
|
123
|
+
dependency_url =
|
124
|
+
error.message.match(/Failed to clone (?<url>.*?) via/).
|
125
|
+
named_captures.fetch("url")
|
126
|
+
raise Dependabot::GitDependenciesNotReachable, dependency_url
|
127
|
+
elsif error.message.start_with?("Could not parse version")
|
128
|
+
raise Dependabot::DependencyFileNotResolvable, error.message
|
129
|
+
elsif error.message.include?("requested PHP extension")
|
130
|
+
extensions = error.message.scan(/\sext\-.*?\s/).map(&:strip).uniq
|
131
|
+
msg = "Dependabot's installed extensions didn't match those "\
|
132
|
+
"required by your application.\n\n"\
|
133
|
+
"Please add the following extensions to the platform "\
|
134
|
+
"config in your composer.json to allow Dependabot to run: "\
|
135
|
+
"#{extensions.join(', ')}.\n\n"\
|
136
|
+
"The full error raised was:\n\n#{error.message}"
|
137
|
+
raise Dependabot::DependencyFileNotResolvable, msg
|
138
|
+
elsif error.message.include?("package requires php") ||
|
139
|
+
error.message.include?("cannot require itself")
|
140
|
+
raise Dependabot::DependencyFileNotResolvable, error.message
|
141
|
+
elsif error.message.include?("No driver found to handle VCS") &&
|
142
|
+
!error.message.include?("@") && !error.message.include?("://")
|
143
|
+
msg = "Dependabot detected a VCS requirement with a local path, "\
|
144
|
+
"rather than a URL. Dependabot does not support this "\
|
145
|
+
"setup.\n\nThe underlying error was:\n\n#{error.message}"
|
146
|
+
raise Dependabot::DependencyFileNotResolvable, msg
|
147
|
+
elsif error.message.include?("requirements could not be resolved")
|
148
|
+
# We should raise a Dependabot::DependencyFileNotResolvable error
|
149
|
+
# here, but can't confidently distinguish between cases where we
|
150
|
+
# can't install and cases where we can't update. For now, we
|
151
|
+
# therefore just ignore the dependency.
|
152
|
+
nil
|
153
|
+
elsif error.message.include?("URL required authentication") ||
|
154
|
+
error.message.include?("403 Forbidden")
|
155
|
+
source =
|
156
|
+
error.message.match(%r{https?://(?<source>[^/]+)/}).
|
157
|
+
named_captures.fetch("source")
|
158
|
+
raise Dependabot::PrivateSourceAuthenticationFailure, source
|
159
|
+
elsif error.message.match?(SOURCE_TIMED_OUT_REGEX)
|
160
|
+
url = error.message.match(SOURCE_TIMED_OUT_REGEX).
|
161
|
+
named_captures.fetch("url")
|
162
|
+
raise if url.include?("packagist.org")
|
163
|
+
|
164
|
+
source = url.gsub(%r{/packages.json$}, "")
|
165
|
+
raise Dependabot::PrivateSourceTimedOut, source
|
166
|
+
elsif error.message.start_with?("Allowed memory size")
|
167
|
+
raise Dependabot::OutOfMemory
|
168
|
+
elsif error.message.start_with?("Package not found in updated") &&
|
169
|
+
!dependency.top_level?
|
170
|
+
# If we can't find the dependency in the composer.lock after an
|
171
|
+
# update, but it was originally a sub-dependency, it's because the
|
172
|
+
# dependency is no longer required and is just cruft in the
|
173
|
+
# composer.json. In this case we just ignore the dependency.
|
174
|
+
nil
|
175
|
+
elsif error.message.include?("stefandoorn/sitemap-plugin-1.0.0.0")
|
176
|
+
# We get a recurring error when attempting to update this repo
|
177
|
+
# which doesn't recur locally and we can't figure out how to fix!
|
178
|
+
#
|
179
|
+
# Package is not installed: stefandoorn/sitemap-plugin-1.0.0.0
|
180
|
+
nil
|
181
|
+
else
|
182
|
+
raise error
|
183
|
+
end
|
184
|
+
end
|
185
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
186
|
+
# rubocop:enable Metrics/AbcSize
|
187
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
188
|
+
# rubocop:enable Metrics/MethodLength
|
189
|
+
|
190
|
+
def php_helper_path
|
191
|
+
NativeHelpers.composer_helper_path
|
192
|
+
end
|
193
|
+
|
194
|
+
def composer_file
|
195
|
+
@composer_file ||=
|
196
|
+
dependency_files.find { |f| f.name == "composer.json" }
|
197
|
+
end
|
198
|
+
|
199
|
+
def lockfile
|
200
|
+
@lockfile ||=
|
201
|
+
dependency_files.find { |f| f.name == "composer.lock" }
|
202
|
+
end
|
203
|
+
|
204
|
+
def git_credentials
|
205
|
+
credentials.select { |cred| cred["type"] == "git_source" }
|
206
|
+
end
|
207
|
+
|
208
|
+
def registry_credentials
|
209
|
+
credentials.select { |cred| cred["type"] == "composer_repository" }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dependabot/utils"
|
4
|
+
require "rubygems_version_patch"
|
5
|
+
|
6
|
+
# PHP pre-release versions use 1.0.1-rc1 syntax, which Gem::Version
|
7
|
+
# converts into 1.0.1.pre.rc1. We override the `to_s` method to stop that
|
8
|
+
# alteration.
|
9
|
+
|
10
|
+
module Dependabot
|
11
|
+
module Composer
|
12
|
+
class Version < Gem::Version
|
13
|
+
def initialize(version)
|
14
|
+
@version_string = version.to_s
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
@version_string
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Dependabot::Utils.
|
26
|
+
register_version_class("composer", Dependabot::Composer::Version)
|
metadata
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dependabot-composer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.89.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dependabot
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dependabot-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.89.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.89.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '12'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-its
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec_junit_formatter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.61'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.61'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: vcr
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: webmock
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.4'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '3.4'
|
139
|
+
description: Automated dependency management for Ruby, JavaScript, Python, PHP, Elixir,
|
140
|
+
Rust, Java, .NET, Elm and Go
|
141
|
+
email: support@dependabot.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- helpers/.php_cs
|
147
|
+
- helpers/bin/run.php
|
148
|
+
- helpers/build
|
149
|
+
- helpers/composer.json
|
150
|
+
- helpers/composer.lock
|
151
|
+
- helpers/php/.php_cs
|
152
|
+
- helpers/setup.sh
|
153
|
+
- helpers/src/DependabotInstallationManager.php
|
154
|
+
- helpers/src/DependabotPluginManager.php
|
155
|
+
- helpers/src/ExceptionIO.php
|
156
|
+
- helpers/src/Hasher.php
|
157
|
+
- helpers/src/UpdateChecker.php
|
158
|
+
- helpers/src/Updater.php
|
159
|
+
- lib/dependabot/composer.rb
|
160
|
+
- lib/dependabot/composer/file_fetcher.rb
|
161
|
+
- lib/dependabot/composer/file_parser.rb
|
162
|
+
- lib/dependabot/composer/file_updater.rb
|
163
|
+
- lib/dependabot/composer/file_updater/lockfile_updater.rb
|
164
|
+
- lib/dependabot/composer/file_updater/manifest_updater.rb
|
165
|
+
- lib/dependabot/composer/metadata_finder.rb
|
166
|
+
- lib/dependabot/composer/native_helpers.rb
|
167
|
+
- lib/dependabot/composer/requirement.rb
|
168
|
+
- lib/dependabot/composer/update_checker.rb
|
169
|
+
- lib/dependabot/composer/update_checker/requirements_updater.rb
|
170
|
+
- lib/dependabot/composer/update_checker/version_resolver.rb
|
171
|
+
- lib/dependabot/composer/version.rb
|
172
|
+
homepage: https://github.com/dependabot/dependabot-core
|
173
|
+
licenses:
|
174
|
+
- Nonstandard
|
175
|
+
metadata: {}
|
176
|
+
post_install_message:
|
177
|
+
rdoc_options: []
|
178
|
+
require_paths:
|
179
|
+
- lib
|
180
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: 2.5.0
|
185
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 2.5.0
|
190
|
+
requirements: []
|
191
|
+
rubygems_version: 3.0.2
|
192
|
+
signing_key:
|
193
|
+
specification_version: 4
|
194
|
+
summary: PHP (Composer) support for dependabot-core
|
195
|
+
test_files: []
|