dependabot-gradle 0.386.0 → 0.387.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e13edb6e52c235438f37abde8da6e16acbf8af7c9ad353b1107d5e3640c452b
4
- data.tar.gz: 3a3e95bec57181355b897de358e3de6bf713b96968cbe8c28cc2465a81aa6599
3
+ metadata.gz: f1925c8db0e74ac32a01d84fbe6eb268c93381e3f8e6d2da4e1750088788c439
4
+ data.tar.gz: b0319754d34aa6a7e9fe6921d0c73a1f69ef8ee39d77be4c9d497f0dabee2c33
5
5
  SHA512:
6
- metadata.gz: ebe25caa251686e54aea6dddddfe590c400e7261eba31772dd43e8dece9a4d037dbfa530f67737521d2f3e7b4c1389e8219bda2aa52a6a6e46c79687d2d62e0b
7
- data.tar.gz: e12a6f556feb7ba1883c1458fc5a1f482be3b60d0a268c1048b86d11470efe262caa70dd324eb7dc9a564b7bc71c0cc941c797ab527b1e1e5a91f4f8bf1c2bc6
6
+ metadata.gz: f63fa431cbd89d827dfd77a9618cda55907ea79311069a0f177266ac93678e21f6e3fda16a8650bf7b7c4a59c12c67c6317d4313552bd21a06a32cb4281bbc55
7
+ data.tar.gz: ff703db39eafc5a298fad53b79a534ebcb4b6518e2937b9714e3c9096409e7382e53572e5a64cada6e251a977a89b3ff6249e9e3f183ef40ea7fc2055dae9f94
@@ -174,9 +174,9 @@ module Dependabot
174
174
  base_credential ? T.must(base_credential["url"]).gsub(%r{/+$}, "") : CENTRAL_REPO_URL
175
175
  end
176
176
 
177
- sig { params(credential: T.untyped).returns(T::Boolean) }
177
+ sig { params(credential: T.any(Dependabot::Credential, T::Hash[String, Object])).returns(T::Boolean) }
178
178
  def replaces_base?(credential)
179
- if credential.respond_to?(:replaces_base?)
179
+ if credential.is_a?(Dependabot::Credential)
180
180
  credential.replaces_base?
181
181
  else
182
182
  credential["replaces-base"] == true
@@ -142,7 +142,7 @@ module Dependabot
142
142
 
143
143
  sig do
144
144
  params(
145
- parsed_toml_file: T::Hash[String, T.untyped],
145
+ parsed_toml_file: T::Hash[String, Object],
146
146
  toml_file: Dependabot::DependencyFile
147
147
  ).returns(DependencySet)
148
148
  end
@@ -156,7 +156,7 @@ module Dependabot
156
156
 
157
157
  sig do
158
158
  params(
159
- parsed_toml_file: T::Hash[String, T.untyped],
159
+ parsed_toml_file: T::Hash[String, Object],
160
160
  toml_file: Dependabot::DependencyFile
161
161
  ).returns(DependencySet)
162
162
  end
@@ -247,9 +247,9 @@ module Dependabot
247
247
  end
248
248
  end
249
249
 
250
- sig { params(file: Dependabot::DependencyFile).returns(T::Hash[String, T.untyped]) }
250
+ sig { params(file: Dependabot::DependencyFile).returns(T::Hash[String, Object]) }
251
251
  def parsed_toml_file(file)
252
- T.cast(TomlRB.parse(file.content), T::Hash[String, T.untyped])
252
+ T.cast(TomlRB.parse(file.content), T::Hash[String, Object])
253
253
  rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
254
254
  raise Dependabot::DependencyFileNotParseable, file.path
255
255
  end
@@ -88,10 +88,10 @@ module Dependabot
88
88
 
89
89
  raise DependencyFileNotResolvable, "No build file found to update the dependency" if buildfile.nil?
90
90
 
91
- metadata = T.let(new_req[:metadata], T.nilable(T::Hash[Symbol, T.untyped]))
92
- if T.let(metadata&.[](:property_name), T.nilable(String))
91
+ metadata = symbol_object_hash(T.cast(new_req[:metadata], T.nilable(Object)))
92
+ if metadata && metadata[:property_name].is_a?(String)
93
93
  files = update_files_for_property_change(files, old_req, new_req)
94
- elsif T.let(metadata&.[](:dependency_set), T.nilable(T::Hash[Symbol, String]))
94
+ elsif metadata && symbol_object_hash(metadata[:dependency_set])
95
95
  files = update_files_for_dep_set_change(files, old_req, new_req)
96
96
  else
97
97
  files[T.must(files.index(buildfile))] = update_version_in_buildfile(dependency, buildfile, old_req, new_req)
@@ -156,47 +156,47 @@ module Dependabot
156
156
  sig do
157
157
  params(
158
158
  buildfiles: T::Array[Dependabot::DependencyFile],
159
- old_req: T::Hash[Symbol, T.untyped],
160
- new_req: T::Hash[Symbol, T.untyped]
159
+ old_req: T::Hash[Symbol, Object],
160
+ new_req: T::Hash[Symbol, Object]
161
161
  )
162
162
  .returns(T::Array[Dependabot::DependencyFile])
163
163
  end
164
164
  def update_files_for_property_change(buildfiles, old_req, new_req)
165
165
  files = buildfiles.dup
166
- metadata = T.let(new_req.fetch(:metadata), T::Hash[Symbol, T.untyped])
167
- property_name = T.let(metadata.fetch(:property_name), String)
168
- file = T.let(new_req.fetch(:file), String)
166
+ metadata = symbol_object_hash_value(new_req, :metadata)
167
+ property_name = string_value(metadata, :property_name)
168
+ file = string_value(new_req, :file)
169
169
  buildfile = T.must(files.find { |f| f.name == file })
170
170
 
171
171
  PropertyValueUpdater.new(dependency_files: files)
