dependabot-docker_compose 0.298.0 → 0.299.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,479 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "docker_registry2"
5
- require "sorbet-runtime"
6
-
7
- require "dependabot/update_checkers"
8
- require "dependabot/update_checkers/base"
9
- require "dependabot/errors"
10
- require "dependabot/docker_compose/tag"
11
- require "dependabot/docker_compose/file_parser"
12
- require "dependabot/docker_compose/version"
13
- require "dependabot/docker_compose/requirement"
14
- require "dependabot/shared/utils/credentials_finder"
15
-
16
- module Dependabot
17
- module DockerCompose
18
- # rubocop:disable Metrics/ClassLength
19
- class UpdateChecker < Dependabot::UpdateCheckers::Base
20
- extend T::Sig
21
-
22
- sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
23
- def latest_version
24
- latest_version_from(T.must(dependency.version))
25
- end
26
-
27
- sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
28
- def latest_resolvable_version
29
- # Resolvability isn't an issue for Docker containers.
30
- latest_version
31
- end
32
-
33
- sig { override.returns(T.nilable(String)) }
34
- def latest_resolvable_version_with_no_unlock
35
- # No concept of "unlocking" for Docker containers
36
- dependency.version
37
- end
38
-
39
- sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
40
- def updated_requirements
41
- dependency.requirements.map do |req|
42
- updated_source = req.fetch(:source).dup
43
-
44
- tag = req[:source][:tag]
45
- digest = req[:source][:digest]
46
-
47
- if tag
48
- updated_tag = latest_version_from(tag)
49
- updated_source[:tag] = updated_tag
50
- updated_source[:digest] = digest_of(updated_tag) if digest
51
- elsif digest
52
- updated_source[:digest] = digest_of("latest")
53
- end
54
-
55
- req.merge(source: updated_source)
56
- end
57
- end
58
-
59
- private
60
-
61
- sig { override.returns(T::Boolean) }
62
- def latest_version_resolvable_with_full_unlock?
63
- # Full unlock checks aren't relevant for Dockerfiles
64
- false
65
- end
66
-
67
- sig { override.returns(T::Array[Dependabot::Dependency]) }
68
- def updated_dependencies_after_full_unlock
69
- raise NotImplementedError
70
- end
71
-
72
- sig { params(requirements_to_unlock: T.nilable(Symbol)).returns(T::Boolean) }
73
- def version_can_update?(requirements_to_unlock:) # rubocop:disable Lint/UnusedMethodArgument
74
- if digest_requirements.any?
75
- !digest_up_to_date?
76
- else
77
- !version_up_to_date?
78
- end
79
- end
80
-
81
- sig { returns(T::Boolean) }
82
- def version_up_to_date?
83
- if digest_requirements.any?
84
- version_tag_up_to_date? && digest_up_to_date?
85
- else
86
- version_tag_up_to_date?
87
- end
88
- end
89
-
90
- sig { returns(T::Boolean) }
91
- def version_tag_up_to_date?
92
- version = dependency.version
93
- return false unless version
94
-
95
- return true unless version_tag.comparable?
96
-
97
- latest_tag = latest_tag_from(version)
98
-
99
- comparable_version_from(latest_tag) <= comparable_version_from(version_tag)
100
- end
101
-
102
- sig { returns(T::Boolean) }
103
- def digest_up_to_date?
104
- digest_requirements.all? do |req|
105
- next true unless updated_digest
106
-
107
- req.fetch(:source).fetch(:digest) == updated_digest
108
- end
109
- end
110
-
111
- sig { params(version: String).returns(String) }
112
- def latest_version_from(version)
113
- latest_tag_from(version).name
114
- end
115
-
116
- sig { params(version: String).returns(Dependabot::DockerCompose::Tag) }
117
- def latest_tag_from(version)
118
- @tags ||= T.let({}, T.nilable(T::Hash[String, Dependabot::DockerCompose::Tag]))
119
- return T.must(@tags[version]) if @tags.key?(version)
120
-
121
- @tags[version] = fetch_latest_tag(Tag.new(version))
122
- end
123
-
124
- # NOTE: It's important that this *always* returns a tag (even if
125
- # it's the existing one) as it is what we later check the digest of.
126
- sig { params(version_tag: Dependabot::DockerCompose::Tag).returns(Dependabot::DockerCompose::Tag) }
127
- def fetch_latest_tag(version_tag)
128
- return Tag.new(T.must(latest_digest)) if version_tag.digest? && latest_digest
129
- return version_tag unless version_tag.comparable?
130
-
131
- # Prune out any downgrade tags before checking for pre-releases
132
- # (which requires a call to the registry for each tag, so can be slow)
133
- candidate_tags = comparable_tags_from_registry(version_tag)
134
- candidate_tags = remove_version_downgrades(candidate_tags, version_tag)
135
- candidate_tags = remove_prereleases(candidate_tags, version_tag)
136
- candidate_tags = filter_ignored(candidate_tags)
137
- candidate_tags = sort_tags(candidate_tags, version_tag)
138
-
139
- latest_tag = candidate_tags.last
140
- return version_tag unless latest_tag
141
-
142
- return latest_tag if latest_tag.same_precision?(version_tag)
143
-
144
- latest_same_precision_tag = remove_precision_changes(candidate_tags, version_tag).last
145
- return latest_tag unless latest_same_precision_tag
146
-
147
- latest_same_precision_digest = digest_of(latest_same_precision_tag.name)
148
- latest_digest = digest_of(latest_tag.name)
149
-
150
- # NOTE: Some registries don't provide digests (the API documents them as
151
- # optional: https://docs.docker.com/registry/spec/api/#content-digests).
152
- #
153
- # In that case we can't know for sure whether the latest tag keeping
154
- # existing precision is the same as the absolute latest tag.
155
- #
156
- # We can however, make a best-effort to avoid unwanted changes by
157
- # directly looking at version numbers and checking whether the absolute
158
- # latest tag is just a more precise version of the latest tag that keeps
159
- # existing precision.
160
-
161
- if latest_same_precision_digest == latest_digest && latest_same_precision_tag.same_but_less_precise?(latest_tag)
162
- latest_same_precision_tag
163
- else
164
- latest_tag
165
- end
166
- end
167
-
168
- sig { params(original_tag: Dependabot::DockerCompose::Tag).returns(T::Array[Dependabot::DockerCompose::Tag]) }
169
- def comparable_tags_from_registry(original_tag)
170
- tags_from_registry.select { |tag| tag.comparable_to?(original_tag) }
171
- end
172
-
173
- sig do
174
- params(
175
- candidate_tags: T::Array[Dependabot::DockerCompose::Tag],
176
- version_tag: Dependabot::DockerCompose::Tag
177
- )
178
- .returns(T::Array[Dependabot::DockerCompose::Tag])
179
- end
180
- def remove_version_downgrades(candidate_tags, version_tag)
181
- current_version = comparable_version_from(version_tag)
182
-
183
- candidate_tags.select do |tag|
184
- comparable_version_from(tag) >= current_version
185
- end
186
- end
187
-
188
- sig do
189
- params(
190
- candidate_tags: T::Array[Dependabot::DockerCompose::Tag],
191
- version_tag: Dependabot::DockerCompose::Tag
192
- )
193
- .returns(T::Array[Dependabot::DockerCompose::Tag])
194
- end
195
- def remove_prereleases(candidate_tags, version_tag)
196
- return candidate_tags if prerelease?(version_tag)
197
-
198
- candidate_tags.reject { |tag| prerelease?(tag) }
199
- end
200
-
201
- sig do
202
- params(
203
- candidate_tags: T::Array[Dependabot::DockerCompose::Tag],
204
- version_tag: Dependabot::DockerCompose::Tag
205
- )
206
- .returns(T::Array[Dependabot::DockerCompose::Tag])
207
- end
208
- def remove_precision_changes(candidate_tags, version_tag)
209
- candidate_tags.select do |tag|
210
- tag.same_precision?(version_tag)
211
- end
212
- end
213
-
214
- sig { returns(T.nilable(Dependabot::DockerCompose::Tag)) }
215
- def latest_tag
216
- return unless latest_digest
217
-
218
- tags_from_registry
219
- .select(&:canonical?)
220
- .sort_by { |t| comparable_version_from(t) }
221
- .reverse
222
- .find { |t| digest_of(t.name) == latest_digest }
223
- end
224
-
225
- sig { returns(T.nilable(String)) }
226
- def updated_digest
227
- @updated_digest ||= T.let(
228
- if latest_tag_from(T.must(dependency.version)).digest?
229
- latest_digest
230
- else
231
- digest_of(T.cast(latest_version, String))
232
- end,
233
- T.nilable(String)
234
- )
235
- end
236
-
237
- sig { returns(T::Array[Dependabot::DockerCompose::Tag]) }
238
- def tags_from_registry
239
- @tags_from_registry ||= T.let(
240
- begin
241
- client = docker_registry_client
242
-
243
- client.tags(docker_repo_name, auto_paginate: true).fetch("tags").map { |name| Tag.new(name) }
244
- rescue *transient_docker_errors
245
- attempt ||= 1
246
- attempt += 1
247
- raise if attempt > 3
248
-
249
- retry
250
- end,
251
- T.nilable(T::Array[Dependabot::DockerCompose::Tag])
252
- )
253
- rescue DockerRegistry2::RegistryAuthenticationException,
254
- RestClient::Forbidden
255
- raise PrivateSourceAuthenticationFailure, registry_hostname
256
- rescue RestClient::Exceptions::OpenTimeout,
257
- RestClient::Exceptions::ReadTimeout
258
- raise if using_dockerhub?
259
-
260
- raise PrivateSourceTimedOut, T.must(registry_hostname)
261
- rescue RestClient::ServerBrokeConnection,
262
- RestClient::TooManyRequests
263
- raise PrivateSourceBadResponse, registry_hostname
264
- rescue JSON::ParserError => e
265
- if e.message.include?("unexpected token")
266
- raise DependencyFileNotResolvable, "Error while accessing docker image at #{registry_hostname}"
267
- end
268
-
269
- raise
270
- end
271
-
272
- sig { returns(T.nilable(String)) }
273
- def latest_digest
274
- return unless tags_from_registry.map(&:name).include?("latest")
275
-
276
- digest_of("latest")
277
- end
278
-
279
- sig { params(tag: String).returns(T.nilable(String)) }
280
- def digest_of(tag)
281
- @digests ||= T.let({}, T.nilable(T::Hash[String, T.nilable(String)]))
282
- return @digests[tag] if @digests.key?(tag)
283
-
284
- @digests[tag] = fetch_digest_of(tag)
285
- end
286
-
287
- sig { params(tag: String).returns(T.nilable(String)) }
288
- def fetch_digest_of(tag)
289
- docker_registry_client.manifest_digest(docker_repo_name, tag)&.delete_prefix("sha256:")
290
- rescue *transient_docker_errors => e
291
- attempt ||= 1
292
- attempt += 1
293
- return if attempt > 3 && e.is_a?(DockerRegistry2::NotFound)
294
- raise PrivateSourceBadResponse, registry_hostname if attempt > 3
295
-
296
- retry
297
- rescue DockerRegistry2::RegistryAuthenticationException,
298
- RestClient::Forbidden
299
- raise PrivateSourceAuthenticationFailure, registry_hostname
300
- rescue RestClient::ServerBrokeConnection,
301
- RestClient::TooManyRequests
302
- raise PrivateSourceBadResponse, registry_hostname
303
- rescue JSON::ParserError
304
- Dependabot.logger.info \
305
- "docker_registry_client.manifest_digest(#{docker_repo_name}, #{tag}) returned an empty string"
306
- nil
307
- end
308
-
309
- sig { returns(T::Array[T.class_of(StandardError)]) }
310
- def transient_docker_errors
311
- [
312
- RestClient::Exceptions::Timeout,
313
- RestClient::ServerBrokeConnection,
314
- RestClient::ServiceUnavailable,
315
- RestClient::InternalServerError,
316
- RestClient::BadGateway,
317
- DockerRegistry2::NotFound
318
- ]
319
- end
320
-
321
- sig { params(tag: Dependabot::DockerCompose::Tag).returns(T::Boolean) }
322
- def prerelease?(tag)
323
- return true if tag.looks_like_prerelease?
324
-
325
- # Compare the numeric version against the version of the `latest` tag.
326
- return false unless latest_tag
327
-
328
- if comparable_version_from(tag) > comparable_version_from(T.must(latest_tag))
329
- Dependabot.logger.info \
330
- "The `latest` tag points to the same image as the `#{T.must(latest_tag).name}` image, " \
331
- "so dependabot is treating `#{tag.name}` as a pre-release. " \
332
- "The `latest` tag needs to point to `#{tag.name}` for Dependabot to consider it."
333
-
334
- true
335
- else
336
- false
337
- end
338
- end
339
-
340
- sig { params(tag: Dependabot::DockerCompose::Tag).returns(Dependabot::Version) }
341
- def comparable_version_from(tag)
342
- version_class.new(tag.numeric_version)
343
- end
344
-
345
- sig { returns(T.nilable(String)) }
346
- def registry_hostname
347
- if dependency.requirements.first&.dig(:source, :registry)
348
- return T.must(dependency.requirements.first).dig(:source, :registry)
349
- end
350
-
351
- credentials_finder.base_registry
352
- end
353
-
354
- sig { returns(T::Boolean) }
355
- def using_dockerhub?
356
- registry_hostname == "registry.hub.docker.com"
357
- end
358
-
359
- sig { returns(T.nilable(Dependabot::Credential)) }
360
- def registry_credentials
361
- credentials_finder.credentials_for_registry(registry_hostname)
362
- end
363
-
364
- sig { returns(Dependabot::Shared::Utils::CredentialsFinder) }
365
- def credentials_finder
366
- @credentials_finder ||= T.let(
367
- Dependabot::Shared::Utils::CredentialsFinder.new(credentials),
368
- T.nilable(Dependabot::Shared::Utils::CredentialsFinder)
369
- )
370
- end
371
-
372
- sig { returns(String) }
373
- def docker_repo_name
374
- return dependency.name unless using_dockerhub?
375
- return dependency.name unless dependency.name.split("/").count < 2
376
-
377
- "library/#{dependency.name}"
378
- end
379
-
380
- # Defaults from https://github.com/deitch/docker_registry2/blob/bfde04144f0b7fd63c156a1aca83efe19ee78ffd/lib/registry/registry.rb#L26-L27
381
- DEFAULT_DOCKER_OPEN_TIMEOUT_IN_SECONDS = 2
382
- DEFAULT_DOCKER_READ_TIMEOUT_IN_SECONDS = 5
383
-
384
- sig { returns(DockerRegistry2::Registry) }
385
- def docker_registry_client
386
- @docker_registry_client ||= T.let(
387
- DockerRegistry2::Registry.new(
388
- "https://#{registry_hostname}",
389
- user: registry_credentials&.fetch("username", nil),
390
- password: registry_credentials&.fetch("password", nil),
391
- read_timeout: docker_read_timeout_in_seconds,
392
- open_timeout: docker_open_timeout_in_seconds,
393
- http_options: { proxy: ENV.fetch("HTTPS_PROXY", nil) }
394
- ),
395
- T.nilable(DockerRegistry2::Registry)
396
- )
397
- end
398
-
399
- sig { returns(Integer) }
400
- def docker_open_timeout_in_seconds
401
- ENV.fetch("DEPENDABOT_DOCKER_OPEN_TIMEOUT_IN_SECONDS", DEFAULT_DOCKER_OPEN_TIMEOUT_IN_SECONDS).to_i
402
- end
403
-
404
- sig { returns(Integer) }
405
- def docker_read_timeout_in_seconds
406
- ENV.fetch("DEPENDABOT_DOCKER_READ_TIMEOUT_IN_SECONDS", DEFAULT_DOCKER_READ_TIMEOUT_IN_SECONDS).to_i
407
- end
408
-
409
- sig do
410
- params(
411
- candidate_tags: T::Array[Dependabot::DockerCompose::Tag],
412
- version_tag: Dependabot::DockerCompose::Tag
413
- )
414
- .returns(T::Array[Dependabot::DockerCompose::Tag])
415
- end
416
- def sort_tags(candidate_tags, version_tag)
417
- candidate_tags.sort do |tag_a, tag_b|
418
- if comparable_version_from(tag_a) > comparable_version_from(tag_b)
419
- 1
420
- elsif comparable_version_from(tag_a) < comparable_version_from(tag_b)
421
- -1
422
- elsif tag_a.same_precision?(version_tag)
423
- 1
424
- elsif tag_b.same_precision?(version_tag)
425
- -1
426
- else
427
- 0
428
- end
429
- end
430
- end
431
-
432
- sig do
433
- params(candidate_tags: T::Array[Dependabot::DockerCompose::Tag])
434
- .returns(T::Array[Dependabot::DockerCompose::Tag])
435
- end
436
- def filter_ignored(candidate_tags)
437
- filtered =
438
- candidate_tags
439
- .reject do |tag|
440
- version = comparable_version_from(tag)
441
- ignore_requirements.any? { |r| r.satisfied_by?(version) }
442
- end
443
- if @raise_on_ignored &&
444
- filter_lower_versions(filtered).empty? &&
445
- filter_lower_versions(candidate_tags).any? &&
446
- digest_requirements.none?
447
- raise AllVersionsIgnored
448
- end
449
-
450
- filtered
451
- end
452
-
453
- sig { params(tags: T::Array[Dependabot::DockerCompose::Tag]).returns(T::Array[Dependabot::DockerCompose::Tag]) }
454
- def filter_lower_versions(tags)
455
- tags.select do |tag|
456
- comparable_version_from(tag) > comparable_version_from(version_tag)
457
- end
458
- end
459
-
460
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
461
- def digest_requirements
462
- dependency.requirements.select do |requirement|
463
- requirement.dig(:source, :digest)
464
- end
465
- end
466
-
467
- sig { returns(Dependabot::DockerCompose::Tag) }
468
- def version_tag
469
- @version_tag ||= T.let(
470
- Tag.new(T.must(dependency.version)),
471
- T.nilable(Dependabot::DockerCompose::Tag)
472
- )
473
- end
474
- end
475
- # rubocop:enable Metrics/ClassLength
476
- end
477
- end
478
-
479
- Dependabot::UpdateCheckers.register("docker_compose", Dependabot::DockerCompose::UpdateChecker)
@@ -1,84 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/version"
5
- require "dependabot/utils"
6
- require "dependabot/docker_compose/tag"
7
- require "sorbet-runtime"
8
-
9
- module Dependabot
10
- module DockerCompose
11
- # In the special case of Java, the version string may also contain
12
- # optional "update number" and "identifier" components.
13
- # See https://www.oracle.com/java/technologies/javase/versioning-naming.html
14
- # for a description of Java versions.
15
- #
16
- class Version < Dependabot::Version
17
- extend T::Sig
18
- # The regex has limits for the 0,255 and 1,255 repetitions to avoid infinite limits which makes codeql angry.
19
- # A docker image cannot be longer than 255 characters anyways.
20
- DOCKER_VERSION_REGEX = /^(?<prefix>[a-z._\-]{0,255})[_\-v]?(?<version>.{1,255})$/
21
-
22
- sig { override.params(version: VersionParameter).void }
23
- def initialize(version)
24
- parsed_version = version.to_s.match(DOCKER_VERSION_REGEX)
25
- release_part, update_part = T.must(T.must(parsed_version)[:version]).split("_", 2)
26
-
27
- # The numeric_version is needed here to validate the version string (ex: 20.9.0-alpine3.18)
28
- # when the call is made via Dependabot Api to convert the image version to semver.
29
- release_part = Tag.new(T.must(release_part).chomp(".").chomp("-").chomp("_")).numeric_version
30
-
31
- @release_part = T.let(Dependabot::Version.new(T.must(release_part).tr("-", ".")), Dependabot::Version)
32
- @update_part = T.let(
33
- Dependabot::Version.new(update_part&.start_with?(/[0-9]/) ? update_part : 0),
34
- Dependabot::Version
35
- )
36
-
37
- super(@release_part)
38
- end
39
-
40
- sig { override.params(version: VersionParameter).returns(T::Boolean) }
41
- def self.correct?(version)
42
- return true if version.is_a?(Gem::Version)
43
-
44
- # We can't call new here because Gem::Version calls self.correct? in its initialize method
45
- # causing an infinite loop, so instead we check if the release_part of the version is correct
46
- parsed_version = version.to_s.match(DOCKER_VERSION_REGEX)
47
- return false if parsed_version.nil?
48
-
49
- release_part, = T.must(parsed_version[:version]).split("_", 2)
50
- release_part = Tag.new(T.must(release_part).chomp(".").chomp("-").chomp("_")).numeric_version || parsed_version
51
- super(release_part.to_s)
52
- rescue ArgumentError
53
- # if we can't instantiate a version, it can't be correct
54
- false
55
- end
56
-
57
- sig { override.returns(String) }
58
- def to_semver
59
- @release_part.to_semver
60
- end
61
-
62
- sig { returns(T::Array[String]) }
63
- def segments
64
- @release_part.segments
65
- end
66
-
67
- sig { returns(Dependabot::Version) }
68
- attr_reader :release_part
69
-
70
- sig { params(other: Dependabot::DockerCompose::Version).returns(T.nilable(Integer)) }
71
- def <=>(other)
72
- sort_criteria <=> other.sort_criteria
73
- end
74
-
75
- sig { returns(T::Array[Dependabot::Version]) }
76
- def sort_criteria
77
- [@release_part, @update_part]
78
- end
79
- end
80
- end
81
- end
82
-
83
- Dependabot::Utils
84
- .register_version_class("docker_compose", Dependabot::DockerCompose::Version)
@@ -1,99 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
- require "dependabot/file_fetchers"
6
- require "dependabot/file_fetchers/base"
7
- require "dependabot/shared/utils/helpers"
8
-
9
- module Dependabot
10
- module Shared
11
- class SharedFileFetcher < Dependabot::FileFetchers::Base
12
- extend T::Sig
13
- extend T::Helpers
14
-
15
- abstract!
16
-
17
- YAML_REGEXP = /^[^\.].*\.ya?ml$/i
18
-
19
- sig { abstract.returns(Regexp) }
20
- def self.filename_regex; end
21
-
22
- sig { override.params(filenames: T::Array[String]).returns(T::Boolean) }
23
- def self.required_files_in?(filenames)
24
- filenames.any? { |f| f.match?(filename_regex) }
25
- end
26
-
27
- sig { override.returns(T::Array[DependencyFile]) }
28
- def fetch_files
29
- fetched_files = []
30
- fetched_files + correctly_encoded_yamlfiles
31
- end
32
-
33
- sig { returns(T::Array[Dependabot::DependencyFile]) }
34
- def correctly_encoded_yamlfiles
35
- candidate_files = yamlfiles.select { |f| f.content&.valid_encoding? }
36
- candidate_files.select do |f|
37
- if f.type == "file" && Utils.likely_helm_chart?(f)
38
- true
39
- else
40
- # This doesn't handle multi-resource files, but it shouldn't matter, since the first resource
41
- # in a multi-resource file had better be a valid k8s resource
42
- content = YAML.safe_load(T.must(f.content), aliases: true)
43
- likely_kubernetes_resource?(content)
44
- end
45
- rescue ::Psych::Exception
46
- false
47
- end
48
- end
49
-
50
- sig { returns(T::Array[Dependabot::DependencyFile]) }
51
- def incorrectly_encoded_yamlfiles
52
- yamlfiles.reject { |f| f.content&.valid_encoding? }
53
- end
54
-
55
- sig do
56
- params(
57
- incorrectly_encoded_files: T::Array[Dependabot::DependencyFile]
58
- ).returns(T.noreturn)
59
- end
60
- def raise_appropriate_error(
61
- incorrectly_encoded_files = []
62
- )
63
- if incorrectly_encoded_files.none? && incorrectly_encoded_yamlfiles.none?
64
- raise Dependabot::DependencyFileNotFound.new(
65
- File.join(directory, "Dockerfile"),
66
- "No Docker Compose manifest found in #{directory}"
67
- )
68
- end
69
-
70
- invalid_files = incorrectly_encoded_files.any? ? incorrectly_encoded_files : incorrectly_encoded_yamlfiles
71
- raise Dependabot::DependencyFileNotParseable, T.must(invalid_files.first).path
72
- end
73
-
74
- sig { returns(T::Array[DependencyFile]) }
75
- def yamlfiles
76
- @yamlfiles ||= T.let(
77
- repo_contents(raise_errors: false)
78
- .select { |f| f.type == "file" && f.name.match?(YAML_REGEXP) }
79
- .map { |f| fetch_file_from_host(f.name) },
80
- T.nilable(T::Array[DependencyFile])
81
- )
82
- end
83
-
84
- private
85
-
86
- sig { params(resource: Object).returns(T.nilable(T::Boolean)) }
87
- def likely_kubernetes_resource?(resource)
88
- # Heuristic for being a Kubernetes resource. We could make this tighter but this probably works well.
89
- resource.is_a?(::Hash) && resource.key?("apiVersion") && resource.key?("kind")
90
- end
91
-
92
- sig { abstract.returns(String) }
93
- def default_file_name; end
94
-
95
- sig { abstract.returns(String) }
96
- def file_type; end
97
- end
98
- end
99
- end