dependabot-bun 0.296.2 → 0.296.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/.eslintrc +11 -0
  3. data/helpers/README.md +29 -0
  4. data/helpers/build +26 -0
  5. data/helpers/jest.config.js +5 -0
  6. data/helpers/lib/npm/conflicting-dependency-parser.js +78 -0
  7. data/helpers/lib/npm/index.js +9 -0
  8. data/helpers/lib/npm/vulnerability-auditor.js +291 -0
  9. data/helpers/lib/npm6/helpers.js +25 -0
  10. data/helpers/lib/npm6/index.js +9 -0
  11. data/helpers/lib/npm6/peer-dependency-checker.js +111 -0
  12. data/helpers/lib/npm6/remove-dependencies-from-lockfile.js +22 -0
  13. data/helpers/lib/npm6/subdependency-updater.js +78 -0
  14. data/helpers/lib/npm6/updater.js +199 -0
  15. data/helpers/lib/pnpm/index.js +5 -0
  16. data/helpers/lib/pnpm/lockfile-parser.js +82 -0
  17. data/helpers/lib/yarn/conflicting-dependency-parser.js +176 -0
  18. data/helpers/lib/yarn/fix-duplicates.js +80 -0
  19. data/helpers/lib/yarn/helpers.js +54 -0
  20. data/helpers/lib/yarn/index.js +14 -0
  21. data/helpers/lib/yarn/lockfile-parser.js +21 -0
  22. data/helpers/lib/yarn/peer-dependency-checker.js +132 -0
  23. data/helpers/lib/yarn/replace-lockfile-declaration.js +57 -0
  24. data/helpers/lib/yarn/subdependency-updater.js +83 -0
  25. data/helpers/lib/yarn/updater.js +209 -0
  26. data/helpers/package-lock.json +28519 -0
  27. data/helpers/package.json +29 -0
  28. data/helpers/patches/npm++pacote+9.5.12.patch +14 -0
  29. data/helpers/run.js +30 -0
  30. data/helpers/test/npm6/conflicting-dependency-parser.test.js +66 -0
  31. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package-lock.json +591 -0
  32. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package.json +14 -0
  33. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/nested/package-lock.json +188 -0
  34. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/nested/package.json +14 -0
  35. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple/package-lock.json +27 -0
  36. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple/package.json +14 -0
  37. data/helpers/test/npm6/fixtures/updater/original/package-lock.json +16 -0
  38. data/helpers/test/npm6/fixtures/updater/original/package.json +9 -0
  39. data/helpers/test/npm6/fixtures/updater/updated/package-lock.json +16 -0
  40. data/helpers/test/npm6/helpers.js +21 -0
  41. data/helpers/test/npm6/updater.test.js +30 -0
  42. data/helpers/test/pnpm/fixtures/parser/empty_version/pnpm-lock.yaml +72 -0
  43. data/helpers/test/pnpm/fixtures/parser/no_lockfile_change/pnpm-lock.yaml +2744 -0
  44. data/helpers/test/pnpm/fixtures/parser/only_dev_dependencies/pnpm-lock.yaml +16 -0
  45. data/helpers/test/pnpm/fixtures/parser/peer_disambiguation/pnpm-lock.yaml +855 -0
  46. data/helpers/test/pnpm/lockfile-parser.test.js +62 -0
  47. data/helpers/test/yarn/conflicting-dependency-parser.test.js +83 -0
  48. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/package.json +14 -0
  49. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/yarn.lock +496 -0
  50. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/dev-dependencies/package.json +14 -0
  51. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/dev-dependencies/yarn.lock +21 -0
  52. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/nested/package.json +14 -0
  53. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/nested/yarn.lock +183 -0
  54. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/simple/package.json +14 -0
  55. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/simple/yarn.lock +21 -0
  56. data/helpers/test/yarn/fixtures/updater/illegal_character/package.json +8 -0
  57. data/helpers/test/yarn/fixtures/updater/illegal_character/yarn.lock +14 -0
  58. data/helpers/test/yarn/fixtures/updater/original/package.json +6 -0
  59. data/helpers/test/yarn/fixtures/updater/original/yarn.lock +11 -0
  60. data/helpers/test/yarn/fixtures/updater/updated/yarn.lock +12 -0
  61. data/helpers/test/yarn/fixtures/updater/with-version-comments/package.json +5 -0
  62. data/helpers/test/yarn/fixtures/updater/with-version-comments/yarn.lock +13 -0
  63. data/helpers/test/yarn/helpers.js +18 -0
  64. data/helpers/test/yarn/updater.test.js +117 -0
  65. data/lib/dependabot/bun/bun_package_manager.rb +47 -0
  66. data/lib/dependabot/bun/constraint_helper.rb +359 -0
  67. data/lib/dependabot/bun/dependency_files_filterer.rb +157 -0
  68. data/lib/dependabot/bun/file_fetcher/path_dependency_builder.rb +184 -0
  69. data/lib/dependabot/bun/file_fetcher.rb +402 -0
  70. data/lib/dependabot/bun/file_parser/bun_lock.rb +140 -0
  71. data/lib/dependabot/bun/file_parser/lockfile_parser.rb +105 -0
  72. data/lib/dependabot/bun/file_parser.rb +477 -0
  73. data/lib/dependabot/bun/file_updater/bun_lockfile_updater.rb +144 -0
  74. data/lib/dependabot/bun/file_updater/npmrc_builder.rb +256 -0
  75. data/lib/dependabot/bun/file_updater/package_json_preparer.rb +88 -0
  76. data/lib/dependabot/bun/file_updater/package_json_updater.rb +378 -0
  77. data/lib/dependabot/bun/file_updater.rb +203 -0
  78. data/lib/dependabot/bun/helpers.rb +93 -0
  79. data/lib/dependabot/bun/language.rb +45 -0
  80. data/lib/dependabot/bun/metadata_finder.rb +214 -0
  81. data/lib/dependabot/bun/native_helpers.rb +19 -0
  82. data/lib/dependabot/bun/package_manager.rb +280 -0
  83. data/lib/dependabot/bun/package_name.rb +118 -0
  84. data/lib/dependabot/bun/pnpm_package_manager.rb +55 -0
  85. data/lib/dependabot/bun/registry_helper.rb +188 -0
  86. data/lib/dependabot/bun/registry_parser.rb +93 -0
  87. data/lib/dependabot/bun/requirement.rb +146 -0
  88. data/lib/dependabot/bun/sub_dependency_files_filterer.rb +82 -0
  89. data/lib/dependabot/bun/update_checker/conflicting_dependency_resolver.rb +59 -0
  90. data/lib/dependabot/bun/update_checker/dependency_files_builder.rb +79 -0
  91. data/lib/dependabot/bun/update_checker/latest_version_finder.rb +448 -0
  92. data/lib/dependabot/bun/update_checker/library_detector.rb +76 -0
  93. data/lib/dependabot/bun/update_checker/registry_finder.rb +279 -0
  94. data/lib/dependabot/bun/update_checker/requirements_updater.rb +206 -0
  95. data/lib/dependabot/bun/update_checker/subdependency_version_resolver.rb +154 -0
  96. data/lib/dependabot/bun/update_checker/version_resolver.rb +583 -0
  97. data/lib/dependabot/bun/update_checker/vulnerability_auditor.rb +164 -0
  98. data/lib/dependabot/bun/update_checker.rb +455 -0
  99. data/lib/dependabot/bun/version.rb +138 -0
  100. data/lib/dependabot/bun/version_selector.rb +61 -0
  101. data/lib/dependabot/bun.rb +337 -35
  102. metadata +108 -65
  103. data/lib/dependabot/javascript/bun/file_fetcher.rb +0 -77
  104. data/lib/dependabot/javascript/bun/file_parser/bun_lock.rb +0 -156
  105. data/lib/dependabot/javascript/bun/file_parser/lockfile_parser.rb +0 -55
  106. data/lib/dependabot/javascript/bun/file_parser.rb +0 -74
  107. data/lib/dependabot/javascript/bun/file_updater/lockfile_updater.rb +0 -138
  108. data/lib/dependabot/javascript/bun/file_updater.rb +0 -75
  109. data/lib/dependabot/javascript/bun/helpers.rb +0 -72
  110. data/lib/dependabot/javascript/bun/package_manager.rb +0 -48
  111. data/lib/dependabot/javascript/bun/requirement.rb +0 -11
  112. data/lib/dependabot/javascript/bun/update_checker/conflicting_dependency_resolver.rb +0 -64
  113. data/lib/dependabot/javascript/bun/update_checker/dependency_files_builder.rb +0 -47
  114. data/lib/dependabot/javascript/bun/update_checker/latest_version_finder.rb +0 -450
  115. data/lib/dependabot/javascript/bun/update_checker/library_detector.rb +0 -76
  116. data/lib/dependabot/javascript/bun/update_checker/requirements_updater.rb +0 -203
  117. data/lib/dependabot/javascript/bun/update_checker/subdependency_version_resolver.rb +0 -144
  118. data/lib/dependabot/javascript/bun/update_checker/version_resolver.rb +0 -525
  119. data/lib/dependabot/javascript/bun/update_checker/vulnerability_auditor.rb +0 -165
  120. data/lib/dependabot/javascript/bun/update_checker.rb +0 -440
  121. data/lib/dependabot/javascript/bun/version.rb +0 -11
  122. data/lib/dependabot/javascript/shared/constraint_helper.rb +0 -359
  123. data/lib/dependabot/javascript/shared/dependency_files_filterer.rb +0 -164
  124. data/lib/dependabot/javascript/shared/file_fetcher.rb +0 -283
  125. data/lib/dependabot/javascript/shared/file_parser/lockfile_parser.rb +0 -106
  126. data/lib/dependabot/javascript/shared/file_parser.rb +0 -454
  127. data/lib/dependabot/javascript/shared/file_updater/npmrc_builder.rb +0 -394
  128. data/lib/dependabot/javascript/shared/file_updater/package_json_preparer.rb +0 -87
  129. data/lib/dependabot/javascript/shared/file_updater/package_json_updater.rb +0 -376
  130. data/lib/dependabot/javascript/shared/file_updater.rb +0 -179
  131. data/lib/dependabot/javascript/shared/language.rb +0 -45
  132. data/lib/dependabot/javascript/shared/metadata_finder.rb +0 -209
  133. data/lib/dependabot/javascript/shared/native_helpers.rb +0 -21
  134. data/lib/dependabot/javascript/shared/package_manager_detector.rb +0 -72
  135. data/lib/dependabot/javascript/shared/package_name.rb +0 -118
  136. data/lib/dependabot/javascript/shared/registry_helper.rb +0 -190
  137. data/lib/dependabot/javascript/shared/registry_parser.rb +0 -93
  138. data/lib/dependabot/javascript/shared/requirement.rb +0 -144
  139. data/lib/dependabot/javascript/shared/sub_dependency_files_filterer.rb +0 -79
  140. data/lib/dependabot/javascript/shared/update_checker/dependency_files_builder.rb +0 -87
  141. data/lib/dependabot/javascript/shared/update_checker/registry_finder.rb +0 -358
  142. data/lib/dependabot/javascript/shared/version.rb +0 -133
  143. data/lib/dependabot/javascript/shared/version_selector.rb +0 -60
  144. data/lib/dependabot/javascript.rb +0 -39