172
172
  .update_files_for_property_change(
173
173
  property_name: property_name,
174
174
  callsite_buildfile: buildfile,
175
- previous_value: T.let(old_req.fetch(:requirement), String),
176
- updated_value: T.let(new_req.fetch(:requirement), String)
175
+ previous_value: string_value(old_req, :requirement),
176
+ updated_value: string_value(new_req, :requirement)
177
177
  )
178
178
  end
179
179
 
180
180
  sig do
181
181
  params(
182
182
  buildfiles: T::Array[Dependabot::DependencyFile],
183
- old_req: T::Hash[Symbol, T.untyped],
184
- new_req: T::Hash[Symbol, T.untyped]
183
+ old_req: T::Hash[Symbol, Object],
184
+ new_req: T::Hash[Symbol, Object]
185
185
  )
186
186
  .returns(T::Array[Dependabot::DependencyFile])
187
187
  end
188
188
  def update_files_for_dep_set_change(buildfiles, old_req, new_req)
189
189
  files = buildfiles.dup
190
- metadata = T.let(new_req.fetch(:metadata), T::Hash[Symbol, T.untyped])
191
- dependency_set = T.let(metadata.fetch(:dependency_set), T::Hash[Symbol, String])
192
- buildfile = T.must(files.find { |f| f.name == T.let(new_req.fetch(:file), String) })
190
+ metadata = symbol_object_hash_value(new_req, :metadata)
191
+ dependency_set = symbol_string_hash_value(metadata, :dependency_set)
192
+ buildfile = T.must(files.find { |f| f.name == string_value(new_req, :file) })
193
193
 
194
194
  DependencySetUpdater.new(dependency_files: files)
195
195
  .update_files_for_dep_set_change(
196
196
  dependency_set: dependency_set,
197
197
  buildfile: buildfile,
198
- previous_requirement: T.let(old_req.fetch(:requirement), String),
199
- updated_requirement: T.let(new_req.fetch(:requirement), String)
198
+ previous_requirement: string_value(old_req, :requirement),
199
+ updated_requirement: string_value(new_req, :requirement)
200
200
  )
201
201
  end
202
202
 
@@ -204,8 +204,8 @@ module Dependabot
204
204
  params(
205
205
  dependency: Dependabot::Dependency,
206
206
  buildfile: Dependabot::DependencyFile,
207
- previous_req: T::Hash[Symbol, T.untyped],
208
- requirement: T::Hash[Symbol, T.untyped]
207
+ previous_req: T::Hash[Symbol, Object],
208
+ requirement: T::Hash[Symbol, Object]
209
209
  )
210
210
  .returns(Dependabot::DependencyFile)
211
211
  end
@@ -235,13 +235,14 @@ module Dependabot
235
235
  sig do
236
236
  params(
237
237
  dependency: Dependabot::Dependency,
238
- requirement: T::Hash[Symbol, T.untyped]
238
+ requirement: T::Hash[Symbol, Object]
239
239
  ).returns(T::Array[String])
240
240
  end
241
241
  def original_buildfile_declarations(dependency, requirement)
242
242
  # This implementation is limited to declarations that appear on a
243
243
  # single line.
244
- buildfile = T.must(buildfiles.find { |f| f.name == T.let(requirement.fetch(:file), String) })
244
+ file = string_value(requirement, :file)
245
+ buildfile = T.must(buildfiles.find { |f| f.name == file })
245
246
 
246
247
  T.must(buildfile.content).lines.select do |line|
247
248
  line = evaluate_properties(line, buildfile)
@@ -250,11 +251,14 @@ module Dependabot
250
251
  if dependency.name.include?(":")
251
252
  dep_parts = dependency.name.split(":")
252
253
  next false unless line.include?(T.must(dep_parts.first)) || line.include?(T.must(dep_parts.last))
253
- elsif T.let(requirement.fetch(:file), String).end_with?(".properties")
254
- property = T.let(requirement, T::Hash[Symbol, T.nilable(T::Hash[Symbol, T.nilable(String)])])
255
- .dig(:source, :property)
256
- next false unless !property.nil? && line.start_with?(property)
257
- elsif T.let(requirement.fetch(:file), String).end_with?(".toml")
254
+ elsif file.end_with?(".properties")
255
+ source = requirement[:source]
256
+ property = T.let(nil, T.nilable(String))
257
+ source_hash = symbol_object_hash(source)
258
+ source_property = source_hash&.[](:property)
259
+ property = source_property if source_property.is_a?(String)
260
+ next false unless property && line.start_with?(property)
261
+ elsif file.end_with?(".toml")
258
262
  next false unless line.include?(dependency.name)
259
263
  else
