dependabot-bundler 0.332.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.
@@ -1,6 +1,8 @@
1
- # typed: true
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 = dependency_files
47
- @dependency = dependency
48
- @remove_git_source = remove_git_source
49
- @unlock_requirement = unlock_requirement
50
- @replacement_git_pin = replacement_git_pin
51
- @latest_allowable_version = latest_allowable_version
52
- @lock_ruby_version = lock_ruby_version
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
- if gemfile
80
+ gemfile_file = gemfile
81
+ if gemfile_file
61
82
  files << DependencyFile.new(
62
- name: gemfile.name,
63
- content: gemfile_content_for_update_check(gemfile),
64
- directory: gemfile.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[String, T.untyped])) }
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: true
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 defined? @source_type
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 ||= Helpers.bundler_version(lockfile)
194
+ @bundler_version ||= T.let(
195
+ Helpers.bundler_version(lockfile),
196
+ T.nilable(String)
197
+ )
162
198
  end
163
199
  end
164
200
  end
@@ -122,12 +122,8 @@ module Dependabot
122
122
  @wants_prerelease ||= T.let(
123
123
  begin
124
124
  current_version = dependency.numeric_version
125
- if current_version&.prerelease?
126
- true
127
- else
128
- dependency.requirements.any? do |req|
129
- req[:requirement].match?(/[a-z]/i)
130
- end
125
+ current_version&.prerelease? || dependency.requirements.any? do |req|
126
+ req[:requirement].match?(/[a-z]/i)
131
127
  end
132
128
  end, T.nilable(T::Boolean)
133
129
  )