@@ -1,454 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- # See https://docs.npmjs.com/files/package.json for package.json format docs.
5
-
6
- module Dependabot
7
- module Javascript
8
- module Shared
9
- class FileParser < Dependabot::FileParsers::Base
10
- extend T::Sig
11
-
12
- abstract!
13
-
14
- DEPENDENCY_TYPES = T.let(%w(dependencies devDependencies optionalDependencies).freeze, T::Array[String])
15
- GIT_URL_REGEX = %r{
16
- (?<git_prefix>^|^git.*?|^github:|^bitbucket:|^gitlab:|github\.com/)
17
- (?<username>[a-z0-9-]+)/
18
- (?<repo>[a-z0-9_.-]+)
19
- (
20
- (?:\#semver:(?<semver>.+))|
21
- (?:\#(?=[\^~=<>*])(?<semver>.+))|
22
- (?:\#(?<ref>.+))
23
- )?$
24
- }ix
25
- RC_FILENAME = T.let(".npmrc", String)
26
-
27
- sig do
28
- params(
29
- json: T::Hash[String, T.untyped],
30
- _block: T.proc.params(arg0: String, arg1: String, arg2: String).void
31
- )
32
- .void
33
- end
34
- def self.each_dependency(json, &_block)
35
- DEPENDENCY_TYPES.each do |type|
36
- deps = json[type] || {}
37
- deps.each do |name, requirement|
38
- yield(name, requirement, type)
39
- end
40
- end
41
- end
42
-
43
- sig { override.returns(T::Array[Dependency]) }
44
- def parse # rubocop:disable Metrics/PerceivedComplexity
45
- dependency_set = DependencySet.new
46
- dependency_set += manifest_dependencies
47
- dependency_set += lockfile_dependencies
48
- dependency_set += workspace_catalog_dependencies if pnpm_workspace_yml
49
-
50
- dependencies = self.class.dependencies_with_all_versions_metadata(dependency_set)
51
-
52
- dependencies.reject do |dep|
53
- reqs = dep.requirements
54
-
55
- # Ignore dependencies defined in support files, since we don't want PRs for those
56
- support_reqs = reqs.select { |r| support_package_files.any? { |f| f.name == r[:file] } }
57
- next true if support_reqs.any?
58
-
59
- # TODO: Currently, Dependabot can't handle dependencies that have both
60
- # a git source *and* a non-git source. Fix that!
61
- git_reqs = reqs.select { |r| r.dig(:source, :type) == "git" }
62
- next false if git_reqs.none?
63
- next true if git_reqs.map { |r| r.fetch(:source) }.uniq.count > 1
64
-
65
- dep.requirements.any? { |r| r.dig(:source, :type) != "git" }
66
- end
67
- end
68
-
69
- sig { abstract.returns(Ecosystem) }
70
- def ecosystem; end
71
-
72
- sig { params(dependency_set: Dependabot::FileParsers::Base::DependencySet).returns(T::Array[Dependency]) }
73
- def self.dependencies_with_all_versions_metadata(dependency_set)
74
- dependency_set.dependencies.map do |dependency|
75
- dependency.metadata[:all_versions] = dependency_set.all_versions_for_name(dependency.name)
76
- dependency
77
- end
78
- end
79
-
80
- private
81
-
82
- sig { abstract.returns(T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)]) }
83
- def lockfiles; end
84
-
85
- sig { abstract.returns(T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)]) }
86
- def registry_config_files; end
87
-
88
- sig { returns(T.untyped) }
89
- def parsed_package_json
90
- JSON.parse(T.must(package_json.content))
91
- rescue JSON::ParserError
92
- raise Dependabot::DependencyFileNotParseable, package_json.path
93
- end
94
-
95
- sig { returns(Dependabot::DependencyFile) }
96
- def package_json
97
- # Declare the instance variable with T.let and the correct type
98
- @package_json ||= T.let(
99
- T.must(dependency_files.find { |f| f.name == MANIFEST_FILENAME }),
100
- T.nilable(Dependabot::DependencyFile)
101
- )
102
- end
103
-
104
- sig { returns(T.nilable(Dependabot::DependencyFile)) }
105
- def npmrc
106
- @npmrc ||= T.let(dependency_files.find do |f|
107
- f.name.end_with?(RC_FILENAME)
108
- end, T.nilable(Dependabot::DependencyFile))
109
- end
110
-
111
- sig { returns(T.nilable(Dependabot::DependencyFile)) }
112
- def pnpm_workspace_yml
113
- nil
114
- end
115
-
116
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
117
- def manifest_dependencies
118
- dependency_set = DependencySet.new
119
-
120
- package_files.each do |file|
121
- json = JSON.parse(T.must(file.content))
122
-
123
- # TODO: Currently, Dependabot can't handle flat dependency files
124
- # (and will error at the FileUpdater stage, because the
125
- # UpdateChecker doesn't take account of flat resolution).
126
- next if json["flat"]
127
-
128
- self.class.each_dependency(json) do |name, requirement, type|
129
- next unless requirement.is_a?(String)
130
-
131
- # Skip dependencies using Yarn workspace cross-references as requirements
132
- next if requirement.start_with?("workspace:", "catalog:")
133
-
134
- requirement = "*" if requirement == ""
135
- dep = build_dependency(
136
- file: file, type: type, name: name, requirement: requirement
137
- )
138
- dependency_set << dep if dep
139
- end
140
- end
141
-
142
- dependency_set
143
- end
144
-
145
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
146
- def workspace_catalog_dependencies
147
- dependency_set = DependencySet.new
148
- workspace_config = YAML.safe_load(T.must(pnpm_workspace_yml&.content), aliases: true)
149
-
150
- workspace_config["catalog"]&.each do |name, version|
151
- dep = build_dependency(
152
- file: T.must(pnpm_workspace_yml), type: "dependencies", name: name, requirement: version
153
- )
154
- dependency_set << dep if dep
155
- end
156
-
157
- workspace_config["catalogs"]&.each do |_, group_depenencies|
158
- group_depenencies.each do |name, version|
159
- dep = build_dependency(
160
- file: T.must(pnpm_workspace_yml), type: "dependencies", name: name, requirement: version
161
- )
162
- dependency_set << dep if dep
163
- end
164
- end
165
-
166
- dependency_set
167
- end
168
-
169
- sig { abstract.returns(FileParser::LockfileParser) }
170
- def lockfile_parser; end
171
-
172
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
173
- def lockfile_dependencies
174
- lockfile_parser.parse_set
175
- end
176
-
177
- sig do
178
- params(file: DependencyFile, type: T.untyped, name: String, requirement: String)
179
- .returns(T.nilable(Dependency))
180
- end
181
- def build_dependency(file:, type:, name:, requirement:)
182
- lockfile_details = lockfile_parser.lockfile_details(
183
- dependency_name: name,
184
- requirement: requirement,
185
- manifest_name: file.name
186
- )
187
- version = version_for(requirement, lockfile_details)
188
- converted_version = T.let(if version.nil?
189
- nil
190
- elsif version.is_a?(String)
191
- version
192
- else
193
- Dependabot::Version.new(version)
194
- end, T.nilable(T.any(String, Dependabot::Version)))
195
-
196
- return if lockfile_details && !version
197
- return if ignore_requirement?(requirement)
198
- return if workspace_package_names.include?(name)
199
-
200
- # TODO: Handle aliased packages:
201
- # https://github.com/dependabot/dependabot-core/pull/1115
202
- #
203
- # Ignore dependencies with an alias in the name
204
- # Example: "my-fetch-factory@npm:fetch-factory"
205
- return if aliased_package_name?(name)
206
-
207
- Dependency.new(
208
- name: name,
209
- version: converted_version,
210
- package_manager: ecosystem.name,
211
- requirements: [{
212
- requirement: requirement_for(requirement),
213
- file: file.name,
214
- groups: [type],
215
- source: source_for(name, requirement, lockfile_details)
216
- }]
217
- )
218
- end
219
-
220
- sig { override.void }
221
- def check_required_files
222
- return if get_original_file(MANIFEST_FILENAME)
223
-
224
- raise DependencyFileNotFound.new(nil,
225
- "#{MANIFEST_FILENAME} not found.")
226
- end
227
-
228
- sig { params(requirement: String).returns(T::Boolean) }
229
- def ignore_requirement?(requirement)
230
- return true if local_path?(requirement)
231
- return true if non_git_url?(requirement)
232
-
233
- # TODO: Handle aliased packages:
234
- # https://github.com/dependabot/dependabot-core/pull/1115
235
- alias_package?(requirement)
236
- end
237
-
238
- sig { params(requirement: String).returns(T::Boolean) }
239
- def local_path?(requirement)
240
- requirement.start_with?("link:", "file:", "/", "./", "../", "~/")
241
- end
242
-
243
- sig { params(requirement: String).returns(T::Boolean) }
244
- def alias_package?(requirement)
245
- requirement.start_with?("npm:")
246
- end
247
-
248
- sig { params(requirement: String).returns(T::Boolean) }
249
- def non_git_url?(requirement)
250
- requirement.include?("://") && !git_url?(requirement)
251
- end
252
-
253
- sig { params(requirement: String).returns(T::Boolean) }
254
- def git_url?(requirement)
255
- requirement.match?(GIT_URL_REGEX)
256
- end
257
-
258
- sig { params(requirement: String).returns(T::Boolean) }
259
- def git_url_with_semver?(requirement)
260
- return false unless git_url?(requirement)
261
-
262
- !T.must(requirement.match(GIT_URL_REGEX)).named_captures.fetch("semver").nil?
263
- end
264
-
265
- sig { params(name: String).returns(T::Boolean) }
266
- def aliased_package_name?(name)
267
- name.include?("@npm:")
268
- end
269
-
270
- sig { returns(T::Array[String]) }
271
- def workspace_package_names
272
- @workspace_package_names ||= T.let(package_files.filter_map do |f|
273
- JSON.parse(T.must(f.content))["name"]
274
- end, T.nilable(T::Array[String]))
275
- end
276
-
277
- sig do
278
- params(requirement: String, lockfile_details: T.nilable(T::Hash[String, T.untyped]))
279
- .returns(T.nilable(T.any(String, Integer, Gem::Version)))
280
- end
281
- def version_for(requirement, lockfile_details)
282
- if git_url_with_semver?(requirement)
283
- semver_version = lockfile_version_for(lockfile_details)
284
- return semver_version if semver_version
285
-
286
- git_revision = git_revision_for(lockfile_details)
287
- version_from_git_revision(requirement, git_revision) || git_revision
288
- elsif git_url?(requirement)
289
- git_revision_for(lockfile_details)
290
- elsif lockfile_details
291
- lockfile_version_for(lockfile_details)
292
- else
293
- exact_version = exact_version_for(requirement)
294
- return unless exact_version
295
-
296
- semver_version_for(exact_version)
297
- end
298
- end
299
-
300
- sig { params(lockfile_details: T.nilable(T::Hash[String, T.untyped])).returns(T.nilable(String)) }
301
- def git_revision_for(lockfile_details)
302
- version = T.cast(lockfile_details&.fetch("version", nil), T.nilable(String))
303
- resolved = T.cast(lockfile_details&.fetch("resolved", nil), T.nilable(String))
304
- [
305
- version&.split("#")&.last,
306
- resolved&.split("#")&.last,
307
- resolved&.split("/")&.last
308
- ].find { |str| commit_sha?(str) }
309
- end
310
-
311
- sig { params(string: T.nilable(String)).returns(T::Boolean) }
312
- def commit_sha?(string)
313
- return false unless string.is_a?(String)
314
-
315
- string.match?(/^[0-9a-f]{40}$/)
316
- end
317
-
318
- sig { params(requirement: String, git_revision: T.nilable(String)).returns(T.nilable(String)) }
319
- def version_from_git_revision(requirement, git_revision)
320
- tags =
321
- Dependabot::GitMetadataFetcher.new(
322
- url: git_source_for(requirement).fetch(:url),
323
- credentials: credentials
324
- ).tags
325
- .select { |t| [t.commit_sha, t.tag_sha].include?(git_revision) }
326
-
327
- tags.each do |t|
328
- next unless t.name.match?(Dependabot::GitCommitChecker::VERSION_REGEX)
329
-
330
- version = T.must(t.name.match(Dependabot::GitCommitChecker::VERSION_REGEX))
331
- .named_captures.fetch("version")
332
- next unless version_class.correct?(version)
333
-
334
- return version
335
- end
336
-
337
- nil
338
- rescue Dependabot::GitDependenciesNotReachable
339
- nil
340
- end
341
-
342
- sig do
343
- params(lockfile_details: T.nilable(T::Hash[String, T.untyped]))
344
- .returns(T.nilable(T.any(String, Integer, Gem::Version)))
345
- end
346
- def lockfile_version_for(lockfile_details)
347
- semver_version_for(lockfile_details&.fetch("version", ""))
348
- end
349
-
350
- sig { params(version: T.nilable(String)).returns(T.nilable(T.any(String, Integer, Gem::Version))) }
351
- def semver_version_for(version)
352
- version_class.semver_for(version)
353
- end
354
-
355
- sig { params(requirement: String).returns(T.nilable(String)) }
356
- def exact_version_for(requirement)
357
- req = requirement_class.new([requirement])
358
- return unless req.exact?
359
-
360
- req.requirements.first.last.to_s
361
- rescue Gem::Requirement::BadRequirementError
362
- # If it doesn't parse, it's definitely not exact
363
- end
364
-
365
- sig do
366
- params(name: String, requirement: String, lockfile_details: T.nilable(T::Hash[String, T.untyped]))
367
- .returns(T.nilable(T::Hash[Symbol, T.untyped]))
368
- end
369
- def source_for(name, requirement, lockfile_details)
370
- return git_source_for(requirement) if git_url?(requirement)
371
-
372
- resolved_url = lockfile_details&.fetch("resolved", nil)
373
-
374
- resolution = lockfile_details&.fetch("resolution", nil)
375
- package_match = resolution&.match(/__archiveUrl=(?<package_url>.+)/)
376
- resolved_url = CGI.unescape(package_match.named_captures.fetch("package_url", "")) if package_match
377
-
378
- return unless resolved_url
379
- return unless resolved_url.start_with?("http")
380
- return if resolved_url.match?(/(?<!pkg\.)github/)
381
-
382
- RegistryParser.new(
383
- resolved_url: resolved_url,
384
- credentials: credentials
385
- ).registry_source_for(name)
386
- end
387
-
388
- sig { params(requirement: String).returns(T.nilable(String)) }
389
- def requirement_for(requirement)
390
- return requirement unless git_url?(requirement)
391
-
392
- details = T.must(requirement.match(GIT_URL_REGEX)).named_captures
393
- details["semver"]
394
- end
395
-
396
- sig { params(requirement: String).returns(T::Hash[Symbol, T.untyped]) }
397
- def git_source_for(requirement)
398
- details = T.must(requirement.match(GIT_URL_REGEX)).named_captures
399
- prefix = T.must(details.fetch("git_prefix"))
400
-
401
- host = if prefix.include?("git@") || prefix.include?("://")
402
- T.must(prefix.split("git@").last)
403
- .sub(%r{.*?://}, "")
404
- .sub(%r{[:/]$}, "")
405
- .split("#").first
406
- elsif prefix.include?("bitbucket") then "bitbucket.org"
407
- elsif prefix.include?("gitlab") then "gitlab.com"
408
- else
409
- "github.com"
410
- end
411
-
412
- {
413
- type: "git",
414
- url: "https://#{host}/#{details['username']}/#{details['repo']}",
415
- branch: nil,
416
- ref: details["ref"] || "master"
417
- }
418
- end
419
-
420
- sig { returns(T::Array[Dependabot::DependencyFile]) }
421
- def support_package_files
422
- @support_package_files ||= T.let(sub_package_files.select(&:support_file?),
423
- T.nilable(T::Array[DependencyFile]))
424
- end
425
-
426
- sig { returns(T::Array[Dependabot::DependencyFile]) }
427
- def sub_package_files
428
- return T.must(@sub_package_files) if defined?(@sub_package_files)
429
-
430
- files = dependency_files.select { |f| f.name.end_with?(MANIFEST_FILENAME) }
431
- .reject { |f| f.name == MANIFEST_FILENAME }
432
- .reject { |f| f.name.include?("node_modules/") }
433
- @sub_package_files ||= T.let(files, T.nilable(T::Array[Dependabot::DependencyFile]))
434
- end
435
-
436
- sig { returns(T::Array[DependencyFile]) }
437
- def package_files
438
- @package_files ||= T.let(
439
- [
440
- dependency_files.find { |f| f.name == MANIFEST_FILENAME },
441
- *sub_package_files
442
- ].compact, T.nilable(T::Array[DependencyFile])
443
- )
444
- end
445
-
446
- sig { abstract.returns(T.class_of(Version)) }
447
- def version_class; end
448
-
449
- sig { abstract.returns(T.class_of(Requirement)) }
450
- def requirement_class; end
451
- end
452
- end
453
- end
454
- end