260
264
  name_regex_value = /['"]#{Regexp.quote(dependency.name)}['"]/
@@ -262,7 +266,7 @@ module Dependabot
262
266
  next false unless line.match?(name_regex)
263
267
  end
264
268
 
265
- line.include?(T.let(requirement.fetch(:requirement), String))
269
+ line.include?(string_value(requirement, :requirement))
266
270
  end
267
271
  end
268
272
  # rubocop:enable Metrics/AbcSize
@@ -297,17 +301,57 @@ module Dependabot
297
301
  sig do
298
302
  params(
299
303
  original_buildfile_declaration: String,
300
- previous_req: T::Hash[Symbol, T.untyped],
301
- requirement: T::Hash[Symbol, T.untyped]
304
+ previous_req: T::Hash[Symbol, Object],
305
+ requirement: T::Hash[Symbol, Object]
302
306
  ).returns(String)
303
307
  end
304
308
  def updated_buildfile_declaration(original_buildfile_declaration, previous_req, requirement)
305
- original_req_string = T.let(previous_req.fetch(:requirement), String)
306
- new_req_string = T.let(requirement.fetch(:requirement), String)
309
+ original_req_string = string_value(previous_req, :requirement)
310
+ new_req_string = string_value(requirement, :requirement)
307
311
 
308
312
  original_buildfile_declaration.gsub(original_req_string, new_req_string)
309
313
  end
310
314
 
315
+ sig { params(hash: T::Hash[Symbol, Object], key: Symbol).returns(String) }
316
+ def string_value(hash, key)
317
+ value = hash.fetch(key)
318
+ raise TypeError, "Expected #{key} to be a String" unless value.is_a?(String)
319
+
320
+ value
321
+ end
322
+
323
+ sig { params(hash: T::Hash[Symbol, Object], key: Symbol).returns(T::Hash[Symbol, Object]) }
324
+ def symbol_object_hash_value(hash, key)
325
+ value = hash.fetch(key)
326
+ raise TypeError, "Expected #{key} to be a Hash" unless value.is_a?(Hash)
327
+
328
+ value
329
+ end
330
+
331
+ sig { params(hash: T::Hash[Symbol, Object], key: Symbol).returns(T::Hash[Symbol, String]) }
332
+ def symbol_string_hash_value(hash, key)
333
+ value = hash.fetch(key)
334
+ raise TypeError, "Expected #{key} to be a Hash" unless value.is_a?(Hash)
335
+
336
+ result = T.let({}, T::Hash[Symbol, String])
337
+ value.each_pair do |hash_key_object, hash_value_object|
338
+ hash_key = T.cast(hash_key_object, T.nilable(Object))
339
+ hash_value = T.cast(hash_value_object, T.nilable(Object))
340
+ raise TypeError, "Expected #{key} keys and values to be Symbols and Strings" unless hash_key.is_a?(Symbol) &&
341
+ hash_value.is_a?(String)
342
+
343
+ result[hash_key] = hash_value
344
+ end
345
+ result
346
+ end
347
+
348
+ sig { params(value: T.nilable(Object)).returns(T.nilable(T::Hash[Symbol, Object])) }
349
+ def symbol_object_hash(value)
350
+ return unless value.is_a?(Hash)
351
+
352
+ value
353
+ end
354
+
311
355
  sig { returns(T::Array[Dependabot::DependencyFile]) }
312
356
  def buildfiles
313
357
  @buildfiles ||= T.let(dependency_files.reject(&:support_file?), T.nilable(T::Array[Dependabot::DependencyFile]))
@@ -11,10 +11,10 @@ module Dependabot
11
11
  class DistributionsFetcher
12
12
  extend T::Sig
13
13
 
14
- @available_versions = T.let([], T::Array[T::Hash[String, T.untyped]])
14
+ @available_versions = T.let([], T::Array[T::Hash[Symbol, Object]])
15
15
  @distributions_checksums = T.let({}, T::Hash[String, T::Array[String]])
16
16
 
17
- sig { returns(T.any(T::Array[T::Hash[String, T.untyped]], T::Array[T::Hash[Symbol, T.untyped]])) }
17
+ sig { returns(T::Array[T::Hash[Symbol, Object]]) }
18
18
  def self.available_versions
19
19
  return @available_versions if @available_versions.any?
20
20
 
@@ -24,7 +24,7 @@ module Dependabot
24
24
  T.let(response.body, String),
25
25
  symbolize_names: true
26
26
  ),
27
- T::Array[T::Hash[Symbol, T.untyped]]
27
+ T::Array[T::Hash[Symbol, Object]]
28
28
  )
29
29
  @available_versions +=
30
30
  versions
@@ -38,14 +38,17 @@ module Dependabot
38
38
  end
39
39
  end
40
40
 
41
- sig { params(version: T::Hash[Symbol, T.untyped]).returns(T::Boolean) }
41
+ sig { params(version: T::Hash[Symbol, Object]).returns(T::Boolean) }
42
42
  def self.release_version?(version:)
43
- Gradle::Version.correct?(T.let(version[:version], String)) &&
44
- T.let(version[:broken], T::Boolean) == false &&
45
- T.let(version[:snapshot], T::Boolean) == false &&
46
- T.let(version[:rcFor], String) == "" &&
47
- T.let(version[:milestoneFor], String) == "" &&
48
- /.*-(rc|milestone)-.*/.match?(T.let(version[:version], String)) == false
43
+ version_number = version[:version]
44
+ return false unless version_number.is_a?(String)
45
+
46
+ Gradle::Version.correct?(version_number) &&
47
+ version[:broken] == false &&
48
+ version[:snapshot] == false &&
49
+ version[:rcFor] == "" &&
50
+ version[:milestoneFor] == "" &&
51
+ /.*-(rc|milestone)-.*/.match?(version_number) == false
49
52
  end
50
53
 
51
54
  sig { params(distribution_url: String).returns(T.nilable(T::Array[String])) }
@@ -28,7 +28,7 @@ module Dependabot
28
28
  sig do
29
29
  params(
30
30
  url: String,
31
- headers: T::Hash[T.any(String, Symbol), T.untyped]
31
+ headers: T::Hash[T.any(String, Symbol), Object]
32
32
  ).returns(Excon::Response)
33
33
  end
34
34
  def self.get(url:, headers:)
@@ -45,8 +45,29 @@ module Dependabot
45
45
  end
46
46
  end
47
47
 
48
+ module RepositoryDetailsHelpers
49
+ extend T::Sig
50
+
51
+ sig { params(hash: T::Hash[String, Object], key: String).returns(String) }
52
+ def string_key_value(hash, key)
53
+ value = hash.fetch(key)
54
+ return value if value.is_a?(String)
55
+
56
+ Kernel.raise TypeError, "Expected #{key} to be a String"
57
+ end
58
+
59
+ sig { params(hash: T::Hash[String, Object]).returns(T::Hash[T.any(String, Symbol), Object]) }
60
+ def auth_headers_value(hash)
61
+ value = hash.fetch("auth_headers")
62
+ return value if value.is_a?(Hash)
63
+
64
+ Kernel.raise TypeError, "Expected auth_headers to be a Hash"
65
+ end
66
+ end
67
+
48
68
  class PackageDetailsFetcher
