dependabot-bundler 0.331.0 → 0.332.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/lib/dependabot/bundler/file_parser.rb +15 -34
- data/lib/dependabot/bundler/package/package_details_fetcher.rb +10 -2
- data/lib/dependabot/bundler/update_checker/conflicting_dependency_resolver.rb +36 -3
- data/lib/dependabot/bundler/update_checker/force_updater.rb +70 -16
- data/lib/dependabot/bundler/update_checker/shared_bundler_helpers.rb +57 -35
- data/lib/dependabot/bundler/update_checker/version_resolver.rb +78 -22
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0373cdfce669d8fb9d4fb6081a0b2660c58217e1c309cbc49e772971ba5f9f1a
|
4
|
+
data.tar.gz: f0a48edc13f2826d1177be53e368fb9bb9957d50f53bfb1ecdf62b7dc3a13b34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f259e4c088e2e8ccbf1a343e216b606681c4e40538a5aa6306fb508b176904467bbaaeeb9f73a8050e16c14d249204be42444640f1f0485f0da45c4127fdf468
|
7
|
+
data.tar.gz: e0a5c41f18681d4db017a5c6e28646739af2315d89a59e937ad2fee2a6078fb6d48b00c8da8652324616640c95ef740b683442b3bbd2059a77178aa0c9475632
|
@@ -122,21 +122,17 @@ module Dependabot
|
|
122
122
|
parsed_gemfile.each do |dep|
|
123
123
|
next unless gemfile_declaration_finder.gemfile_includes_dependency?(dep)
|
124
124
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
)
|
137
|
-
|
138
|
-
file.dependencies << dep
|
139
|
-
dependencies << dep
|
125
|
+
dependencies << Dependency.new(
|
126
|
+
name: dep.fetch("name"),
|
127
|
+
version: dependency_version(dep.fetch("name"))&.to_s,
|
128
|
+
requirements: [{
|
129
|
+
requirement: gemfile_declaration_finder.enhanced_req_string(dep),
|
130
|
+
groups: dep.fetch("groups").map(&:to_sym),
|
131
|
+
source: dep.fetch("source")&.transform_keys(&:to_sym),
|
132
|
+
file: file.name
|
133
|
+
}],
|
134
|
+
package_manager: "bundler"
|
135
|
+
)
|
140
136
|
end
|
141
137
|
end
|
142
138
|
|
@@ -144,7 +140,7 @@ module Dependabot
|
|
144
140
|
end
|
145
141
|
|
146
142
|
sig { returns(DependencySet) }
|
147
|
-
def gemspec_dependencies # rubocop:disable Metrics/PerceivedComplexity
|
143
|
+
def gemspec_dependencies # rubocop:disable Metrics/PerceivedComplexity
|
148
144
|
@gemspec_dependencies = T.let(@gemspec_dependencies, T.nilable(DependencySet))
|
149
145
|
return @gemspec_dependencies if @gemspec_dependencies
|
150
146
|
|
@@ -159,7 +155,7 @@ module Dependabot
|
|
159
155
|
parsed_gemspec(gemspec).each do |dependency|
|
160
156
|
next unless gemspec_declaration_finder.gemspec_includes_dependency?(dependency)
|
161
157
|
|
162
|
-
|
158
|
+
queue << Dependency.new(
|
163
159
|
name: dependency.fetch("name"),
|
164
160
|
version: dependency_version(dependency.fetch("name"))&.to_s,
|
165
161
|
requirements: [{
|
@@ -174,9 +170,6 @@ module Dependabot
|
|
174
170
|
}],
|
175
171
|
package_manager: "bundler"
|
176
172
|
)
|
177
|
-
|
178
|
-
gemspec.dependencies << dep
|
179
|
-
queue << dep
|
180
173
|
end
|
181
174
|
end
|
182
175
|
end
|
@@ -198,23 +191,15 @@ module Dependabot
|
|
198
191
|
parsed_lockfile.specs.each do |dependency|
|
199
192
|
next if dependency.source.is_a?(::Bundler::Source::Path)
|
200
193
|
|
201
|
-
|
202
|
-
# then it is a direct dependency & we want to keep track of that fact
|
203
|
-
is_direct = parsed_lockfile.dependencies.key?(dependency.name)
|
204
|
-
|
205
|
-
dep = Dependency.new(
|
194
|
+
dependencies << Dependency.new(
|
206
195
|
name: dependency.name,
|
207
196
|
version: dependency_version(dependency.name)&.to_s,
|
208
197
|
requirements: [],
|
209
198
|
package_manager: "bundler",
|
210
199
|
subdependency_metadata: [{
|
211
200
|
production: production_dep_names.include?(dependency.name)
|
212
|
-
}]
|
213
|
-
direct_relationship: is_direct
|
201
|
+
}]
|
214
202
|
)
|
215
|
-
|
216
|
-
T.must(lockfile).dependencies << dep
|
217
|
-
dependencies << dep
|
218
203
|
end
|
219
204
|
|
220
205
|
dependencies
|
@@ -357,10 +342,6 @@ module Dependabot
|
|
357
342
|
get_original_file("Gemfile.lock") || get_original_file("gems.locked"),
|
358
343
|
T.nilable(Dependabot::DependencyFile)
|
359
344
|
)
|
360
|
-
|
361
|
-
# Set the lockfile as higher priority so we know to ignore the Gemfile, etc
|
362
|
-
# when producing a graph.
|
363
|
-
@lockfile&.tap { |f| f.priority = 1 }
|
364
345
|
end
|
365
346
|
|
366
347
|
sig { returns(T.untyped) }
|
@@ -43,17 +43,25 @@ module Dependabot
|
|
43
43
|
@credentials = credentials
|
44
44
|
|
45
45
|
@source_type = T.let(nil, T.nilable(String))
|
46
|
+
@options = T.let({}, T::Hash[Symbol, T.untyped])
|
47
|
+
@repo_contents_path = T.let(nil, T.nilable(String))
|
46
48
|
end
|
47
49
|
|
48
50
|
sig { returns(Dependabot::Dependency) }
|
49
51
|
attr_reader :dependency
|
50
52
|
|
51
|
-
sig { returns(T::Array[T.untyped]) }
|
53
|
+
sig { override.returns(T::Array[T.untyped]) }
|
52
54
|
attr_reader :dependency_files
|
53
55
|
|
54
|
-
sig { returns(T::Array[T.untyped]) }
|
56
|
+
sig { override.returns(T::Array[T.untyped]) }
|
55
57
|
attr_reader :credentials
|
56
58
|
|
59
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
60
|
+
attr_reader :options
|
61
|
+
|
62
|
+
sig { override.returns(T.nilable(String)) }
|
63
|
+
attr_reader :repo_contents_path
|
64
|
+
|
57
65
|
sig { returns(Dependabot::Package::PackageDetails) }
|
58
66
|
def fetch
|
59
67
|
case source_type
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/bundler/update_checker"
|
@@ -10,11 +10,33 @@ module Dependabot
|
|
10
10
|
module Bundler
|
11
11
|
class UpdateChecker < UpdateCheckers::Base
|
12
12
|
class ConflictingDependencyResolver
|
13
|
+
extend T::Sig
|
14
|
+
|
13
15
|
require_relative "shared_bundler_helpers"
|
16
|
+
|
14
17
|
include SharedBundlerHelpers
|
15
18
|
|
19
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
16
20
|
attr_reader :options
|
17
21
|
|
22
|
+
sig { override.returns(T::Array[Dependabot::Credential]) }
|
23
|
+
attr_reader :credentials
|
24
|
+
|
25
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
26
|
+
attr_reader :dependency_files
|
27
|
+
|
28
|
+
sig { override.returns(T.nilable(String)) }
|
29
|
+
attr_reader :repo_contents_path
|
30
|
+
|
31
|
+
sig do
|
32
|
+
params(
|
33
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
34
|
+
repo_contents_path: T.nilable(String),
|
35
|
+
credentials: T::Array[Dependabot::Credential],
|
36
|
+
options: T::Hash[Symbol, T.untyped]
|
37
|
+
)
|
38
|
+
.void
|
39
|
+
end
|
18
40
|
def initialize(dependency_files:, repo_contents_path:, credentials:, options:)
|
19
41
|
@dependency_files = dependency_files
|
20
42
|
@repo_contents_path = repo_contents_path
|
@@ -31,6 +53,13 @@ module Dependabot
|
|
31
53
|
# * name [String] the blocking dependencies name
|
32
54
|
# * version [String] the version of the blocking dependency
|
33
55
|
# * requirement [String] the requirement on the target_dependency
|
56
|
+
sig do
|
57
|
+
params(
|
58
|
+
dependency: Dependabot::Dependency,
|
59
|
+
target_version: String
|
60
|
+
)
|
61
|
+
.returns(T::Array[T::Hash[String, String]])
|
62
|
+
end
|
34
63
|
def conflicting_dependencies(dependency:, target_version:)
|
35
64
|
return [] if lockfile.nil?
|
36
65
|
|
@@ -44,7 +73,7 @@ module Dependabot
|
|
44
73
|
dependency_name: dependency.name,
|
45
74
|
target_version: target_version,
|
46
75
|
credentials: credentials,
|
47
|
-
lockfile_name: lockfile.name
|
76
|
+
lockfile_name: T.must(lockfile).name
|
48
77
|
}
|
49
78
|
)
|
50
79
|
end
|
@@ -52,8 +81,12 @@ module Dependabot
|
|
52
81
|
|
53
82
|
private
|
54
83
|
|
84
|
+
sig { override.returns(String) }
|
55
85
|
def bundler_version
|
56
|
-
@bundler_version ||=
|
86
|
+
@bundler_version ||= T.let(
|
87
|
+
Helpers.bundler_version(lockfile),
|
88
|
+
T.nilable(String)
|
89
|
+
)
|
57
90
|
end
|
58
91
|
end
|
59
92
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
4
5
|
require "dependabot/bundler/file_parser"
|
5
6
|
require "dependabot/bundler/file_updater/lockfile_updater"
|
6
7
|
require "dependabot/bundler/native_helpers"
|
@@ -14,14 +15,28 @@ module Dependabot
|
|
14
15
|
module Bundler
|
15
16
|
class UpdateChecker
|
16
17
|
class ForceUpdater
|
18
|
+
extend T::Sig
|
19
|
+
|
17
20
|
require_relative "shared_bundler_helpers"
|
21
|
+
|
18
22
|
include SharedBundlerHelpers
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
sig do
|
25
|
+
params(
|
26
|
+
dependency: Dependabot::Dependency,
|
27
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
28
|
+
credentials: T::Array[Dependabot::Credential],
|
29
|
+
target_version: Dependabot::Version,
|
30
|
+
requirements_update_strategy: Dependabot::RequirementsUpdateStrategy,
|
31
|
+
options: T::Hash[Symbol, T.untyped],
|
32
|
+
repo_contents_path: T.nilable(String),
|
33
|
+
update_multiple_dependencies: T::Boolean
|
34
|
+
).void
|
35
|
+
end
|
36
|
+
def initialize(dependency:, dependency_files:, credentials:, target_version:,
|
37
|
+
requirements_update_strategy:, options:,
|
38
|
+
repo_contents_path: nil,
|
39
|
+
update_multiple_dependencies: true)
|
25
40
|
@dependency = dependency
|
26
41
|
@dependency_files = dependency_files
|
27
42
|
@repo_contents_path = repo_contents_path
|
@@ -30,28 +45,50 @@ module Dependabot
|
|
30
45
|
@requirements_update_strategy = requirements_update_strategy
|
31
46
|
@update_multiple_dependencies = update_multiple_dependencies
|
32
47
|
@options = options
|
48
|
+
|
49
|
+
@updated_dependencies = T.let(nil, T.nilable(T::Array[Dependabot::Dependency]))
|
50
|
+
@original_dependencies = T.let(nil, T.nilable(T::Array[Dependabot::Dependency]))
|
51
|
+
@bundler_version = T.let(nil, T.nilable(String))
|
33
52
|
end
|
34
53
|
|
54
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
35
55
|
def updated_dependencies
|
36
56
|
@updated_dependencies ||= force_update
|
37
57
|
end
|
38
58
|
|
39
|
-
|
40
|
-
|
41
|
-
attr_reader :dependency
|
59
|
+
# Abstract method implementations
|
60
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
42
61
|
attr_reader :dependency_files
|
62
|
+
|
63
|
+
sig { override.returns(T.nilable(String)) }
|
43
64
|
attr_reader :repo_contents_path
|
65
|
+
|
66
|
+
sig { override.returns(T::Array[Dependabot::Credential]) }
|
44
67
|
attr_reader :credentials
|
68
|
+
|
69
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
70
|
+
attr_reader :options
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
sig { returns(Dependabot::Dependency) }
|
75
|
+
attr_reader :dependency
|
76
|
+
|
77
|
+
sig { returns(Dependabot::Version) }
|
45
78
|
attr_reader :target_version
|
79
|
+
|
80
|
+
sig { returns(Dependabot::RequirementsUpdateStrategy) }
|
46
81
|
attr_reader :requirements_update_strategy
|
47
|
-
attr_reader :options
|
48
82
|
|
83
|
+
sig { returns(T::Boolean) }
|
49
84
|
def update_multiple_dependencies?
|
50
85
|
@update_multiple_dependencies
|
51
86
|
end
|
52
87
|
|
88
|
+
# rubocop:disable Metrics/AbcSize
|
89
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
53
90
|
def force_update
|
54
|
-
requirement = dependency.requirements.find { |req| req[:file] == gemfile.name }
|
91
|
+
requirement = dependency.requirements.find { |req| req[:file] == T.must(gemfile).name }
|
55
92
|
|
56
93
|
valid_gem_version?(target_version)
|
57
94
|
|
@@ -71,8 +108,8 @@ module Dependabot
|
|
71
108
|
dependency_name: dependency.name,
|
72
109
|
target_version: target_version,
|
73
110
|
credentials: credentials,
|
74
|
-
gemfile_name: gemfile.name,
|
75
|
-
lockfile_name: lockfile.name,
|
111
|
+
gemfile_name: T.must(gemfile).name,
|
112
|
+
lockfile_name: T.must(lockfile).name,
|
76
113
|
update_multiple_dependencies: update_multiple_dependencies?
|
77
114
|
}
|
78
115
|
)
|
@@ -82,7 +119,9 @@ module Dependabot
|
|
82
119
|
raise Dependabot::DependencyFileNotResolvable, msg
|
83
120
|
end
|
84
121
|
end
|
122
|
+
# rubocop:enable Metrics/AbcSize
|
85
123
|
|
124
|
+
sig { params(target_version: T.nilable(Dependabot::Version)).returns(TrueClass) }
|
86
125
|
def valid_gem_version?(target_version)
|
87
126
|
# to rule out empty, non gem info ending up in as target_version
|
88
127
|
return true if target_version.is_a?(Gem::Version)
|
@@ -92,6 +131,7 @@ module Dependabot
|
|
92
131
|
raise Dependabot::DependencyFileNotResolvable
|
93
132
|
end
|
94
133
|
|
134
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
95
135
|
def original_dependencies
|
96
136
|
@original_dependencies ||=
|
97
137
|
FileParser.new(
|
@@ -101,6 +141,13 @@ module Dependabot
|
|
101
141
|
).parse
|
102
142
|
end
|
103
143
|
|
144
|
+
sig do
|
145
|
+
params(
|
146
|
+
updated_deps: T::Array[T::Hash[String, T.untyped]],
|
147
|
+
specs: T::Array[T::Hash[String, T.untyped]]
|
148
|
+
)
|
149
|
+
.returns(T::Array[Dependabot::Dependency])
|
150
|
+
end
|
104
151
|
def dependencies_from(updated_deps, specs)
|
105
152
|
# You might think we'd want to remove dependencies whose version
|
106
153
|
# hadn't changed from this array. We don't. We still need to unlock
|
@@ -114,12 +161,13 @@ module Dependabot
|
|
114
161
|
original_dependencies.find { |d| d.name == dep.fetch("name") }
|
115
162
|
spec = specs.find { |d| d.fetch("name") == dep.fetch("name") }
|
116
163
|
|
117
|
-
next if spec.fetch("version") == original_dep.version
|
164
|
+
next if T.must(spec).fetch("version") == T.must(original_dep).version
|
118
165
|
|
119
166
|
build_dependency(original_dep, spec)
|
120
167
|
end
|
121
168
|
end
|
122
169
|
|
170
|
+
sig { params(original_dep: T.untyped, updated_spec: T.untyped).returns(Dependabot::Dependency) }
|
123
171
|
def build_dependency(original_dep, updated_spec)
|
124
172
|
Dependency.new(
|
125
173
|
name: updated_spec.fetch("name"),
|
@@ -138,27 +186,32 @@ module Dependabot
|
|
138
186
|
)
|
139
187
|
end
|
140
188
|
|
189
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(T::Hash[String, T.untyped])) }
|
141
190
|
def source_for(dependency)
|
142
191
|
dependency.requirements
|
143
192
|
.find { |r| r.fetch(:source) }
|
144
193
|
&.fetch(:source)
|
145
194
|
end
|
146
195
|
|
196
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
147
197
|
def gemfile
|
148
198
|
dependency_files.find { |f| f.name == "Gemfile" } ||
|
149
199
|
dependency_files.find { |f| f.name == "gems.rb" }
|
150
200
|
end
|
151
201
|
|
202
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
152
203
|
def lockfile
|
153
204
|
dependency_files.find { |f| f.name == "Gemfile.lock" } ||
|
154
205
|
dependency_files.find { |f| f.name == "gems.locked" }
|
155
206
|
end
|
156
207
|
|
208
|
+
sig { returns(String) }
|
157
209
|
def sanitized_lockfile_body
|
158
210
|
re = FileUpdater::LockfileUpdater::LOCKFILE_ENDING
|
159
|
-
lockfile.content.gsub(re, "")
|
211
|
+
T.must(T.must(lockfile).content).gsub(re, "")
|
160
212
|
end
|
161
213
|
|
214
|
+
sig { void }
|
162
215
|
def write_temporary_dependency_files
|
163
216
|
dependency_files.each do |file|
|
164
217
|
path = file.name
|
@@ -166,9 +219,10 @@ module Dependabot
|
|
166
219
|
File.write(path, file.content)
|
167
220
|
end
|
168
221
|
|
169
|
-
File.write(lockfile.name, sanitized_lockfile_body) if lockfile
|
222
|
+
File.write(T.must(lockfile).name, sanitized_lockfile_body) if lockfile
|
170
223
|
end
|
171
224
|
|
225
|
+
sig { override.returns(String) }
|
172
226
|
def bundler_version
|
173
227
|
@bundler_version ||= Helpers.bundler_version(lockfile)
|
174
228
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "excon"
|
@@ -23,8 +23,17 @@ module Dependabot
|
|
23
23
|
|
24
24
|
abstract!
|
25
25
|
|
26
|
-
sig { returns(T::Hash[Symbol, T.untyped]) }
|
27
|
-
|
26
|
+
sig { abstract.returns(T::Hash[Symbol, T.untyped]) }
|
27
|
+
def options; end
|
28
|
+
|
29
|
+
sig { abstract.returns(T::Array[Dependabot::DependencyFile]) }
|
30
|
+
def dependency_files; end
|
31
|
+
|
32
|
+
sig { abstract.returns(T.nilable(String)) }
|
33
|
+
def repo_contents_path; end
|
34
|
+
|
35
|
+
sig { abstract.returns(T::Array[Dependabot::Credential]) }
|
36
|
+
def credentials; end
|
28
37
|
|
29
38
|
GIT_REGEX = /reset --hard [^\s]*` in directory (?<path>[^\s]*)/
|
30
39
|
GIT_REF_REGEX = /not exist in the repository (?<path>[^\s]*)\./
|
@@ -51,21 +60,24 @@ module Dependabot
|
|
51
60
|
Bundler::Fetcher::FallbackError
|
52
61
|
).freeze
|
53
62
|
|
54
|
-
attr_reader :dependency_files
|
55
|
-
attr_reader :repo_contents_path
|
56
|
-
attr_reader :credentials
|
57
|
-
|
58
63
|
#########################
|
59
64
|
# Bundler context setup #
|
60
65
|
#########################
|
61
66
|
|
62
|
-
|
67
|
+
sig do
|
68
|
+
params(
|
69
|
+
error_handling: T::Boolean,
|
70
|
+
_blk: T.proc.params(arg0: String).returns(T.untyped)
|
71
|
+
)
|
72
|
+
.returns(T.untyped)
|
73
|
+
end
|
74
|
+
def in_a_native_bundler_context(error_handling: true, &_blk)
|
63
75
|
SharedHelpers
|
64
76
|
.in_a_temporary_repo_directory(base_directory,
|
65
77
|
repo_contents_path) do |tmp_dir|
|
66
78
|
write_temporary_dependency_files
|
67
79
|
|
68
|
-
yield(tmp_dir)
|
80
|
+
yield(tmp_dir.to_s)
|
69
81
|
end
|
70
82
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
71
83
|
retry_count ||= 0
|
@@ -75,10 +87,12 @@ module Dependabot
|
|
75
87
|
error_handling ? handle_bundler_errors(e) : raise
|
76
88
|
end
|
77
89
|
|
90
|
+
sig { returns(String) }
|
78
91
|
def base_directory
|
79
|
-
dependency_files.first.directory
|
92
|
+
T.must(dependency_files.first).directory
|
80
93
|
end
|
81
94
|
|
95
|
+
sig { params(error: Dependabot::SharedHelpers::HelperSubprocessFailed).returns(T::Boolean) }
|
82
96
|
def retryable_error?(error)
|
83
97
|
return true if error.error_class == "JSON::ParserError"
|
84
98
|
return true if RETRYABLE_ERRORS.include?(error.error_class)
|
@@ -92,6 +106,7 @@ module Dependabot
|
|
92
106
|
# rubocop:disable Metrics/PerceivedComplexity
|
93
107
|
# rubocop:disable Metrics/AbcSize
|
94
108
|
# rubocop:disable Metrics/MethodLength
|
109
|
+
sig { params(error: Dependabot::SharedHelpers::HelperSubprocessFailed).void }
|
95
110
|
def handle_bundler_errors(error)
|
96
111
|
if error.error_class == "JSON::ParserError"
|
97
112
|
msg = "Error evaluating your dependency files: #{error.message}"
|
@@ -105,25 +120,22 @@ module Dependabot
|
|
105
120
|
# We couldn't evaluate the Gemfile, let alone resolve it
|
106
121
|
raise Dependabot::DependencyFileNotEvaluatable, msg
|
107
122
|
when "Bundler::Source::Git::MissingGitRevisionError"
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
raise GitDependencyReferenceNotFound, gem_name
|
123
|
+
match_data = error.message.match(GIT_REF_REGEX)
|
124
|
+
gem_name = T.must(T.must(match_data).named_captures["path"])
|
125
|
+
.split("/").last
|
126
|
+
raise GitDependencyReferenceNotFound, T.must(gem_name)
|
113
127
|
when "Bundler::PathError"
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
.split("/").last.split("-")[0..-2].join
|
128
|
+
match_data = error.message.match(PATH_REGEX)
|
129
|
+
path = T.must(T.must(match_data).named_captures["path"])
|
130
|
+
gem_name = T.must(T.must(path.split("/").last).split("-")[0..-2]).join
|
118
131
|
raise Dependabot::PathDependenciesNotReachable, [gem_name]
|
119
132
|
when "Bundler::Source::Git::GitCommandError"
|
120
133
|
if error.message.match?(GIT_REGEX)
|
121
134
|
# We couldn't find the specified branch / commit (or the two
|
122
135
|
# weren't compatible).
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
.split("/").last.split("-")[0..-2].join
|
136
|
+
match_data = error.message.match(GIT_REGEX)
|
137
|
+
path = T.must(T.must(match_data).named_captures["path"])
|
138
|
+
gem_name = T.must(T.must(path.split("/").last).split("-")[0..-2]).join
|
127
139
|
raise GitDependencyReferenceNotFound, gem_name
|
128
140
|
end
|
129
141
|
|
@@ -144,24 +156,24 @@ module Dependabot
|
|
144
156
|
raise Dependabot::DependencyFileNotResolvable, msg
|
145
157
|
when "Bundler::Fetcher::AuthenticationRequiredError"
|
146
158
|
regex = BundlerErrorPatterns::MISSING_AUTH_REGEX
|
147
|
-
source = error.message.match(regex)[:source]
|
159
|
+
source = T.must(T.must(error.message.match(regex))[:source])
|
148
160
|
raise Dependabot::PrivateSourceAuthenticationFailure, source
|
149
161
|
when "Bundler::Fetcher::AuthenticationForbiddenError"
|
150
162
|
regex = BundlerErrorPatterns::FORBIDDEN_AUTH_REGEX
|
151
|
-
source = error.message.match(regex)[:source]
|
163
|
+
source = T.must(T.must(error.message.match(regex))[:source])
|
152
164
|
raise Dependabot::PrivateSourceAuthenticationFailure, source
|
153
165
|
when "Bundler::Fetcher::BadAuthenticationError"
|
154
166
|
regex = BundlerErrorPatterns::BAD_AUTH_REGEX
|
155
|
-
source = error.message.match(regex)[:source]
|
167
|
+
source = T.must(T.must(error.message.match(regex))[:source])
|
156
168
|
raise Dependabot::PrivateSourceAuthenticationFailure, source
|
157
169
|
when "Bundler::Fetcher::CertificateFailureError"
|
158
170
|
regex = BundlerErrorPatterns::BAD_CERT_REGEX
|
159
|
-
source = error.message.match(regex)[:source]
|
171
|
+
source = T.must(T.must(error.message.match(regex))[:source])
|
160
172
|
raise Dependabot::PrivateSourceCertificateFailure, source
|
161
173
|
when "Bundler::HTTPError"
|
162
174
|
regex = BundlerErrorPatterns::HTTP_ERR_REGEX
|
163
175
|
if error.message.match?(regex)
|
164
|
-
source = error.message.match(regex)[:source]
|
176
|
+
source = T.must(T.must(error.message.match(regex))[:source])
|
165
177
|
raise if [
|
166
178
|
"rubygems.org",
|
167
179
|
"www.rubygems.org"
|
@@ -184,6 +196,7 @@ module Dependabot
|
|
184
196
|
# rubocop:enable Metrics/AbcSize
|
185
197
|
# rubocop:enable Metrics/MethodLength
|
186
198
|
|
199
|
+
sig { returns(T::Array[T::Hash[String, T.untyped]]) }
|
187
200
|
def inaccessible_git_dependencies
|
188
201
|
in_a_native_bundler_context(error_handling: false) do |tmp_dir|
|
189
202
|
git_specs = NativeHelpers.run_bundler_subprocess(
|
@@ -192,7 +205,7 @@ module Dependabot
|
|
192
205
|
options: options,
|
193
206
|
args: {
|
194
207
|
dir: tmp_dir,
|
195
|
-
gemfile_name: gemfile.name,
|
208
|
+
gemfile_name: T.must(gemfile).name,
|
196
209
|
credentials: credentials
|
197
210
|
}
|
198
211
|
)
|
@@ -210,8 +223,10 @@ module Dependabot
|
|
210
223
|
end
|
211
224
|
end
|
212
225
|
|
226
|
+
sig { returns(T.nilable(String)) }
|
213
227
|
def jfrog_source
|
214
|
-
|
228
|
+
@jfrog_source = T.let(@jfrog_source, T.nilable(String)) if @jfrog_source.nil?
|
229
|
+
return @jfrog_source unless @jfrog_source.nil?
|
215
230
|
|
216
231
|
@jfrog_source = in_a_native_bundler_context(error_handling: false) do |dir|
|
217
232
|
NativeHelpers.run_bundler_subprocess(
|
@@ -220,16 +235,14 @@ module Dependabot
|
|
220
235
|
options: options,
|
221
236
|
args: {
|
222
237
|
dir: dir,
|
223
|
-
gemfile_name: gemfile.name,
|
238
|
+
gemfile_name: T.must(gemfile).name,
|
224
239
|
credentials: credentials
|
225
240
|
}
|
226
241
|
)
|
227
242
|
end
|
228
243
|
end
|
229
244
|
|
230
|
-
sig {
|
231
|
-
def bundler_version; end
|
232
|
-
|
245
|
+
sig { void }
|
233
246
|
def write_temporary_dependency_files
|
234
247
|
dependency_files.each do |file|
|
235
248
|
path = file.name
|
@@ -237,23 +250,32 @@ module Dependabot
|
|
237
250
|
File.write(path, file.content)
|
238
251
|
end
|
239
252
|
|
240
|
-
|
253
|
+
lockfile_obj = lockfile
|
254
|
+
File.write(lockfile_obj.name, lockfile_obj.content) if lockfile_obj
|
241
255
|
end
|
242
256
|
|
257
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
243
258
|
def private_registry_credentials
|
244
259
|
credentials
|
245
260
|
.select { |cred| cred["type"] == "rubygems_server" }
|
246
261
|
end
|
247
262
|
|
263
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
248
264
|
def gemfile
|
249
265
|
dependency_files.find { |f| f.name == "Gemfile" } ||
|
250
266
|
dependency_files.find { |f| f.name == "gems.rb" }
|
251
267
|
end
|
252
268
|
|
269
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
253
270
|
def lockfile
|
254
271
|
dependency_files.find { |f| f.name == "Gemfile.lock" } ||
|
255
272
|
dependency_files.find { |f| f.name == "gems.locked" }
|
256
273
|
end
|
274
|
+
|
275
|
+
private
|
276
|
+
|
277
|
+
sig { abstract.returns(String) }
|
278
|
+
def bundler_version; end
|
257
279
|
end
|
258
280
|
end
|
259
281
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "excon"
|
5
|
+
require "sorbet-runtime"
|
5
6
|
|
6
7
|
require "dependabot/bundler/helpers"
|
7
8
|
require "dependabot/bundler/update_checker"
|
@@ -15,19 +16,36 @@ module Dependabot
|
|
15
16
|
module Bundler
|
16
17
|
class UpdateChecker
|
17
18
|
class VersionResolver
|
19
|
+
extend T::Sig
|
20
|
+
|
18
21
|
require_relative "file_preparer"
|
19
22
|
require_relative "latest_version_finder"
|
20
23
|
require_relative "shared_bundler_helpers"
|
21
24
|
include SharedBundlerHelpers
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
sig do
|
27
|
+
params(
|
28
|
+
dependency: Dependabot::Dependency,
|
29
|
+
unprepared_dependency_files: T::Array[Dependabot::DependencyFile],
|
30
|
+
credentials: T::Array[Dependabot::Credential],
|
31
|
+
ignored_versions: T::Array[String],
|
32
|
+
options: T::Hash[Symbol, T.untyped],
|
33
|
+
repo_contents_path: T.nilable(String),
|
34
|
+
raise_on_ignored: T::Boolean,
|
35
|
+
replacement_git_pin: T.nilable(String),
|
36
|
+
remove_git_source: T::Boolean,
|
37
|
+
unlock_requirement: T::Boolean,
|
38
|
+
latest_allowable_version: T.nilable(T.any(String, Dependabot::Version)),
|
39
|
+
cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
|
40
|
+
).void
|
41
|
+
end
|
42
|
+
def initialize(dependency:, unprepared_dependency_files:, credentials:, ignored_versions:, options:,
|
43
|
+
repo_contents_path: nil,
|
25
44
|
raise_on_ignored: false,
|
26
45
|
replacement_git_pin: nil, remove_git_source: false,
|
27
46
|
unlock_requirement: true,
|
28
47
|
latest_allowable_version: nil,
|
29
|
-
cooldown_options: nil
|
30
|
-
options:)
|
48
|
+
cooldown_options: nil)
|
31
49
|
@dependency = dependency
|
32
50
|
@unprepared_dependency_files = unprepared_dependency_files
|
33
51
|
@credentials = credentials
|
@@ -41,50 +59,77 @@ module Dependabot
|
|
41
59
|
@cooldown_options = cooldown_options
|
42
60
|
@options = options
|
43
61
|
|
44
|
-
@latest_allowable_version_incompatible_with_ruby = false
|
62
|
+
@latest_allowable_version_incompatible_with_ruby = T.let(false, T::Boolean)
|
63
|
+
@latest_resolvable_version_details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
|
64
|
+
@dependency_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
65
|
+
@latest_version_details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
|
66
|
+
@gemspec_ruby_unlocked = T.let(false, T::Boolean)
|
67
|
+
@bundler_version = T.let(nil, T.nilable(String))
|
45
68
|
end
|
46
69
|
|
70
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
47
71
|
def latest_resolvable_version_details
|
48
72
|
@latest_resolvable_version_details ||=
|
49
73
|
fetch_latest_resolvable_version_details
|
50
74
|
end
|
51
75
|
|
76
|
+
sig { returns(T::Boolean) }
|
52
77
|
def latest_allowable_version_incompatible_with_ruby?
|
53
78
|
@latest_allowable_version_incompatible_with_ruby
|
54
79
|
end
|
55
80
|
|
81
|
+
# Abstract method implementations
|
82
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
83
|
+
attr_reader :options
|
84
|
+
|
85
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
86
|
+
def dependency_files
|
87
|
+
@dependency_files ||=
|
88
|
+
FilePreparer.new(
|
89
|
+
dependency: dependency,
|
90
|
+
dependency_files: unprepared_dependency_files,
|
91
|
+
replacement_git_pin: replacement_git_pin,
|
92
|
+
remove_git_source: remove_git_source?,
|
93
|
+
unlock_requirement: unlock_requirement?,
|
94
|
+
latest_allowable_version: latest_allowable_version
|
95
|
+
).prepared_dependency_files
|
96
|
+
end
|
97
|
+
|
98
|
+
sig { override.returns(T.nilable(String)) }
|
99
|
+
attr_reader :repo_contents_path
|
100
|
+
|
101
|
+
sig { override.returns(T::Array[Dependabot::Credential]) }
|
102
|
+
attr_reader :credentials
|
103
|
+
|
56
104
|
private
|
57
105
|
|
106
|
+
sig { returns(Dependabot::Dependency) }
|
58
107
|
attr_reader :dependency
|
108
|
+
|
109
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
59
110
|
attr_reader :unprepared_dependency_files
|
60
|
-
|
61
|
-
|
111
|
+
|
112
|
+
sig { returns(T::Array[String]) }
|
62
113
|
attr_reader :ignored_versions
|
114
|
+
|
115
|
+
sig { returns(T.nilable(String)) }
|
63
116
|
attr_reader :replacement_git_pin
|
117
|
+
|
118
|
+
sig { returns(T.nilable(T.any(String, Dependabot::Version))) }
|
64
119
|
attr_reader :latest_allowable_version
|
65
|
-
attr_reader :options
|
66
120
|
|
121
|
+
sig { returns(T::Boolean) }
|
67
122
|
def remove_git_source?
|
68
123
|
@remove_git_source
|
69
124
|
end
|
70
125
|
|
126
|
+
sig { returns(T::Boolean) }
|
71
127
|
def unlock_requirement?
|
72
128
|
@unlock_requirement
|
73
129
|
end
|
74
130
|
|
75
|
-
def dependency_files
|
76
|
-
@dependency_files ||=
|
77
|
-
FilePreparer.new(
|
78
|
-
dependency: dependency,
|
79
|
-
dependency_files: unprepared_dependency_files,
|
80
|
-
replacement_git_pin: replacement_git_pin,
|
81
|
-
remove_git_source: remove_git_source?,
|
82
|
-
unlock_requirement: unlock_requirement?,
|
83
|
-
latest_allowable_version: latest_allowable_version
|
84
|
-
).prepared_dependency_files
|
85
|
-
end
|
86
|
-
|
87
131
|
# rubocop:disable Metrics/PerceivedComplexity
|
132
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
88
133
|
def fetch_latest_resolvable_version_details
|
89
134
|
return latest_version_details unless gemfile
|
90
135
|
|
@@ -100,7 +145,7 @@ module Dependabot
|
|
100
145
|
args: {
|
101
146
|
dependency_name: dependency.name,
|
102
147
|
dependency_requirements: dependency.requirements,
|
103
|
-
gemfile_name: gemfile.name,
|
148
|
+
gemfile_name: T.must(gemfile).name,
|
104
149
|
lockfile_name: lockfile&.name,
|
105
150
|
dir: tmp_dir,
|
106
151
|
credentials: credentials
|
@@ -136,12 +181,14 @@ module Dependabot
|
|
136
181
|
end
|
137
182
|
# rubocop:enable Metrics/PerceivedComplexity
|
138
183
|
|
184
|
+
sig { params(error: Dependabot::SharedHelpers::HelperSubprocessFailed).returns(T::Boolean) }
|
139
185
|
def circular_dependency_at_new_version?(error)
|
140
186
|
return false unless error.error_class.include?("CyclicDependencyError")
|
141
187
|
|
142
188
|
error.message.include?("'#{dependency.name}'")
|
143
189
|
end
|
144
190
|
|
191
|
+
sig { params(error: Dependabot::SharedHelpers::HelperSubprocessFailed).returns(T::Boolean) }
|
145
192
|
def error_due_to_restrictive_upper_bound?(error)
|
146
193
|
# We see this when the dependency doesn't appear in the lockfile and
|
147
194
|
# has an overly restrictive upper bound that we've added, either due
|
@@ -152,6 +199,7 @@ module Dependabot
|
|
152
199
|
error.message.include?("#{dependency.name} ")
|
153
200
|
end
|
154
201
|
|
202
|
+
sig { params(error: T.untyped).returns(T::Boolean) }
|
155
203
|
def ruby_lock_error?(error)
|
156
204
|
return false unless conflict_on_ruby?(error)
|
157
205
|
return false if @gemspec_ruby_unlocked
|
@@ -159,6 +207,7 @@ module Dependabot
|
|
159
207
|
dependency_files.any? { |f| f.name.end_with?(".gemspec") }
|
160
208
|
end
|
161
209
|
|
210
|
+
sig { params(error: Dependabot::SharedHelpers::HelperSubprocessFailed).returns(T::Boolean) }
|
162
211
|
def conflict_on_ruby?(error)
|
163
212
|
if bundler_version == "1"
|
164
213
|
error.message.include?(" for gem \"ruby\0\"")
|
@@ -167,6 +216,7 @@ module Dependabot
|
|
167
216
|
end
|
168
217
|
end
|
169
218
|
|
219
|
+
sig { returns(T::Boolean) }
|
170
220
|
def regenerate_dependency_files_without_ruby_lock
|
171
221
|
@dependency_files =
|
172
222
|
FilePreparer.new(
|
@@ -178,8 +228,10 @@ module Dependabot
|
|
178
228
|
latest_allowable_version: latest_allowable_version,
|
179
229
|
lock_ruby_version: false
|
180
230
|
).prepared_dependency_files
|
231
|
+
true
|
181
232
|
end
|
182
233
|
|
234
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
183
235
|
def latest_version_details
|
184
236
|
@latest_version_details ||=
|
185
237
|
LatestVersionFinder.new(
|
@@ -194,6 +246,7 @@ module Dependabot
|
|
194
246
|
).latest_version_details
|
195
247
|
end
|
196
248
|
|
249
|
+
sig { params(details: T.untyped).returns(T::Boolean) }
|
197
250
|
def ruby_version_incompatible?(details)
|
198
251
|
# It's only the old index we have a problem with
|
199
252
|
return false unless details[:fetcher] == "Bundler::Fetcher::Dependency"
|
@@ -231,16 +284,19 @@ module Dependabot
|
|
231
284
|
false
|
232
285
|
end
|
233
286
|
|
287
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
234
288
|
def gemfile
|
235
289
|
dependency_files.find { |f| f.name == "Gemfile" } ||
|
236
290
|
dependency_files.find { |f| f.name == "gems.rb" }
|
237
291
|
end
|
238
292
|
|
293
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
239
294
|
def lockfile
|
240
295
|
dependency_files.find { |f| f.name == "Gemfile.lock" } ||
|
241
296
|
dependency_files.find { |f| f.name == "gems.locked" }
|
242
297
|
end
|
243
298
|
|
299
|
+
sig { override.returns(String) }
|
244
300
|
def bundler_version
|
245
301
|
@bundler_version ||= Helpers.bundler_version(lockfile)
|
246
302
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-bundler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.332.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.
|
18
|
+
version: 0.332.0
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - '='
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 0.
|
25
|
+
version: 0.332.0
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: parallel
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -322,7 +322,7 @@ licenses:
|
|
322
322
|
- MIT
|
323
323
|
metadata:
|
324
324
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
325
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
325
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.332.0
|
326
326
|
rdoc_options: []
|
327
327
|
require_paths:
|
328
328
|
- lib
|