dependabot-bundler 0.333.0 → 0.334.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_updater/git_pin_replacer.rb +27 -6
- data/lib/dependabot/bundler/file_updater/git_source_remover.rb +14 -2
- data/lib/dependabot/bundler/file_updater/lockfile_updater.rb +85 -26
- data/lib/dependabot/bundler/file_updater/requirement_replacer.rb +74 -10
- data/lib/dependabot/bundler/file_updater.rb +48 -19
- data/lib/dependabot/bundler/metadata_finder.rb +50 -22
- data/lib/dependabot/bundler/requirement.rb +3 -2
- data/lib/dependabot/bundler/update_checker/file_preparer.rb +69 -19
- data/lib/dependabot/bundler/update_checker/force_updater.rb +1 -1
- data/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb +47 -11
- data/lib/dependabot/bundler/update_checker/requirements_updater.rb +77 -29
- data/lib/dependabot/bundler/update_checker.rb +1 -1
- metadata +4 -4
@@ -1,6 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/dependency_file"
|
5
7
|
require "dependabot/bundler/update_checker"
|
6
8
|
require "dependabot/bundler/cached_lockfile_parser"
|
@@ -26,10 +28,13 @@ module Dependabot
|
|
26
28
|
# version allowed by the gemspec, if the gemspec has a required ruby
|
27
29
|
# version range
|
28
30
|
class FilePreparer
|
31
|
+
extend T::Sig
|
32
|
+
|
29
33
|
VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/
|
30
34
|
|
31
35
|
# Can't be a constant because some of these don't exist in bundler
|
32
36
|
# 1.15, which Heroku uses, which causes an exception on boot.
|
37
|
+
sig { returns(T::Array[T.class_of(::Bundler::Source::Path)]) }
|
33
38
|
def gemspec_sources
|
34
39
|
[
|
35
40
|
::Bundler::Source::Path,
|
@@ -37,31 +42,47 @@ module Dependabot
|
|
37
42
|
]
|
38
43
|
end
|
39
44
|
|
45
|
+
sig do
|
46
|
+
params(
|
47
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
48
|
+
dependency: Dependabot::Dependency,
|
49
|
+
remove_git_source: T::Boolean,
|
50
|
+
unlock_requirement: T::Boolean,
|
51
|
+
replacement_git_pin: T.nilable(String),
|
52
|
+
latest_allowable_version: T.nilable(T.any(String, Dependabot::Version)),
|
53
|
+
lock_ruby_version: T::Boolean
|
54
|
+
).void
|
55
|
+
end
|
40
56
|
def initialize(dependency_files:, dependency:,
|
41
57
|
remove_git_source: false,
|
42
58
|
unlock_requirement: true,
|
43
59
|
replacement_git_pin: nil,
|
44
60
|
latest_allowable_version: nil,
|
45
61
|
lock_ruby_version: true)
|
46
|
-
@dependency_files
|
47
|
-
@dependency
|
48
|
-
@remove_git_source
|
49
|
-
@unlock_requirement
|
50
|
-
@replacement_git_pin
|
51
|
-
@latest_allowable_version =
|
52
|
-
|
62
|
+
@dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
|
63
|
+
@dependency = T.let(dependency, Dependabot::Dependency)
|
64
|
+
@remove_git_source = T.let(remove_git_source, T::Boolean)
|
65
|
+
@unlock_requirement = T.let(unlock_requirement, T::Boolean)
|
66
|
+
@replacement_git_pin = T.let(replacement_git_pin, T.nilable(String))
|
67
|
+
@latest_allowable_version = T.let(
|
68
|
+
latest_allowable_version&.to_s,
|
69
|
+
T.nilable(String)
|
70
|
+
)
|
71
|
+
@lock_ruby_version = T.let(lock_ruby_version, T::Boolean)
|
53
72
|
end
|
54
73
|
|
55
74
|
# rubocop:disable Metrics/AbcSize
|
56
75
|
# rubocop:disable Metrics/MethodLength
|
76
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
57
77
|
def prepared_dependency_files
|
58
78
|
files = []
|
59
79
|
|
60
|
-
|
80
|
+
gemfile_file = gemfile
|
81
|
+
if gemfile_file
|
61
82
|
files << DependencyFile.new(
|
62
|
-
name:
|
63
|
-
content: gemfile_content_for_update_check(
|
64
|
-
directory:
|
83
|
+
name: gemfile_file.name,
|
84
|
+
content: gemfile_content_for_update_check(gemfile_file),
|
85
|
+
directory: gemfile_file.directory
|
65
86
|
)
|
66
87
|
end
|
67
88
|
|
@@ -76,7 +97,7 @@ module Dependabot
|
|
76
97
|
path_gemspecs.each do |file|
|
77
98
|
files << DependencyFile.new(
|
78
99
|
name: file.name,
|
79
|
-
content: sanitize_gemspec_content(file.content),
|
100
|
+
content: sanitize_gemspec_content(T.must(file.content)),
|
80
101
|
directory: file.directory,
|
81
102
|
support_file: file.support_file?
|
82
103
|
)
|
@@ -104,28 +125,37 @@ module Dependabot
|
|
104
125
|
|
105
126
|
private
|
106
127
|
|
128
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
107
129
|
attr_reader :dependency_files
|
130
|
+
sig { returns(Dependabot::Dependency) }
|
108
131
|
attr_reader :dependency
|
132
|
+
sig { returns(T.nilable(String)) }
|
109
133
|
attr_reader :replacement_git_pin
|
134
|
+
sig { returns(T.nilable(String)) }
|
110
135
|
attr_reader :latest_allowable_version
|
111
136
|
|
137
|
+
sig { returns(T::Boolean) }
|
112
138
|
def remove_git_source?
|
113
139
|
@remove_git_source
|
114
140
|
end
|
115
141
|
|
142
|
+
sig { returns(T::Boolean) }
|
116
143
|
def unlock_requirement?
|
117
144
|
@unlock_requirement
|
118
145
|
end
|
119
146
|
|
147
|
+
sig { returns(T::Boolean) }
|
120
148
|
def replace_git_pin?
|
121
149
|
!replacement_git_pin.nil?
|
122
150
|
end
|
123
151
|
|
152
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
124
153
|
def gemfile
|
125
154
|
dependency_files.find { |f| f.name == "Gemfile" } ||
|
126
155
|
dependency_files.find { |f| f.name == "gems.rb" }
|
127
156
|
end
|
128
157
|
|
158
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
129
159
|
def evaled_gemfiles
|
130
160
|
dependency_files
|
131
161
|
.reject { |f| f.name.end_with?(".gemspec") }
|
@@ -137,41 +167,49 @@ module Dependabot
|
|
137
167
|
.reject(&:support_file?)
|
138
168
|
end
|
139
169
|
|
170
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
140
171
|
def lockfile
|
141
172
|
dependency_files.find { |f| f.name == "Gemfile.lock" } ||
|
142
173
|
dependency_files.find { |f| f.name == "gems.locked" }
|
143
174
|
end
|
144
175
|
|
176
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
145
177
|
def specification_files
|
146
178
|
dependency_files.select { |f| f.name.end_with?(".specification") }
|
147
179
|
end
|
148
180
|
|
181
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
149
182
|
def top_level_gemspecs
|
150
183
|
dependency_files
|
151
184
|
.select { |f| f.name.end_with?(".gemspec") }
|
152
185
|
end
|
153
186
|
|
187
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
154
188
|
def ruby_version_file
|
155
189
|
dependency_files.find { |f| f.name == ".ruby-version" }
|
156
190
|
end
|
157
191
|
|
192
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
158
193
|
def tool_versions_file
|
159
194
|
dependency_files.find { |f| f.name == ".tool-versions" }
|
160
195
|
end
|
161
196
|
|
197
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
162
198
|
def path_gemspecs
|
163
199
|
all = dependency_files.select { |f| f.name.end_with?(".gemspec") }
|
164
200
|
all - top_level_gemspecs
|
165
201
|
end
|
166
202
|
|
203
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
167
204
|
def imported_ruby_files
|
168
205
|
dependency_files
|
169
206
|
.select { |f| f.name.end_with?(".rb") }
|
170
207
|
.reject { |f| f.name == "gems.rb" }
|
171
208
|
end
|
172
209
|
|
210
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
173
211
|
def gemfile_content_for_update_check(file)
|
174
|
-
content = file.content
|
212
|
+
content = T.must(file.content)
|
175
213
|
content = replace_gemfile_constraint(content, file.name)
|
176
214
|
content = remove_git_source(content) if remove_git_source?
|
177
215
|
content = replace_git_pin(content) if replace_git_pin?
|
@@ -179,12 +217,14 @@ module Dependabot
|
|
179
217
|
content
|
180
218
|
end
|
181
219
|
|
220
|
+
sig { params(gemspec: Dependabot::DependencyFile).returns(String) }
|
182
221
|
def gemspec_content_for_update_check(gemspec)
|
183
|
-
content = gemspec.content
|
222
|
+
content = T.must(gemspec.content)
|
184
223
|
content = replace_gemspec_constraint(content, gemspec.name)
|
185
224
|
sanitize_gemspec_content(content)
|
186
225
|
end
|
187
226
|
|
227
|
+
sig { params(content: String, filename: String).returns(String) }
|
188
228
|
def replace_gemfile_constraint(content, filename)
|
189
229
|
FileUpdater::RequirementReplacer.new(
|
190
230
|
dependency: dependency,
|
@@ -194,6 +234,7 @@ module Dependabot
|
|
194
234
|
).rewrite(content)
|
195
235
|
end
|
196
236
|
|
237
|
+
sig { params(content: String, filename: String).returns(String) }
|
197
238
|
def replace_gemspec_constraint(content, filename)
|
198
239
|
FileUpdater::RequirementReplacer.new(
|
199
240
|
dependency: dependency,
|
@@ -203,6 +244,7 @@ module Dependabot
|
|
203
244
|
).rewrite(content)
|
204
245
|
end
|
205
246
|
|
247
|
+
sig { params(gemspec_content: String).returns(String) }
|
206
248
|
def sanitize_gemspec_content(gemspec_content)
|
207
249
|
new_version = replacement_version_for_gemspec(gemspec_content)
|
208
250
|
|
@@ -211,6 +253,7 @@ module Dependabot
|
|
211
253
|
.rewrite(gemspec_content)
|
212
254
|
end
|
213
255
|
|
256
|
+
sig { params(filename: String).returns(String) }
|
214
257
|
def updated_version_requirement_string(filename)
|
215
258
|
lower_bound_req = updated_version_req_lower_bound(filename)
|
216
259
|
|
@@ -221,6 +264,7 @@ module Dependabot
|
|
221
264
|
end
|
222
265
|
|
223
266
|
# rubocop:disable Metrics/PerceivedComplexity
|
267
|
+
sig { params(filename: String).returns(String) }
|
224
268
|
def updated_version_req_lower_bound(filename) # rubocop:disable Metrics/CyclomaticComplexity
|
225
269
|
original_req = dependency.requirements
|
226
270
|
.find { |r| r.fetch(:file) == filename }
|
@@ -243,19 +287,22 @@ module Dependabot
|
|
243
287
|
end
|
244
288
|
# rubocop:enable Metrics/PerceivedComplexity
|
245
289
|
|
290
|
+
sig { params(content: String).returns(String) }
|
246
291
|
def remove_git_source(content)
|
247
292
|
FileUpdater::GitSourceRemover.new(
|
248
293
|
dependency: dependency
|
249
294
|
).rewrite(content)
|
250
295
|
end
|
251
296
|
|
297
|
+
sig { params(content: String).returns(String) }
|
252
298
|
def replace_git_pin(content)
|
253
299
|
FileUpdater::GitPinReplacer.new(
|
254
300
|
dependency: dependency,
|
255
|
-
new_pin: replacement_git_pin
|
301
|
+
new_pin: T.must(replacement_git_pin)
|
256
302
|
).rewrite(content)
|
257
303
|
end
|
258
304
|
|
305
|
+
sig { params(gemfile_content: String).returns(String) }
|
259
306
|
def lock_ruby_version(gemfile_content)
|
260
307
|
top_level_gemspecs.each do |gs|
|
261
308
|
gemfile_content = FileUpdater::RubyRequirementSetter
|
@@ -265,11 +312,13 @@ module Dependabot
|
|
265
312
|
gemfile_content
|
266
313
|
end
|
267
314
|
|
315
|
+
sig { params(file: Dependabot::DependencyFile).returns(T::Boolean) }
|
268
316
|
def lock_ruby_version?(file)
|
269
317
|
@lock_ruby_version && file == gemfile
|
270
318
|
end
|
271
319
|
|
272
320
|
# rubocop:disable Metrics/PerceivedComplexity
|
321
|
+
sig { params(gemspec_content: String).returns(String) }
|
273
322
|
def replacement_version_for_gemspec(gemspec_content)
|
274
323
|
return "0.0.1" unless lockfile
|
275
324
|
|
@@ -282,17 +331,18 @@ module Dependabot
|
|
282
331
|
.new(gemspec_content: gemspec_content)
|
283
332
|
.dependency_name
|
284
333
|
|
285
|
-
return gemspec_specs.first&.version || "0.0.1" unless gem_name
|
334
|
+
return gemspec_specs.first&.version&.to_s || "0.0.1" unless gem_name
|
286
335
|
|
287
336
|
spec = gemspec_specs.find { |s| s.name == gem_name }
|
288
|
-
spec&.version || gemspec_specs.first&.version || "0.0.1"
|
337
|
+
spec&.version&.to_s || gemspec_specs.first&.version&.to_s || "0.0.1"
|
289
338
|
end
|
290
339
|
# rubocop:enable Metrics/PerceivedComplexity
|
291
340
|
|
292
341
|
# TODO: Stop sanitizing the lockfile once we have bundler 2 installed
|
342
|
+
sig { returns(String) }
|
293
343
|
def sanitized_lockfile_content
|
294
344
|
re = FileUpdater::LockfileUpdater::LOCKFILE_ENDING
|
295
|
-
lockfile.content.gsub(re, "")
|
345
|
+
T.must(T.must(lockfile).content).gsub(re, "")
|
296
346
|
end
|
297
347
|
end
|
298
348
|
end
|
@@ -186,7 +186,7 @@ module Dependabot
|
|
186
186
|
)
|
187
187
|
end
|
188
188
|
|
189
|
-
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(T::Hash[
|
189
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
190
190
|
def source_for(dependency)
|
191
191
|
dependency.requirements
|
192
192
|
.find { |r| r.fetch(:source) }
|
@@ -1,11 +1,12 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/registry_client"
|
5
7
|
require "dependabot/bundler/native_helpers"
|
6
8
|
require "dependabot/bundler/helpers"
|
7
9
|
require "dependabot/bundler/update_checker/latest_version_finder"
|
8
|
-
require "sorbet-runtime"
|
9
10
|
|
10
11
|
module Dependabot
|
11
12
|
module Bundler
|
@@ -22,20 +23,39 @@ module Dependabot
|
|
22
23
|
GIT = "git"
|
23
24
|
OTHER = "other"
|
24
25
|
|
26
|
+
sig { returns(Dependabot::Dependency) }
|
25
27
|
attr_reader :dependency
|
28
|
+
|
29
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
26
30
|
attr_reader :dependency_files
|
31
|
+
|
32
|
+
sig { override.returns(T.nilable(String)) }
|
27
33
|
attr_reader :repo_contents_path
|
34
|
+
|
35
|
+
sig { override.returns(T::Array[Dependabot::Credential]) }
|
28
36
|
attr_reader :credentials
|
37
|
+
|
38
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
29
39
|
attr_reader :options
|
30
40
|
|
41
|
+
sig do
|
42
|
+
params(
|
43
|
+
dependency: Dependabot::Dependency,
|
44
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
45
|
+
credentials: T::Array[Dependabot::Credential],
|
46
|
+
options: T::Hash[Symbol, T.untyped]
|
47
|
+
).void
|
48
|
+
end
|
31
49
|
def initialize(dependency:,
|
32
50
|
dependency_files:,
|
33
51
|
credentials:,
|
34
52
|
options:)
|
35
53
|
@dependency = dependency
|
36
54
|
@dependency_files = dependency_files
|
55
|
+
@repo_contents_path = T.let(nil, T.nilable(String))
|
37
56
|
@credentials = credentials
|
38
57
|
@options = options
|
58
|
+
@source_type = T.let(nil, T.nilable(String))
|
39
59
|
end
|
40
60
|
|
41
61
|
# The latest version details for the dependency from a registry
|
@@ -58,6 +78,7 @@ module Dependabot
|
|
58
78
|
# The latest version details for the dependency from a git repo
|
59
79
|
#
|
60
80
|
# @return [Hash{Symbol => String}, nil]
|
81
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
61
82
|
def latest_git_version_details
|
62
83
|
return unless git?
|
63
84
|
|
@@ -73,7 +94,7 @@ module Dependabot
|
|
73
94
|
options: options,
|
74
95
|
args: {
|
75
96
|
dir: tmp_dir,
|
76
|
-
gemfile_name: gemfile.name,
|
97
|
+
gemfile_name: T.must(gemfile).name,
|
77
98
|
dependency_name: dependency.name,
|
78
99
|
credentials: credentials,
|
79
100
|
dependency_source_url: source_details[:url],
|
@@ -84,14 +105,16 @@ module Dependabot
|
|
84
105
|
end.transform_keys(&:to_sym)
|
85
106
|
end
|
86
107
|
|
108
|
+
sig { returns(T::Boolean) }
|
87
109
|
def git?
|
88
110
|
source_type == GIT
|
89
111
|
end
|
90
112
|
|
91
113
|
private
|
92
114
|
|
115
|
+
sig { returns(T::Array[Dependabot::Bundler::Version]) }
|
93
116
|
def rubygems_versions
|
94
|
-
@rubygems_versions ||=
|
117
|
+
@rubygems_versions ||= T.let(
|
95
118
|
begin
|
96
119
|
response = Dependabot::RegistryClient.get(
|
97
120
|
url: dependency_rubygems_uri,
|
@@ -100,17 +123,21 @@ module Dependabot
|
|
100
123
|
|
101
124
|
JSON.parse(response.body)
|
102
125
|
.map { |d| Dependabot::Bundler::Version.new(d["number"]) }
|
103
|
-
end
|
126
|
+
end,
|
127
|
+
T.nilable(T::Array[Dependabot::Bundler::Version])
|
128
|
+
)
|
104
129
|
rescue JSON::ParserError, Excon::Error::Timeout
|
105
130
|
@rubygems_versions = []
|
106
131
|
end
|
107
132
|
|
133
|
+
sig { returns(String) }
|
108
134
|
def dependency_rubygems_uri
|
109
135
|
"https://rubygems.org/api/v1/versions/#{dependency.name}.json"
|
110
136
|
end
|
111
137
|
|
138
|
+
sig { returns(T::Array[Dependabot::Bundler::Version]) }
|
112
139
|
def private_registry_versions
|
113
|
-
@private_registry_versions ||=
|
140
|
+
@private_registry_versions ||= T.let(
|
114
141
|
in_a_native_bundler_context do |tmp_dir|
|
115
142
|
NativeHelpers.run_bundler_subprocess(
|
116
143
|
bundler_version: bundler_version,
|
@@ -118,18 +145,21 @@ module Dependabot
|
|
118
145
|
options: options,
|
119
146
|
args: {
|
120
147
|
dir: tmp_dir,
|
121
|
-
gemfile_name: gemfile.name,
|
148
|
+
gemfile_name: T.must(gemfile).name,
|
122
149
|
dependency_name: dependency.name,
|
123
150
|
credentials: credentials
|
124
151
|
}
|
125
152
|
).map do |version_string|
|
126
153
|
Dependabot::Bundler::Version.new(version_string)
|
127
154
|
end
|
128
|
-
end
|
155
|
+
end,
|
156
|
+
T.nilable(T::Array[Dependabot::Bundler::Version])
|
157
|
+
)
|
129
158
|
end
|
130
159
|
|
160
|
+
sig { returns(String) }
|
131
161
|
def source_type
|
132
|
-
return @source_type if
|
162
|
+
return @source_type if @source_type
|
133
163
|
return @source_type = RUBYGEMS unless gemfile
|
134
164
|
|
135
165
|
@source_type = in_a_native_bundler_context do |tmp_dir|
|
@@ -139,7 +169,7 @@ module Dependabot
|
|
139
169
|
options: options,
|
140
170
|
args: {
|
141
171
|
dir: tmp_dir,
|
142
|
-
gemfile_name: gemfile.name,
|
172
|
+
gemfile_name: T.must(gemfile).name,
|
143
173
|
dependency_name: dependency.name,
|
144
174
|
credentials: credentials
|
145
175
|
}
|
@@ -147,18 +177,24 @@ module Dependabot
|
|
147
177
|
end
|
148
178
|
end
|
149
179
|
|
180
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
150
181
|
def gemfile
|
151
182
|
dependency_files.find { |f| f.name == "Gemfile" } ||
|
152
183
|
dependency_files.find { |f| f.name == "gems.rb" }
|
153
184
|
end
|
154
185
|
|
186
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
155
187
|
def lockfile
|
156
188
|
dependency_files.find { |f| f.name == "Gemfile.lock" } ||
|
157
189
|
dependency_files.find { |f| f.name == "gems.locked" }
|
158
190
|
end
|
159
191
|
|
192
|
+
sig { override.returns(String) }
|
160
193
|
def bundler_version
|
161
|
-
@bundler_version ||=
|
194
|
+
@bundler_version ||= T.let(
|
195
|
+
Helpers.bundler_version(lockfile),
|
196
|
+
T.nilable(String)
|
197
|
+
)
|
162
198
|
end
|
163
199
|
end
|
164
200
|
end
|