49
69
  extend T::Sig
70
+ include RepositoryDetailsHelpers
50
71
 
51
72
  CENTRAL_REPO_URL = "https://repo.maven.apache.org/maven2"
52
73
  KOTLIN_PLUGIN_REPO_PREFIX = "org.jetbrains.kotlin"
@@ -66,10 +87,10 @@ module Dependabot
66
87
  @credentials = credentials
67
88
  @forbidden_urls = forbidden_urls
68
89
  @cooldown_options = T.let(cooldown_options, T.nilable(Dependabot::Package::ReleaseCooldownOptions))
69
- @repositories = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
70
- @google_version_details = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
71
- @dependency_repository_details = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
72
- @release_details = T.let(nil, T.nilable(T::Hash[String, T::Hash[Symbol, T.untyped]]))
90
+ @repositories = T.let(nil, T.nilable(T::Array[T::Hash[String, Object]]))
91
+ @google_version_details = T.let(nil, T.nilable(Nokogiri::XML::Document))
92
+ @dependency_repository_details = T.let(nil, T.nilable(T::Array[T::Hash[String, Object]]))
93
+ @release_details = T.let(nil, T.nilable(T::Hash[String, T::Hash[Symbol, Object]]))
73
94
  @version_release_date_fallback_fetcher = T.let(nil, T.nilable(VersionReleaseDateFallbackFetcher))
74
95
  end
75
96
 
@@ -86,9 +107,9 @@ module Dependabot
86
107
  attr_reader :forbidden_urls
87
108
 
88
109
  # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
89
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
110
+ sig { returns(T::Array[T::Hash[Symbol, Object]]) }
90
111
  def fetch_available_versions
91
- package_releases = T.let([], T::Array[T::Hash[String, T.untyped]])
112
+ package_releases = T.let([], T::Array[T::Hash[Symbol, Object]])
92
113
  version_details =
93
114
  repositories.map do |repository_details|
94
115
  url = repository_details.fetch("url")
@@ -125,6 +146,7 @@ module Dependabot
125
146
  return release if release.released_at
126
147
 
127
148
  release_date = release_details[release.version.to_s]&.fetch(:release_date, nil)
149
+ release_date = nil unless release_date.is_a?(Time)
128
150
  hydrated_release = build_release_with_date(release, release_date)
129
151
 
130
152
  return hydrated_release if hydrated_release.released_at || !plugin?
@@ -132,7 +154,7 @@ module Dependabot
132
154
  build_release_with_date(hydrated_release, version_release_date_fallback(release.version.to_s))
133
155
  end
134
156
 
135
- sig { returns(T::Hash[String, T::Hash[Symbol, T.untyped]]) }
157
+ sig { returns(T::Hash[String, T::Hash[Symbol, Object]]) }
136
158
  def release_details
137
159
  @release_details ||= begin
138
160
  extractor = ReleaseDateExtractor.new(dependency_name: dependency.name, version_class: version_class)
@@ -180,7 +202,7 @@ module Dependabot
180
202
  )
181
203
  end
182
204
 
183
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
205
+ sig { returns(T::Array[T::Hash[String, Object]]) }
184
206
  def repositories
185
207
  return @repositories if @repositories
186
208
 
@@ -200,11 +222,12 @@ module Dependabot
200
222
  end
201
223
  end
202
224
 
203
- sig { returns(T.nilable(T::Array[T::Hash[String, T.untyped]])) }
225
+ sig { returns(T.nilable(T::Array[T::Hash[Symbol, Object]])) }
204
226
  def distribution_version_details
205
227
  DistributionsFetcher.available_versions.map do |info|
228
+ build_time = info[:build_time]
206
229
  release_date = begin
207
- Time.parse(info[:build_time])
230
+ Time.parse(build_time) if build_time.is_a?(String)
208
231
  rescue StandardError
209
232
  nil
210
233
  end
@@ -219,7 +242,7 @@ module Dependabot
219
242
  nil
220
243
  end
221
244
 
222
- sig { returns(T.nilable(T::Array[T::Hash[String, T.untyped]])) }
245
+ sig { returns(T.nilable(T::Array[T::Hash[Symbol, Object]])) }
223
246
  def google_version_details
224
247
  url = Gradle::FileParser::RepositoriesFinder::GOOGLE_MAVEN_REPO
225
248
  group_id, artifact_id = group_and_artifact_ids
@@ -247,17 +270,18 @@ module Dependabot
247
270
  nil
248
271
  end
249
272
 
250
- sig { params(repository_details: T::Hash[T.untyped, T.untyped]).returns(T.untyped) }
273
+ sig { params(repository_details: T::Hash[String, Object]).returns(Nokogiri::XML::Document) }
251
274
  def dependency_metadata(repository_details)
252
- @dependency_metadata ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped]))
275
+ @dependency_metadata ||= T.let({}, T.nilable(T::Hash[Integer, Nokogiri::XML::Document]))
253
276
  @dependency_metadata[repository_details.hash] ||=
254
277
  begin
278
+ repository_url = string_key_value(repository_details, "url")
255
279
  response = EofRetry.get(
256
- url: dependency_metadata_url(repository_details.fetch("url")),
257
- headers: repository_details.fetch("auth_headers")
280
+ url: dependency_metadata_url(repository_url),
281
+ headers: auth_headers_value(repository_details)
258
282
  )
259
283
 
260
- check_response(response, repository_details.fetch("url"))
284
+ check_response(response, repository_url)
261
285
  Nokogiri::XML(response.body)
262
286
  rescue URI::InvalidURIError
263
287
  Nokogiri::XML("")
@@ -269,17 +293,18 @@ module Dependabot
269
293
  end
270
294
  end
271
295
 
272
- sig { params(repository_details: T::Hash[T.untyped, T.untyped]).returns(T.untyped) }
296
+ sig { params(repository_details: T::Hash[String, Object]).returns(Nokogiri::HTML::Document) }
273
297
  def release_info_metadata(repository_details)
274
- @release_info_metadata ||= T.let({}, T.nilable(T::Hash[Integer, T.untyped]))
298
+ @release_info_metadata ||= T.let({}, T.nilable(T::Hash[Integer, Nokogiri::HTML::Document]))
275
299
  @release_info_metadata[repository_details.hash] ||=
276
300
  begin
301
+ repository_url = string_key_value(repository_details, "url")
277
302
  response = EofRetry.get(
278
- url: dependency_metadata_url(repository_details.fetch("url")).gsub("maven-metadata.xml", ""),
279
- headers: repository_details.fetch("auth_headers")
303
+ url: dependency_metadata_url(repository_url).gsub("maven-metadata.xml", ""),
304
+ headers: auth_headers_value(repository_details)
280
305
  )
281
306
 
282
- check_response(response, repository_details.fetch("url"))
307
+ check_response(response, repository_url)
283
308
  Nokogiri::HTML(response.body)
284
309
  rescue URI::InvalidURIError
285
310
  Nokogiri::HTML("")
@@ -291,12 +316,12 @@ module Dependabot
291
316
  end
292
317
  end
293
318
 
294
- sig { returns(T::Array[T::Hash[String, String]]) }
319
+ sig { returns(T::Array[T::Hash[String, Object]]) }
295
320
  def repository_urls
296
321
  plugin? ? plugin_repository_details : dependency_repository_details
297
322
  end
298
323
 
299
- sig { params(response: T.untyped, repository_url: T.untyped).returns(T.nilable(T::Array[T.untyped])) }
324
+ sig { params(response: Excon::Response, repository_url: String).void }
300
325
  def check_response(response, repository_url)
301
326
  return unless response.status == 401 || response.status == 403
302
327
  return if T.must(@forbidden_urls).include?(repository_url)
@@ -317,7 +342,7 @@ module Dependabot
317
342
  end
318
343
  end
319
344
 
320
- sig { returns(T::Array[T::Hash[String, String]]) }
345
+ sig { returns(T::Array[T::Hash[String, Object]]) }
321
346
  def dependency_repository_details
322
347
  requirement_files =
323
348
  dependency.requirements
@@ -337,18 +362,18 @@ module Dependabot
337
362
  end.uniq
338
363
  end
339
364
 
340
- sig { returns(T::Array[T::Hash[String, String]]) }
365
+ sig { returns(T::Array[T::Hash[String, Object]]) }
341
366
  def plugin_repository_details
342
367
  [{ "url" => Gradle::FileParser::RepositoriesFinder::GRADLE_PLUGINS_REPO, "auth_headers" => {} }] +
343
368
  dependency_repository_details
344
369
  end
345
370
 
346
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
371
+ sig { returns(T::Array[T::Hash[String, Object]]) }
347
372
  def distribution_repository_details
348
373
  [{ "url" => Gradle::Distributions::DISTRIBUTION_REPOSITORY_URL, "auth_headers" => {} }]
349
374
  end
350
375
 
351
- sig { params(comparison_version: T.untyped).returns(T::Boolean) }
376
+ sig { params(comparison_version: Object).returns(T::Boolean) }
352
377
  def matches_dependency_version_type?(comparison_version)
353
378
  return true unless dependency.version
354
379
 
@@ -375,7 +400,7 @@ module Dependabot
375
400
  dependency_files.find { |f| f.name == filename }
376
401
  end
377
402
 
378
- sig { params(repository_url: T.untyped).returns(String) }
403
+ sig { params(repository_url: String).returns(String) }
379
404
  def dependency_metadata_url(repository_url)
380
405
  group_id, artifact_id = group_and_artifact_ids
381
406
  group_id = "#{Dependabot::Gradle::MetadataFinder::KOTLIN_PLUGIN_REPO_PREFIX}.#{group_id}" if kotlin_plugin?
@@ -32,17 +32,17 @@ module Dependabot
32
32
  # This supports mirrors/proxies of both Maven Central and Gradle Plugin Portal.
33
33
  sig do
34
34
  params(
35
- repositories: T::Array[T::Hash[String, T.untyped]],
35
+ repositories: T::Array[T::Hash[String, Object]],
36
36
  dependency_metadata_fetcher: T.proc.params(
37
- repo: T::Hash[String, T.untyped]
37
+ repo: T::Hash[String, Object]
38
38
  ).returns(Nokogiri::XML::Document),
39
39
  release_info_metadata_fetcher: T.proc.params(
40
- repo: T::Hash[String, T.untyped]
40
+ repo: T::Hash[String, Object]
41
41
  ).returns(Nokogiri::HTML::Document)
42
- ).returns(T::Hash[String, T::Hash[Symbol, T.untyped]])
42
+ ).returns(T::Hash[String, T::Hash[Symbol, Object]])
43
43
  end
44
44
  def extract(repositories:, dependency_metadata_fetcher:, release_info_metadata_fetcher:)
45
- release_date_info = T.let({}, T::Hash[String, T::Hash[Symbol, T.untyped]])
45
+ release_date_info = T.let({}, T::Hash[String, T::Hash[Symbol, Object]])
46
46
 
47
47
  begin
48
48
  parse_repository_release_dates(
@@ -72,13 +72,13 @@ module Dependabot
72
72
 
73
73
  sig do
74
74
  params(
75
- repositories: T::Array[T::Hash[String, T.untyped]],
76
- release_date_info: T::Hash[String, T::Hash[Symbol, T.untyped]],
75
+ repositories: T::Array[T::Hash[String, Object]],
76
+ release_date_info: T::Hash[String, T::Hash[Symbol, Object]],
77
77
  dependency_metadata_fetcher: T.proc.params(
78
- repo: T::Hash[String, T.untyped]
78
+ repo: T::Hash[String, Object]
79
79
  ).returns(Nokogiri::XML::Document),
80
80
  release_info_metadata_fetcher: T.proc.params(
81
- repo: T::Hash[String, T.untyped]
81
+ repo: T::Hash[String, Object]
82
82
  ).returns(Nokogiri::HTML::Document)
83
83
  ).void
84
84
  end
@@ -106,10 +106,10 @@ module Dependabot
106
106
  # Parses Maven-style HTML directory listings to extract release dates.
107
107
  sig do
108
108
  params(
109
- repository_details: T::Hash[String, T.untyped],
110
- release_date_info: T::Hash[String, T::Hash[Symbol, T.untyped]],
109
+ repository_details: T::Hash[String, Object],
110
+ release_date_info: T::Hash[String, T::Hash[Symbol, Object]],
111
111
  metadata_fetcher: T.proc.params(
112
- repo: T::Hash[String, T.untyped]
112
+ repo: T::Hash[String, Object]
113
113
  ).returns(Nokogiri::HTML::Document)
114
114
  ).void
115
115
  end
@@ -134,10 +134,10 @@ module Dependabot
134
134
  # Parses Gradle Plugin Portal maven-metadata.xml for release dates.
135
135
  sig do
136
136
  params(
137
- repository_details: T::Hash[String, T.untyped],
138
- release_date_info: T::Hash[String, T::Hash[Symbol, T.untyped]],
137
+ repository_details: T::Hash[String, Object],
138
+ release_date_info: T::Hash[String, T::Hash[Symbol, Object]],
139
139
  metadata_fetcher: T.proc.params(
140
- repo: T::Hash[String, T.untyped]
140
+ repo: T::Hash[String, Object]
141
141
  ).returns(Nokogiri::XML::Document)
142
142
  ).void
143
143
  end
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "dependabot/logger"
@@ -14,7 +14,7 @@ module Dependabot
14
14
  sig do
15
15
  params(
16
16
  dependency_name: String,
17
- repositories: T::Array[T::Hash[String, T.untyped]],
17
+ repositories: T::Array[T::Hash[String, Object]],
18
18
  forbidden_urls: T::Array[String],
19
19
  pom_url_builder: T.proc.params(repository_url: String, version: String).returns(String)
20
20
  ).void
@@ -35,10 +35,14 @@ module Dependabot
35
35
 
36
36
  ordered_repositories.each do |repo|
37
37
  repository_url = repo.fetch("url")
38
+ next unless repository_url.is_a?(String)
39
+
38
40
  pom_url = @pom_url_builder.call(repository_url, version)
39
41
 
40
42
  begin
41
- response = Dependabot::RegistryClient.head(url: pom_url, headers: repo["auth_headers"])
43
+ headers = repo["auth_headers"]
44
+ headers = {} unless headers.is_a?(Hash)
45
+ response = Dependabot::RegistryClient.head(url: pom_url, headers: headers)
42
46
  last_modified = response.headers["Last-Modified"] || response.headers["last-modified"]
43
47
  next unless last_modified
44
48
 
@@ -63,10 +67,10 @@ module Dependabot
63
67
 
64
68
  private
65
69
 
66
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
70
+ sig { returns(T::Array[T::Hash[String, Object]]) }
67
71
  def ordered_repositories
68
72
  candidates = @repositories.reject do |repo|
69
- @forbidden_urls.include?(repo.fetch("url"))
73
+ @forbidden_urls.include?(repo.fetch("url").to_s)
70
74
  end
71
75
 
72
76
  preferred, remaining = candidates.partition do |repo|
@@ -14,13 +14,12 @@ module Dependabot
14
14
  require_relative "version_finder"
15
15
  require_relative "requirements_updater"
16
16
 
17
- # rubocop:disable Metrics/AbcSize
18
17
  sig do
19
18
  params(
20
19
  dependency: Dependabot::Dependency,
21
20
  dependency_files: T::Array[Dependabot::DependencyFile],
22
21
  credentials: T::Array[Dependabot::Credential],
23
- target_version_details: T.nilable(T::Hash[Symbol, Dependabot::Gradle::Version]),
22
+ target_version_details: T.nilable(T::Hash[Symbol, Object]),
24
23
  ignored_versions: T::Array[String],
25
24
  raise_on_ignored: T::Boolean
26
25
  ).void
@@ -37,11 +36,11 @@ module Dependabot
37
36
  @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
38
37
  @credentials = T.let(credentials, T::Array[Dependabot::Credential])
39
38
  @target_version = T.let(
40
- target_version_details&.fetch(:version),
39
+ version_from_details(target_version_details),
41
40
  T.nilable(Dependabot::Gradle::Version)
42
41
  )
43
42
  @source_url = T.let(
44
- T.cast(target_version_details&.fetch(:source_url), T.nilable(String)),
43
+ source_url_from_details(target_version_details),
45
44
  T.nilable(String)
46
45
  )
47
46
  @ignored_versions = T.let(ignored_versions, T::Array[String])
@@ -51,10 +50,8 @@ module Dependabot
51
50
  @dependencies_to_update = T.let(nil, T.nilable(T::Array[Dependabot::Dependency]))
52
51
  @property_name = T.let(nil, T.nilable(String))
53
52
  @dependency_set = T.let(nil, T.nilable(T::Hash[Symbol, String]))
54
- @updated_requirements = T.let({}, T::Hash[String, T::Array[T::Hash[Symbol, T.untyped]]])
53
+ @updated_requirements = T.let({}, T::Hash[String, T::Array[T::Hash[Symbol, Object]]])
55
54
  end
56
- # rubocop:enable Metrics/AbcSize
57
-
58
55
  sig { returns(T::Boolean) }
59
56
  def update_possible?
60
57
  return false unless target_version
@@ -93,6 +90,18 @@ module Dependabot
93
90
 
94
91
  private
95
92
 
93
+ sig { params(details: T.nilable(T::Hash[Symbol, Object])).returns(T.nilable(Dependabot::Gradle::Version)) }
94
+ def version_from_details(details)
95
+ version = details&.fetch(:version, nil)
96
+ version if version.is_a?(Dependabot::Gradle::Version)
97
+ end
98
+
99
+ sig { params(details: T.nilable(T::Hash[Symbol, Object])).returns(T.nilable(String)) }
100
+ def source_url_from_details(details)
101
+ source_url = details&.fetch(:source_url, nil)
102
+ source_url if source_url.is_a?(String)
103
+ end
104
+
96
105
  sig { returns(Dependabot::Dependency) }
97
106
  attr_reader :dependency
98
107
 
@@ -142,7 +151,7 @@ module Dependabot
142
151
  &.dig(:metadata, :dependency_set)
143
152
  end
144
153
 
145
- sig { params(dep: Dependabot::Dependency).returns(T::Array[T::Hash[Symbol, T.untyped]]) }
154
+ sig { params(dep: Dependabot::Dependency).returns(T::Array[T::Hash[Symbol, Object]]) }
146
155
  def updated_requirements(dep)
147
156
  @updated_requirements[dep.name] ||=
148
157
  RequirementsUpdater.new(
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "nokogiri"
@@ -49,7 +49,7 @@ module Dependabot
49
49
  @dependency_files = dependency_files
50
50
  @credentials = credentials
51
51
  @raise_on_ignored = raise_on_ignored
52
- @forbidden_urls = T.let([], T::Array[T.untyped])
52
+ @forbidden_urls = T.let([], T::Array[String])
53
53
  @ignored_versions = ignored_versions
54
54
 
55
55
  super(
@@ -64,7 +64,7 @@ module Dependabot
64
64
  )
65
65
  end
66
66
 
67
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
67
+ sig { returns(T.nilable(T::Hash[Symbol, Object])) }
68
68
  def latest_version_details
69
69
  possible_versions = package_release(versions)
70
70
 
@@ -92,7 +92,7 @@ module Dependabot
92
92
  true
93
93
  end
94
94
 
95
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
95
+ sig { returns(T.nilable(T::Hash[Symbol, Object])) }
96
96
  def lowest_security_fix_version_details
97
97
  possible_versions = package_release(versions)
98
98
 
@@ -118,7 +118,7 @@ module Dependabot
118
118
  source_url: url }
119
119
  end
120
120
 
121
- sig { returns(T.any(T::Array[T::Hash[String, T.untyped]], T::Array[T::Hash[Symbol, T.untyped]])) }
121
+ sig { returns(T::Array[T::Hash[Symbol, Object]]) }
122
122
  def versions
123
123
  Package::PackageDetailsFetcher.new(
124
124
  dependency: dependency,
@@ -134,10 +134,10 @@ module Dependabot
134
134
  sig { returns(Dependabot::Dependency) }
135
135
  attr_reader :dependency
136
136
 
137
- sig { returns(T::Array[T.untyped]) }
137
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
138
138
  attr_reader :dependency_files
139
139
 
140
- sig { returns(T::Array[T.untyped]) }
140
+ sig { returns(T::Array[Dependabot::Credential]) }
141
141
  attr_reader :credentials
142
142
 
143
143
  sig { returns(T.nilable(T::Array[String])) }
@@ -149,15 +149,16 @@ module Dependabot
149
149
  sig { returns(T::Array[Dependabot::SecurityAdvisory]) }
150
150
  attr_reader :security_advisories
151
151
 
152
- sig { params(version: T::Array[T.untyped]).returns(T::Array[Dependabot::Package::PackageRelease]) }
152
+ sig { params(version: T::Array[T::Hash[Symbol, Object]]).returns(T::Array[Dependabot::Package::PackageRelease]) }
153
153
  def package_release(version)
154
154
  package_releases = []
155
155
 
156
156
  version.map do |info|
157
+ released_at = info[:released_at]
157
158
  package_releases << Dependabot::Package::PackageRelease.new(
158
- version: info[:version],
159
- released_at: info[:released_at],
160
- url: info[:source_url]
159
+ version: Dependabot::Gradle::Version.new(info[:version].to_s),
160
+ released_at: released_at.is_a?(Time) ? released_at : nil,
161
+ url: info[:source_url]&.to_s
161
162
  )
162
163
  end
163
164
  package_releases
@@ -177,7 +178,10 @@ module Dependabot
177
178
  )
178
179
  end
179
180
 
180
- sig { params(possible_versions: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
181
+ sig do
182
+ params(possible_versions: T::Array[Dependabot::Package::PackageRelease])
183
+ .returns(T::Array[Dependabot::Package::PackageRelease])
184
+ end
181
185
  def filter_ignored_versions(possible_versions)
182
186
  filtered = possible_versions
183
187
 
@@ -19,7 +19,7 @@ module Dependabot
19
19
  def latest_version
20
20
  return if git_dependency?
21
21
 
22
- latest_version_details&.fetch(:version)
22
+ version_from_details(latest_version_details)
23
23
  end
24
24
 
25
25
  sig { override.returns(T.nilable(Dependabot::Version)) }
@@ -38,7 +38,7 @@ module Dependabot
38
38
 
39
39
  sig { override.returns(T.nilable(Dependabot::Version)) }
40
40
  def lowest_security_fix_version
41
- lowest_security_fix_version_details&.fetch(:version)
41
+ version_from_details(lowest_security_fix_version_details)
42
42
  end
43
43
 
44
44
  sig { override.returns(T.nilable(Dependabot::Version)) }
@@ -66,12 +66,12 @@ module Dependabot
66
66
  def updated_requirements
67
67
  property_names =
68
68
  declarations_using_a_property
69
- .map { |req| req.dig(:metadata, :property_name) }
69
+ .filter_map { |req| property_name_from_requirement(req) }
70
70
 
71
71
  RequirementsUpdater.new(
72
72
  requirements: dependency.requirements,
73
73
  latest_version: preferred_resolvable_version&.to_s,
74
- source_url: preferred_version_details&.fetch(:source_url),
74
+ source_url: source_url_from_details(preferred_version_details),
75
75
  properties_to_update: property_names
76
76
  ).updated_requirements
77
77
  end
@@ -114,26 +114,26 @@ module Dependabot
114
114
  super
115
115
  end
116
116
 
117
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
117
+ sig { returns(T.nilable(T::Hash[Symbol, Object])) }
118
118
  def preferred_version_details
119
119
  return lowest_security_fix_version_details if vulnerable?
120
120
 
121
121
  latest_version_details
122
122
  end
123
123
 
124
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
124
+ sig { returns(T.nilable(T::Hash[Symbol, Object])) }
125
125
  def latest_version_details
126
126
  @latest_version_details ||= T.let(
127
127
  version_finder.latest_version_details,
128
- T.nilable(T::Hash[Symbol, T.untyped])
128
+ T.nilable(T::Hash[Symbol, Object])
129
129
  )
130
130
  end
131
131
 
132
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
132
+ sig { returns(T.nilable(T::Hash[Symbol, Object])) }
133
133
  def lowest_security_fix_version_details
134
134
  @lowest_security_fix_version_details ||= T.let(
135
135
  version_finder.lowest_security_fix_version_details,
136
- T.nilable(T::Hash[Symbol, T.untyped])
136
+ T.nilable(T::Hash[Symbol, Object])
137
137
  )
138
138
  end
139
139
 
@@ -168,6 +168,18 @@ module Dependabot
168
168
  )
169
169
  end
170
170
 
171
+ sig { params(details: T.nilable(T::Hash[Symbol, Object])).returns(T.nilable(Dependabot::Version)) }
172
+ def version_from_details(details)
173
+ version = details&.fetch(:version, nil)
174
+ version if version.is_a?(Dependabot::Version)
175
+ end
176
+
177
+ sig { params(details: T.nilable(T::Hash[Symbol, Object])).returns(T.nilable(String)) }
178
+ def source_url_from_details(details)
179
+ source_url = details&.fetch(:source_url, nil)
180
+ source_url if source_url.is_a?(String)
181
+ end
182
+
171
183
  sig { returns(T::Boolean) }
172
184
  def git_dependency?
173
185
  git_commit_checker.git_dependency?
@@ -187,7 +199,8 @@ module Dependabot
187
199
  sig { returns(T::Boolean) }
188
200
  def version_comes_from_multi_dependency_property?
189
201
  declarations_using_a_property.any? do |requirement|
190
- property_name = requirement.fetch(:metadata).fetch(:property_name)
202
+ property_name = property_name_from_requirement(requirement)
203
+ next false unless property_name
191
204
 
192
205
  all_property_based_dependencies.any? do |dep|
193
206
  next false if dep.name == dependency.name
@@ -199,6 +212,15 @@ module Dependabot
199
212
  end
200
213
  end
201
214
 
215
+ sig { params(requirement: T::Hash[Symbol, Object]).returns(T.nilable(String)) }
216
+ def property_name_from_requirement(requirement)
217
+ metadata = requirement[:metadata]
218
+ return unless metadata.is_a?(Hash)
219
+
220
+ property_name = metadata[:property_name]
221
+ property_name if property_name.is_a?(String)
222
+ end
223
+
202
224
  sig { returns(T::Boolean) }
203
225
  def version_comes_from_dependency_set?
204
226
  dependency.requirements.any? do |req|
@@ -206,12 +228,12 @@ module Dependabot
206
228
  end
207
229
  end
208
230
 
209
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
231
+ sig { returns(T::Array[T::Hash[Symbol, Object]]) }
210
232
  def declarations_using_a_property
211
233
  @declarations_using_a_property ||= T.let(
212
234
  dependency.requirements
213
235
  .select { |req| req.dig(:metadata, :property_name) },
214
- T.nilable(T::Array[T::Hash[Symbol, T.untyped]])
236
+ T.nilable(T::Array[T::Hash[Symbol, Object]])
215
237
  )
216
238
  end
217
239
 
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -47,14 +47,14 @@ module Dependabot
47
47
  )
48
48
  ANCHORED_VERSION_PATTERN = T.let(/\A\s*(#{VERSION_PATTERN})?\s*\z/, Regexp)
49
49
 
50
- sig { override.params(version: T.untyped).returns(T::Boolean) }
50
+ sig { override.params(version: Object).returns(T::Boolean) }
51
51
  def self.correct?(version)
52
52
  return false if version.nil?
53
53
 
54
54
  version.to_s.match?(ANCHORED_VERSION_PATTERN)
55
55
  end
56
56
 
57
- sig { override.params(version: T.untyped).void }
57
+ sig { override.params(version: Object).void }
58
58
  def initialize(version)
59
59
  @version_string = T.let(version.to_s, String)
60
60
  super(version.to_s.tr("_", "-"))
@@ -75,7 +75,7 @@ module Dependabot
75
75
  end
76
76
  end
77
77
 
78
- sig { params(other: T.untyped).returns(Integer) }
78
+ sig { params(other: Object).returns(Integer) }
79
79
  def <=>(other)
80
80
  version = stringify_version(@version_string)
81
81
  version = fill_tokens(version)
@@ -122,7 +122,7 @@ module Dependabot
122
122
  @tokens
123
123
  end
124
124
 
125
- sig { params(version: T.untyped).returns(String) }
125
+ sig { params(version: Object).returns(String) }
126
126
  def stringify_version(version)
127
127
  version = version.to_s.downcase
128
128
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-gradle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.386.0
4
+ version: 0.387.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.386.0
18
+ version: 0.387.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.386.0
25
+ version: 0.387.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: dependabot-maven
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.386.0
32
+ version: 0.387.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.386.0
39
+ version: 0.387.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: debug
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -291,7 +291,7 @@ licenses:
291
291
  - MIT
292
292
  metadata:
293
293
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
294
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.386.0
294
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.387.0
295
295
  rdoc_options: []
296
296
  require_paths:
297
297
  - lib