dependabot-npm_and_yarn 0.310.0 → 0.311.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/dependabot/npm_and_yarn/file_parser/json_lock.rb +1 -1
- data/lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb +4 -50
- data/lib/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater.rb +161 -51
- data/lib/dependabot/npm_and_yarn/helpers.rb +12 -59
- data/lib/dependabot/npm_and_yarn/metadata_finder.rb +11 -3
- data/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb +66 -37
- data/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +1 -1
- data/lib/dependabot/npm_and_yarn/update_checker.rb +15 -5
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd4ac6b246c4c95b8125e2770880b1f729276e4e01990de13e52a1a7fd1f9e6f
|
4
|
+
data.tar.gz: 33a4d9f4ea227d1eda55ce264e2a2aa19cf76b04a70b309368bbde7f55c40abe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e96d0e963c92f523a3e8c17a0d43461c519b89da2d2a7c06a9b155e0d4d9b4a9e7d7f5df712f1a94b9e00783f146b10ee6ad21c35639e6e1f23e0acec0ee625
|
7
|
+
data.tar.gz: c3d66d433a60a3b2e7ed64284be142c9dddd49a564ab0a10f1afe362f7975fdcd806c5aef04d3c8e0fa01d8ce3a882a2d03cd80c086a9ec9fea53634766b2bf5
|
@@ -35,7 +35,7 @@ module Dependabot
|
|
35
35
|
.returns(T.nilable(T::Hash[String, T.untyped]))
|
36
36
|
end
|
37
37
|
def details(dependency_name, _requirement, manifest_name)
|
38
|
-
if Helpers.
|
38
|
+
if Helpers.parse_npm8?(@dependency_file)
|
39
39
|
# NOTE: npm 8 sometimes doesn't install workspace dependencies in the
|
40
40
|
# workspace folder so we need to fallback to checking top-level
|
41
41
|
nested_details = parsed.dig("packages", node_modules_path(manifest_name, dependency_name))
|
@@ -248,22 +248,7 @@ module Dependabot
|
|
248
248
|
|
249
249
|
sig { params(top_level_dependencies: T::Array[Dependabot::Dependency]).returns(T::Hash[String, String]) }
|
250
250
|
def run_npm_top_level_updater(top_level_dependencies:)
|
251
|
-
|
252
|
-
run_npm8_top_level_updater(top_level_dependencies: top_level_dependencies)
|
253
|
-
else
|
254
|
-
T.cast(
|
255
|
-
SharedHelpers.run_helper_subprocess(
|
256
|
-
command: NativeHelpers.helper_path,
|
257
|
-
function: "npm6:update",
|
258
|
-
args: [
|
259
|
-
Dir.pwd,
|
260
|
-
lockfile_basename,
|
261
|
-
top_level_dependencies.map(&:to_h)
|
262
|
-
]
|
263
|
-
),
|
264
|
-
T::Hash[String, String]
|
265
|
-
)
|
266
|
-
end
|
251
|
+
run_npm8_top_level_updater(top_level_dependencies: top_level_dependencies)
|
267
252
|
end
|
268
253
|
|
269
254
|
sig { params(top_level_dependencies: T::Array[Dependabot::Dependency]).returns(T::Hash[String, String]) }
|
@@ -301,18 +286,7 @@ module Dependabot
|
|
301
286
|
params(sub_dependencies: T::Array[Dependabot::Dependency]).returns(T.nilable(T::Hash[String, String]))
|
302
287
|
end
|
303
288
|
def run_npm_subdependency_updater(sub_dependencies:)
|
304
|
-
|
305
|
-
run_npm8_subdependency_updater(sub_dependencies: sub_dependencies)
|
306
|
-
else
|
307
|
-
T.cast(
|
308
|
-
SharedHelpers.run_helper_subprocess(
|
309
|
-
command: NativeHelpers.helper_path,
|
310
|
-
function: "npm6:updateSubdependency",
|
311
|
-
args: [Dir.pwd, lockfile_basename, sub_dependencies.map(&:to_h)]
|
312
|
-
),
|
313
|
-
T.nilable(T::Hash[String, String])
|
314
|
-
)
|
315
|
-
end
|
289
|
+
run_npm8_subdependency_updater(sub_dependencies: sub_dependencies)
|
316
290
|
end
|
317
291
|
|
318
292
|
sig { params(sub_dependencies: T::Array[Dependabot::Dependency]).returns(T::Hash[String, String]) }
|
@@ -894,8 +868,6 @@ module Dependabot
|
|
894
868
|
.returns(String)
|
895
869
|
end
|
896
870
|
def restore_packages_name(updated_lockfile_content, parsed_updated_lockfile_content)
|
897
|
-
return updated_lockfile_content unless npm8?
|
898
|
-
|
899
871
|
current_name = parsed_updated_lockfile_content.dig("packages", "", "name")
|
900
872
|
original_name = parsed_lockfile.dig("packages", "", "name")
|
901
873
|
|
@@ -973,8 +945,6 @@ module Dependabot
|
|
973
945
|
.returns(String)
|
974
946
|
end
|
975
947
|
def restore_locked_package_dependencies(updated_lockfile_content, parsed_updated_lockfile_content)
|
976
|
-
return updated_lockfile_content unless npm8?
|
977
|
-
|
978
948
|
dependency_names_to_restore = (dependencies.map(&:name) + git_dependencies_to_lock.keys).uniq
|
979
949
|
|
980
950
|
NpmAndYarn::FileParser.each_dependency(parsed_package_json) do |dependency_name, original_requirement, type|
|
@@ -1014,14 +984,8 @@ module Dependabot
|
|
1014
984
|
# updates the lockfile "from" field to the new git commit when we
|
1015
985
|
# run npm install
|
1016
986
|
original_from = %("from": "#{details[:from]}")
|
1017
|
-
|
1018
|
-
|
1019
|
-
npm8_locked_from = %("from": "#{dependency_name}@#{details[:version]}")
|
1020
|
-
updated_lockfile_content = updated_lockfile_content.gsub(npm8_locked_from, original_from)
|
1021
|
-
else
|
1022
|
-
npm6_locked_from = %("from": "#{details[:version]}")
|
1023
|
-
updated_lockfile_content = updated_lockfile_content.gsub(npm6_locked_from, original_from)
|
1024
|
-
end
|
987
|
+
npm8_locked_from = %("from": "#{dependency_name}@#{details[:version]}")
|
988
|
+
updated_lockfile_content = updated_lockfile_content.gsub(npm8_locked_from, original_from)
|
1025
989
|
end
|
1026
990
|
|
1027
991
|
updated_lockfile_content
|
@@ -1103,16 +1067,6 @@ module Dependabot
|
|
1103
1067
|
npmrc_content.match?(/^package-lock\s*=\s*false/)
|
1104
1068
|
end
|
1105
1069
|
|
1106
|
-
sig { returns(T::Boolean) }
|
1107
|
-
def npm8?
|
1108
|
-
return T.must(@npm8) if defined?(@npm8)
|
1109
|
-
|
1110
|
-
@npm8 ||= T.let(
|
1111
|
-
Dependabot::NpmAndYarn::Helpers.npm8?(lockfile),
|
1112
|
-
T.nilable(T::Boolean)
|
1113
|
-
)
|
1114
|
-
end
|
1115
|
-
|
1116
1070
|
sig { params(package_name: String).returns(String) }
|
1117
1071
|
def sanitize_package_name(package_name)
|
1118
1072
|
package_name.gsub("%2f", "/").gsub("%2F", "/")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/npm_and_yarn/helpers"
|
@@ -9,24 +9,47 @@ require "dependabot/shared_helpers"
|
|
9
9
|
module Dependabot
|
10
10
|
module NpmAndYarn
|
11
11
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
12
13
|
class PnpmLockfileUpdater
|
14
|
+
extend T::Sig
|
15
|
+
|
13
16
|
require_relative "npmrc_builder"
|
14
17
|
require_relative "package_json_updater"
|
15
18
|
|
19
|
+
sig do
|
20
|
+
params(
|
21
|
+
dependencies: T::Array[Dependabot::Dependency],
|
22
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
23
|
+
repo_contents_path: T.nilable(String),
|
24
|
+
credentials: T::Array[Dependabot::Credential]
|
25
|
+
).void
|
26
|
+
end
|
16
27
|
def initialize(dependencies:, dependency_files:, repo_contents_path:, credentials:)
|
17
28
|
@dependencies = dependencies
|
18
29
|
@dependency_files = dependency_files
|
19
30
|
@repo_contents_path = repo_contents_path
|
20
31
|
@credentials = credentials
|
21
|
-
@error_handler =
|
22
|
-
|
23
|
-
|
32
|
+
@error_handler = T.let(
|
33
|
+
PnpmErrorHandler.new(
|
34
|
+
dependencies: dependencies,
|
35
|
+
dependency_files: dependency_files
|
36
|
+
),
|
37
|
+
PnpmErrorHandler
|
24
38
|
)
|
25
39
|
end
|
26
40
|
|
41
|
+
sig do
|
42
|
+
params(
|
43
|
+
pnpm_lock: Dependabot::DependencyFile,
|
44
|
+
updated_pnpm_workspace_content: T.nilable(T::Hash[String, T.nilable(String)])
|
45
|
+
).returns(String)
|
46
|
+
end
|
27
47
|
def updated_pnpm_lock_content(pnpm_lock, updated_pnpm_workspace_content: nil)
|
28
|
-
@updated_pnpm_lock_content ||=
|
29
|
-
|
48
|
+
@updated_pnpm_lock_content ||= T.let(
|
49
|
+
{},
|
50
|
+
T.nilable(T::Hash[String, String])
|
51
|
+
)
|
52
|
+
return T.must(@updated_pnpm_lock_content[pnpm_lock.name]) if @updated_pnpm_lock_content[pnpm_lock.name]
|
30
53
|
|
31
54
|
new_content = run_pnpm_update(
|
32
55
|
pnpm_lock: pnpm_lock,
|
@@ -39,10 +62,19 @@ module Dependabot
|
|
39
62
|
|
40
63
|
private
|
41
64
|
|
65
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
42
66
|
attr_reader :dependencies
|
67
|
+
|
68
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
43
69
|
attr_reader :dependency_files
|
70
|
+
|
71
|
+
sig { returns(T.nilable(String)) }
|
44
72
|
attr_reader :repo_contents_path
|
73
|
+
|
74
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
45
75
|
attr_reader :credentials
|
76
|
+
|
77
|
+
sig { returns(PnpmErrorHandler) }
|
46
78
|
attr_reader :error_handler
|
47
79
|
|
48
80
|
IRRESOLVABLE_PACKAGE = "ERR_PNPM_NO_MATCHING_VERSION"
|
@@ -103,6 +135,13 @@ module Dependabot
|
|
103
135
|
# Peer dependencies configuration error
|
104
136
|
ERR_PNPM_PEER_DEP_ISSUES = /ERR_PNPM_PEER_DEP_ISSUES/
|
105
137
|
|
138
|
+
sig do
|
139
|
+
params(
|
140
|
+
pnpm_lock: Dependabot::DependencyFile,
|
141
|
+
updated_pnpm_workspace_content: T.nilable(T::Hash[String, T.nilable(String)])
|
142
|
+
)
|
143
|
+
.returns(String)
|
144
|
+
end
|
106
145
|
def run_pnpm_update(pnpm_lock:, updated_pnpm_workspace_content: nil)
|
107
146
|
SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
|
108
147
|
File.write(".npmrc", npmrc_content(pnpm_lock))
|
@@ -122,6 +161,7 @@ module Dependabot
|
|
122
161
|
end
|
123
162
|
end
|
124
163
|
|
164
|
+
sig { returns(T.nilable(String)) }
|
125
165
|
def run_pnpm_update_packages
|
126
166
|
dependency_updates = dependencies.map do |d|
|
127
167
|
"#{d.name}@#{d.version}"
|
@@ -133,18 +173,24 @@ module Dependabot
|
|
133
173
|
)
|
134
174
|
end
|
135
175
|
|
176
|
+
sig { returns(T.nilable(String)) }
|
136
177
|
def run_pnpm_install
|
137
178
|
Helpers.run_pnpm_command(
|
138
179
|
"install --lockfile-only"
|
139
180
|
)
|
140
181
|
end
|
141
182
|
|
183
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
142
184
|
def workspace_files
|
143
|
-
@workspace_files ||=
|
185
|
+
@workspace_files ||= T.let(
|
186
|
+
dependency_files.select { |f| f.name.end_with?("pnpm-workspace.yaml") },
|
187
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
188
|
+
)
|
144
189
|
end
|
145
190
|
|
191
|
+
sig { params(lockfile: Dependabot::DependencyFile).returns(T::Array[Dependabot::Dependency]) }
|
146
192
|
def lockfile_dependencies(lockfile)
|
147
|
-
@lockfile_dependencies ||= {}
|
193
|
+
@lockfile_dependencies ||= T.let({}, T.nilable(T::Hash[String, T::Array[Dependabot::Dependency]]))
|
148
194
|
@lockfile_dependencies[lockfile.name] ||=
|
149
195
|
NpmAndYarn::FileParser.new(
|
150
196
|
dependency_files: [lockfile, *package_files, *workspace_files],
|
@@ -157,6 +203,13 @@ module Dependabot
|
|
157
203
|
# rubocop:disable Metrics/PerceivedComplexity
|
158
204
|
# rubocop:disable Metrics/MethodLength
|
159
205
|
# rubocop:disable Metrics/CyclomaticComplexity
|
206
|
+
sig do
|
207
|
+
params(
|
208
|
+
error: SharedHelpers::HelperSubprocessFailed,
|
209
|
+
pnpm_lock: Dependabot::DependencyFile
|
210
|
+
)
|
211
|
+
.returns(T.noreturn)
|
212
|
+
end
|
160
213
|
def handle_pnpm_lock_updater_error(error, pnpm_lock)
|
161
214
|
error_message = error.message
|
162
215
|
|
@@ -165,15 +218,15 @@ module Dependabot
|
|
165
218
|
end
|
166
219
|
|
167
220
|
if error_message.match?(UNREACHABLE_GIT)
|
168
|
-
url = error_message.match(UNREACHABLE_GIT)
|
221
|
+
url = error_message.match(UNREACHABLE_GIT)&.named_captures&.fetch("url")&.gsub("git+ssh://git@", "https://")&.delete_suffix(".git")
|
169
222
|
|
170
|
-
raise Dependabot::GitDependenciesNotReachable, url
|
223
|
+
raise Dependabot::GitDependenciesNotReachable, T.must(url)
|
171
224
|
end
|
172
225
|
|
173
226
|
if error_message.match?(UNREACHABLE_GIT_V8)
|
174
|
-
url = error_message.match(UNREACHABLE_GIT_V8)
|
227
|
+
url = error_message.match(UNREACHABLE_GIT_V8)&.named_captures&.fetch("url")&.gsub("codeload.", "")
|
175
228
|
|
176
|
-
raise Dependabot::GitDependenciesNotReachable, url
|
229
|
+
raise Dependabot::GitDependenciesNotReachable, T.must(url)
|
177
230
|
end
|
178
231
|
|
179
232
|
[FORBIDDEN_PACKAGE, MISSING_PACKAGE, UNAUTHORIZED_PACKAGE, ERR_PNPM_FETCH_401,
|
@@ -181,14 +234,13 @@ module Dependabot
|
|
181
234
|
.each do |regexp|
|
182
235
|
next unless error_message.match?(regexp)
|
183
236
|
|
184
|
-
dependency_url = error_message.match(regexp)
|
237
|
+
dependency_url = T.must(error_message.match(regexp)&.named_captures&.[]("dependency_url"))
|
185
238
|
raise_package_access_error(error_message, dependency_url, pnpm_lock)
|
186
239
|
end
|
187
240
|
|
188
241
|
# TO-DO : subclassifcation of ERR_PNPM_TARBALL_INTEGRITY errors
|
189
242
|
if error_message.match?(ERR_PNPM_TARBALL_INTEGRITY)
|
190
243
|
dependency_names = dependencies.map(&:name).join(", ")
|
191
|
-
|
192
244
|
msg = "Error (ERR_PNPM_TARBALL_INTEGRITY) while resolving \"#{dependency_names}\"."
|
193
245
|
Dependabot.logger.warn(error_message)
|
194
246
|
raise Dependabot::DependencyFileNotResolvable, msg
|
@@ -197,20 +249,17 @@ module Dependabot
|
|
197
249
|
# TO-DO : investigate "packageManager" allowed regex
|
198
250
|
if error_message.match?(INVALID_PACKAGE_SPEC)
|
199
251
|
dependency_names = dependencies.map(&:name).join(", ")
|
200
|
-
|
201
252
|
msg = "Invalid package manager specification in package.json while resolving \"#{dependency_names}\"."
|
202
253
|
raise Dependabot::DependencyFileNotResolvable, msg
|
203
254
|
end
|
204
255
|
|
205
256
|
if error_message.match?(ERR_PNPM_META_FETCH_FAIL)
|
206
|
-
|
207
257
|
msg = error_message.split(ERR_PNPM_META_FETCH_FAIL).last
|
208
258
|
raise Dependabot::DependencyFileNotResolvable, msg
|
209
259
|
end
|
210
260
|
|
211
261
|
if error_message.match?(ERR_PNPM_WORKSPACE_PKG_NOT_FOUND)
|
212
262
|
dependency_names = dependencies.map(&:name).join(", ")
|
213
|
-
|
214
263
|
msg = "No package named \"#{dependency_names}\" present in workspace."
|
215
264
|
Dependabot.logger.warn(error_message)
|
216
265
|
raise Dependabot::DependencyFileNotResolvable, msg
|
@@ -223,8 +272,8 @@ module Dependabot
|
|
223
272
|
end
|
224
273
|
|
225
274
|
if error_message.match?(ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND)
|
226
|
-
dir = error_message.match(ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND)
|
227
|
-
msg = "Could not find linked package installation directory \"#{dir
|
275
|
+
dir = error_message.match(ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND)&.named_captures&.fetch("dir")
|
276
|
+
msg = "Could not find linked package installation directory \"#{dir&.split('/')&.last}\""
|
228
277
|
raise Dependabot::DependencyFileNotResolvable, msg
|
229
278
|
end
|
230
279
|
|
@@ -246,13 +295,11 @@ module Dependabot
|
|
246
295
|
|
247
296
|
if error_message.match?(ERR_PNPM_PEER_DEP_ISSUES)
|
248
297
|
msg = "Missing or invalid configuration while installing peer dependencies."
|
249
|
-
|
250
298
|
Dependabot.logger.warn(error_message)
|
251
299
|
raise Dependabot::DependencyFileNotResolvable, msg
|
252
300
|
end
|
253
301
|
|
254
302
|
raise_patch_dependency_error(error_message) if error_message.match?(ERR_PNPM_PATCH_NOT_APPLIED)
|
255
|
-
|
256
303
|
raise_unsupported_engine_error(error_message, pnpm_lock) if error_message.match?(ERR_PNPM_UNSUPPORTED_ENGINE)
|
257
304
|
|
258
305
|
if error_message.match?(ERR_INVALID_THIS) && error_message.match?(URL_SEARCH_PARAMS)
|
@@ -262,8 +309,7 @@ module Dependabot
|
|
262
309
|
end
|
263
310
|
|
264
311
|
if error_message.match?(ERR_PNPM_UNSUPPORTED_PLATFORM)
|
265
|
-
raise_unsupported_platform_error(error_message,
|
266
|
-
pnpm_lock)
|
312
|
+
raise_unsupported_platform_error(error_message, pnpm_lock)
|
267
313
|
end
|
268
314
|
|
269
315
|
error_handler.handle_pnpm_error(error)
|
@@ -275,6 +321,7 @@ module Dependabot
|
|
275
321
|
# rubocop:enable Metrics/MethodLength
|
276
322
|
# rubocop:enable Metrics/CyclomaticComplexity
|
277
323
|
|
324
|
+
sig { params(error_message: String, pnpm_lock: Dependabot::DependencyFile).returns(T.noreturn) }
|
278
325
|
def raise_resolvability_error(error_message, pnpm_lock)
|
279
326
|
dependency_names = dependencies.map(&:name).join(", ")
|
280
327
|
msg = "Error whilst updating #{dependency_names} in " \
|
@@ -282,6 +329,7 @@ module Dependabot
|
|
282
329
|
raise Dependabot::DependencyFileNotResolvable, msg
|
283
330
|
end
|
284
331
|
|
332
|
+
sig { params(error_message: String).returns(T.noreturn) }
|
285
333
|
def raise_patch_dependency_error(error_message)
|
286
334
|
dependency_names = dependencies.map(&:name).join(", ")
|
287
335
|
msg = "Error while updating \"#{dependency_names}\" in " \
|
@@ -290,21 +338,50 @@ module Dependabot
|
|
290
338
|
raise Dependabot::DependencyFileNotResolvable, msg
|
291
339
|
end
|
292
340
|
|
341
|
+
sig do
|
342
|
+
params(
|
343
|
+
error_message: String,
|
344
|
+
_pnpm_lock: Dependabot::DependencyFile
|
345
|
+
).returns(T.nilable(T.noreturn))
|
346
|
+
end
|
293
347
|
def raise_unsupported_engine_error(error_message, _pnpm_lock)
|
294
|
-
|
295
|
-
|
296
|
-
|
348
|
+
match_pkg_mgr = error_message.match(PACAKGE_MANAGER)
|
349
|
+
match_version = error_message.match(VERSION_REQUIREMENT)
|
350
|
+
|
351
|
+
unless match_pkg_mgr && match_version &&
|
352
|
+
match_pkg_mgr.named_captures && match_version.named_captures
|
353
|
+
return nil
|
297
354
|
end
|
298
355
|
|
299
|
-
|
300
|
-
|
301
|
-
|
356
|
+
captures_pkg_mgr = match_pkg_mgr.named_captures
|
357
|
+
captures_version = match_version.named_captures
|
358
|
+
|
359
|
+
pkg_mgr = captures_pkg_mgr["pkg_mgr"]
|
360
|
+
supported_ver = captures_version["supported_ver"]
|
361
|
+
detected_ver = captures_version["detected_ver"]
|
362
|
+
|
363
|
+
if pkg_mgr && supported_ver && detected_ver
|
364
|
+
raise Dependabot::ToolVersionNotSupported.new(
|
365
|
+
pkg_mgr,
|
366
|
+
supported_ver,
|
367
|
+
detected_ver
|
368
|
+
)
|
369
|
+
end
|
302
370
|
|
303
|
-
|
371
|
+
nil
|
304
372
|
end
|
305
373
|
|
374
|
+
sig do
|
375
|
+
params(
|
376
|
+
error_message: String,
|
377
|
+
dependency_url: String,
|
378
|
+
pnpm_lock: Dependabot::DependencyFile
|
379
|
+
)
|
380
|
+
.returns(T.noreturn)
|
381
|
+
end
|
306
382
|
def raise_package_access_error(error_message, dependency_url, pnpm_lock)
|
307
|
-
package_name = RegistryParser.new(resolved_url: dependency_url,
|
383
|
+
package_name = RegistryParser.new(resolved_url: dependency_url,
|
384
|
+
credentials: credentials).dependency_name
|
308
385
|
missing_dep = lockfile_dependencies(pnpm_lock)
|
309
386
|
.find { |dep| dep.name == package_name }
|
310
387
|
raise DependencyNotFound, package_name unless missing_dep
|
@@ -318,6 +395,7 @@ module Dependabot
|
|
318
395
|
raise PrivateSourceAuthenticationFailure, reg
|
319
396
|
end
|
320
397
|
|
398
|
+
sig { void }
|
321
399
|
def write_final_package_json_files
|
322
400
|
package_files.each do |file|
|
323
401
|
path = file.name
|
@@ -326,57 +404,88 @@ module Dependabot
|
|
326
404
|
end
|
327
405
|
end
|
328
406
|
|
407
|
+
sig do
|
408
|
+
params(
|
409
|
+
error_message: String,
|
410
|
+
_pnpm_lock: Dependabot::DependencyFile
|
411
|
+
)
|
412
|
+
.returns(T.nilable(T.noreturn))
|
413
|
+
end
|
329
414
|
def raise_unsupported_platform_error(error_message, _pnpm_lock)
|
330
|
-
|
331
|
-
|
332
|
-
|
415
|
+
match_dep = error_message.match(PLATFORM_PACAKGE_DEP)
|
416
|
+
match_version = error_message.match(PLATFORM_VERSION_REQUIREMENT)
|
417
|
+
|
418
|
+
unless match_dep && match_version &&
|
419
|
+
match_dep.named_captures && match_version.named_captures
|
420
|
+
return nil
|
333
421
|
end
|
334
422
|
|
335
|
-
|
336
|
-
.named_captures["supported_ver"]
|
337
|
-
.then { sanitize_message(_1) }
|
338
|
-
detected_version = error_message.match(PLATFORM_VERSION_REQUIREMENT)
|
339
|
-
.named_captures["detected_ver"]
|
340
|
-
.then { sanitize_message(_1) }
|
423
|
+
captures_version = match_version.named_captures
|
341
424
|
|
342
|
-
|
343
|
-
|
425
|
+
supported_ver = captures_version["supported_ver"]
|
426
|
+
detected_ver = captures_version["detected_ver"]
|
427
|
+
|
428
|
+
if supported_ver && detected_ver
|
429
|
+
supported_version = sanitize_message(supported_ver)
|
430
|
+
detected_version = sanitize_message(detected_ver)
|
431
|
+
|
432
|
+
Dependabot.logger.warn(error_message)
|
433
|
+
raise Dependabot::ToolVersionNotSupported.new(
|
434
|
+
PLATFORM_PACAKGE_MANAGER,
|
435
|
+
supported_version,
|
436
|
+
detected_version
|
437
|
+
)
|
438
|
+
end
|
439
|
+
|
440
|
+
nil
|
344
441
|
end
|
345
442
|
|
443
|
+
sig { params(pnpm_lock: Dependabot::DependencyFile).returns(String) }
|
346
444
|
def npmrc_content(pnpm_lock)
|
347
445
|
NpmrcBuilder.new(
|
348
|
-
credentials: credentials,
|
446
|
+
credentials: T.unsafe(credentials),
|
349
447
|
dependency_files: dependency_files,
|
350
448
|
dependencies: lockfile_dependencies(pnpm_lock)
|
351
449
|
).npmrc_content
|
352
450
|
end
|
353
451
|
|
452
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
354
453
|
def updated_package_json_content(file)
|
355
|
-
@updated_package_json_content ||= {}
|
454
|
+
@updated_package_json_content ||= T.let({}, T.nilable(T::Hash[String, String]))
|
356
455
|
@updated_package_json_content[file.name] ||=
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
456
|
+
T.must(
|
457
|
+
PackageJsonUpdater.new(
|
458
|
+
package_json: file,
|
459
|
+
dependencies: dependencies
|
460
|
+
).updated_package_json.content
|
461
|
+
)
|
361
462
|
end
|
362
463
|
|
464
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
363
465
|
def package_files
|
364
|
-
@package_files ||=
|
466
|
+
@package_files ||= T.let(
|
467
|
+
dependency_files.select { |f| f.name.end_with?("package.json") },
|
468
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
469
|
+
)
|
365
470
|
end
|
366
471
|
|
472
|
+
sig { returns(String) }
|
367
473
|
def base_dir
|
368
|
-
dependency_files.first.directory
|
474
|
+
T.must(dependency_files.first).directory
|
369
475
|
end
|
370
476
|
|
477
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
371
478
|
def npmrc_file
|
372
479
|
dependency_files.find { |f| f.name == ".npmrc" }
|
373
480
|
end
|
374
481
|
|
482
|
+
sig { params(message: String).returns(String) }
|
375
483
|
def sanitize_message(message)
|
376
484
|
message.gsub(/"|\[|\]|\}|\{/, "")
|
377
485
|
end
|
378
486
|
end
|
379
487
|
end
|
488
|
+
# rubocop:enable Metrics/ClassLength
|
380
489
|
|
381
490
|
class PnpmErrorHandler
|
382
491
|
extend T::Sig
|
@@ -400,7 +509,8 @@ module Dependabot
|
|
400
509
|
params(
|
401
510
|
dependencies: T::Array[Dependabot::Dependency],
|
402
511
|
dependency_files: T::Array[Dependabot::DependencyFile]
|
403
|
-
)
|
512
|
+
)
|
513
|
+
.void
|
404
514
|
end
|
405
515
|
def initialize(dependencies:, dependency_files:)
|
406
516
|
@dependencies = dependencies
|
@@ -43,39 +43,17 @@ module Dependabot
|
|
43
43
|
# corepack supported package managers
|
44
44
|
SUPPORTED_COREPACK_PACKAGE_MANAGERS = %w(npm yarn pnpm).freeze
|
45
45
|
|
46
|
-
# Determines the npm version depends to the feature flag
|
47
|
-
# If the feature flag is enabled, we are going to use the minimum version npm 8
|
48
|
-
# Otherwise, we are going to use old versionining npm 6
|
49
46
|
sig { params(lockfile: T.nilable(DependencyFile)).returns(Integer) }
|
50
47
|
def self.npm_version_numeric(lockfile)
|
51
|
-
|
48
|
+
detected_npm_version = detect_npm_version(lockfile)
|
52
49
|
|
53
|
-
return
|
50
|
+
return NPM_DEFAULT_VERSION if detected_npm_version.nil? || detected_npm_version == NPM_V6
|
54
51
|
|
55
|
-
|
52
|
+
detected_npm_version
|
56
53
|
end
|
57
54
|
|
58
|
-
sig { params(lockfile: T.nilable(DependencyFile)).returns(Integer) }
|
59
|
-
def self.
|
60
|
-
lockfile_content = lockfile&.content
|
61
|
-
|
62
|
-
if lockfile_content.nil? ||
|
63
|
-
lockfile_content.strip.empty? ||
|
64
|
-
JSON.parse(lockfile_content)["lockfileVersion"].to_i >= 2
|
65
|
-
return NPM_V8
|
66
|
-
end
|
67
|
-
|
68
|
-
NPM_V6
|
69
|
-
rescue JSON::ParserError
|
70
|
-
NPM_V6
|
71
|
-
end
|
72
|
-
|
73
|
-
# Determines the npm version based on the lockfile version
|
74
|
-
# - NPM 7 uses lockfileVersion 2
|
75
|
-
# - NPM 8 uses lockfileVersion 2
|
76
|
-
# - NPM 9 uses lockfileVersion 3
|
77
|
-
sig { params(lockfile: T.nilable(DependencyFile)).returns(Integer) }
|
78
|
-
def self.npm_version_numeric_npm8_or_higher(lockfile)
|
55
|
+
sig { params(lockfile: T.nilable(DependencyFile)).returns(T.nilable(Integer)) }
|
56
|
+
def self.detect_npm_version(lockfile)
|
79
57
|
lockfile_content = lockfile&.content
|
80
58
|
|
81
59
|
# Return default NPM version if there's no lockfile or it's empty
|
@@ -94,40 +72,13 @@ module Dependabot
|
|
94
72
|
# Update needed to support npm 9+ based on lockfile version.
|
95
73
|
return NPM_V8 if lockfile_version >= 2
|
96
74
|
|
97
|
-
|
75
|
+
NPM_V6 if lockfile_version >= 1
|
76
|
+
# Return nil if can't capture
|
98
77
|
rescue JSON::ParserError
|
99
78
|
NPM_DEFAULT_VERSION # Fallback to default npm version if parsing fails
|
100
79
|
end
|
101
80
|
|
102
|
-
|
103
|
-
sig { params(lockfile: T.nilable(DependencyFile)).returns(Integer) }
|
104
|
-
def self.npm_version_numeric_latest(lockfile)
|
105
|
-
lockfile_content = lockfile&.content
|
106
|
-
|
107
|
-
# Return npm 10 as the default if the lockfile is missing or empty
|
108
|
-
return NPM_V10 if lockfile_content.nil? || lockfile_content.strip.empty?
|
109
|
-
|
110
|
-
# Parse the lockfile content to extract the `lockfileVersion`
|
111
|
-
parsed_lockfile = JSON.parse(lockfile_content)
|
112
|
-
lockfile_version = parsed_lockfile["lockfileVersion"]&.to_i
|
113
|
-
|
114
|
-
# Determine the appropriate npm version based on `lockfileVersion`
|
115
|
-
if lockfile_version.nil?
|
116
|
-
NPM_V10 # Use npm 10 if `lockfileVersion` is missing or nil
|
117
|
-
elsif lockfile_version >= 3
|
118
|
-
NPM_V10 # Use npm 10 for lockfileVersion 3 or higher
|
119
|
-
elsif lockfile_version >= 2
|
120
|
-
NPM_V8 # Use npm 8 for lockfileVersion 2
|
121
|
-
elsif lockfile_version >= 1
|
122
|
-
# Use npm 8 if the fallback version flag is enabled, otherwise use npm 6
|
123
|
-
Dependabot::Experiments.enabled?(:npm_fallback_version_above_v6) ? NPM_V8 : NPM_V6
|
124
|
-
else
|
125
|
-
NPM_V10 # Default to npm 10 for unexpected or unsupported versions
|
126
|
-
end
|
127
|
-
rescue JSON::ParserError
|
128
|
-
NPM_V8 # Fallback to npm 8 if the lockfile content cannot be parsed
|
129
|
-
end
|
130
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
81
|
+
private_class_method :detect_npm_version
|
131
82
|
|
132
83
|
sig { params(yarn_lock: T.nilable(DependencyFile)).returns(Integer) }
|
133
84
|
def self.yarn_version_numeric(yarn_lock)
|
@@ -179,10 +130,12 @@ module Dependabot
|
|
179
130
|
end
|
180
131
|
|
181
132
|
sig { params(package_lock: T.nilable(DependencyFile)).returns(T::Boolean) }
|
182
|
-
def self.
|
133
|
+
def self.parse_npm8?(package_lock)
|
183
134
|
return true unless package_lock&.content
|
184
135
|
|
185
|
-
|
136
|
+
detected_npm = detect_npm_version(package_lock)
|
137
|
+
# For conversion reading properly from npm 6 lockfile we need to check if detected version is npm 6
|
138
|
+
detected_npm.nil? || detected_npm != NPM_V6
|
186
139
|
end
|
187
140
|
|
188
141
|
sig { params(yarn_lock: T.nilable(DependencyFile)).returns(T::Boolean) }
|
@@ -129,15 +129,20 @@ module Dependabot
|
|
129
129
|
|
130
130
|
sig do
|
131
131
|
params(
|
132
|
-
details: T.nilable(T.any(String, T::Hash[String,
|
133
|
-
)
|
134
|
-
.returns(T.nilable(String))
|
132
|
+
details: T.nilable(T.any(String, T::Array[String], T::Hash[String, String]))
|
133
|
+
).returns(T.nilable(String))
|
135
134
|
end
|
136
135
|
def get_url(details)
|
136
|
+
return unless details
|
137
|
+
|
137
138
|
url =
|
138
139
|
case details
|
139
140
|
when String then details
|
140
141
|
when Hash then details.fetch("url", nil)
|
142
|
+
when Array
|
143
|
+
# Try to find the first valid URL string, and if not, return the first string (even if it isn't a URL)
|
144
|
+
details.find { |d| d.is_a?(String) && d.match?(%r{^[\w.-]+/[\w.-]+$}) } ||
|
145
|
+
details.find { |d| d.is_a?(String) }
|
141
146
|
end
|
142
147
|
return url unless url&.match?(%r{^[\w.-]+/[\w.-]+$})
|
143
148
|
|
@@ -215,6 +220,9 @@ module Dependabot
|
|
215
220
|
new_source&.fetch(:url)
|
216
221
|
end
|
217
222
|
|
223
|
+
# spaces must be escaped in base URL
|
224
|
+
registry_url = registry_url.gsub(" ", "%20")
|
225
|
+
|
218
226
|
# NPM registries expect slashes to be escaped
|
219
227
|
escaped_dependency_name = dependency.name.gsub("/", "%2F")
|
220
228
|
"#{registry_url}/#{escaped_dependency_name}"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/dependency"
|
@@ -12,11 +12,42 @@ require "dependabot/npm_and_yarn/update_checker"
|
|
12
12
|
require "dependabot/npm_and_yarn/update_checker/dependency_files_builder"
|
13
13
|
require "dependabot/npm_and_yarn/version"
|
14
14
|
require "dependabot/shared_helpers"
|
15
|
+
require "sorbet-runtime"
|
15
16
|
|
16
17
|
module Dependabot
|
17
18
|
module NpmAndYarn
|
18
19
|
class UpdateChecker
|
19
20
|
class SubdependencyVersionResolver
|
21
|
+
extend T::Sig
|
22
|
+
|
23
|
+
sig { returns(Dependency) }
|
24
|
+
attr_reader :dependency
|
25
|
+
|
26
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
27
|
+
attr_reader :credentials
|
28
|
+
|
29
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
30
|
+
attr_reader :dependency_files
|
31
|
+
|
32
|
+
sig { returns(T::Array[String]) }
|
33
|
+
attr_reader :ignored_versions
|
34
|
+
|
35
|
+
sig { returns(T.nilable(T.any(String, Gem::Version))) }
|
36
|
+
attr_reader :latest_allowable_version
|
37
|
+
|
38
|
+
sig { returns(T.nilable(String)) }
|
39
|
+
attr_reader :repo_contents_path
|
40
|
+
|
41
|
+
sig do
|
42
|
+
params(
|
43
|
+
dependency: Dependency,
|
44
|
+
credentials: T::Array[Dependabot::Credential],
|
45
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
46
|
+
ignored_versions: T::Array[String],
|
47
|
+
latest_allowable_version: T.nilable(T.any(String, Gem::Version)),
|
48
|
+
repo_contents_path: T.nilable(String)
|
49
|
+
).void
|
50
|
+
end
|
20
51
|
def initialize(dependency:, credentials:, dependency_files:,
|
21
52
|
ignored_versions:, latest_allowable_version:, repo_contents_path:)
|
22
53
|
@dependency = dependency
|
@@ -27,11 +58,12 @@ module Dependabot
|
|
27
58
|
@repo_contents_path = repo_contents_path
|
28
59
|
end
|
29
60
|
|
61
|
+
sig { returns(T.nilable(T.any(String, Gem::Version))) }
|
30
62
|
def latest_resolvable_version
|
31
63
|
raise "Not a subdependency!" if dependency.requirements.any?
|
32
64
|
return if bundled_dependency?
|
33
65
|
|
34
|
-
base_dir = dependency_files.first.directory
|
66
|
+
base_dir = T.must(dependency_files.first).directory
|
35
67
|
SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
|
36
68
|
dependency_files_builder.write_temporary_dependency_files
|
37
69
|
|
@@ -53,13 +85,7 @@ module Dependabot
|
|
53
85
|
|
54
86
|
private
|
55
87
|
|
56
|
-
|
57
|
-
attr_reader :credentials
|
58
|
-
attr_reader :dependency_files
|
59
|
-
attr_reader :ignored_versions
|
60
|
-
attr_reader :latest_allowable_version
|
61
|
-
attr_reader :repo_contents_path
|
62
|
-
|
88
|
+
sig { params(lockfile: Dependabot::DependencyFile).returns(String) }
|
63
89
|
def update_subdependency_in_lockfile(lockfile)
|
64
90
|
lockfile_name = Pathname.new(lockfile.name).basename.to_s
|
65
91
|
path = Pathname.new(lockfile.name).dirname.to_s
|
@@ -72,7 +98,7 @@ module Dependabot
|
|
72
98
|
run_pnpm_updater(path, lockfile_name)
|
73
99
|
elsif lockfile.name.end_with?("bun.lock")
|
74
100
|
run_bun_updater(path, lockfile_name)
|
75
|
-
elsif !Helpers.
|
101
|
+
elsif !Helpers.parse_npm8?(lockfile)
|
76
102
|
run_npm6_updater(path, lockfile_name)
|
77
103
|
else
|
78
104
|
run_npm_updater(path, lockfile_name)
|
@@ -81,6 +107,7 @@ module Dependabot
|
|
81
107
|
updated_files.fetch(lockfile_name)
|
82
108
|
end
|
83
109
|
|
110
|
+
sig { params(updated_lockfiles: T::Array[Dependabot::DependencyFile]).returns(T.nilable(Gem::Version)) }
|
84
111
|
def version_from_updated_lockfiles(updated_lockfiles)
|
85
112
|
updated_files = dependency_files -
|
86
113
|
dependency_files_builder.lockfiles +
|
@@ -96,13 +123,17 @@ module Dependabot
|
|
96
123
|
version_class.new(updated_version)
|
97
124
|
end
|
98
125
|
|
126
|
+
sig { params(path: String, lockfile_name: String).returns(T::Hash[String, String]) }
|
99
127
|
def run_yarn_updater(path, lockfile_name)
|
100
128
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
101
129
|
Dir.chdir(path) do
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
130
|
+
T.cast(
|
131
|
+
SharedHelpers.run_helper_subprocess(
|
132
|
+
command: NativeHelpers.helper_path,
|
133
|
+
function: "yarn:updateSubdependency",
|
134
|
+
args: [Dir.pwd, lockfile_name, [dependency.to_h]]
|
135
|
+
),
|
136
|
+
T::Hash[String, String]
|
106
137
|
)
|
107
138
|
end
|
108
139
|
end
|
@@ -121,6 +152,7 @@ module Dependabot
|
|
121
152
|
retry
|
122
153
|
end
|
123
154
|
|
155
|
+
sig { params(path: String, lockfile_name: String).returns(T::Hash[String, String]) }
|
124
156
|
def run_yarn_berry_updater(path, lockfile_name)
|
125
157
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
126
158
|
Dir.chdir(path) do
|
@@ -133,6 +165,7 @@ module Dependabot
|
|
133
165
|
end
|
134
166
|
end
|
135
167
|
|
168
|
+
sig { params(path: String, lockfile_name: String).returns(T::Hash[String, String]) }
|
136
169
|
def run_pnpm_updater(path, lockfile_name)
|
137
170
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
138
171
|
Dir.chdir(path) do
|
@@ -145,6 +178,7 @@ module Dependabot
|
|
145
178
|
end
|
146
179
|
end
|
147
180
|
|
181
|
+
sig { params(path: String, lockfile_name: String).returns(T::Hash[String, String]) }
|
148
182
|
def run_npm_updater(path, lockfile_name)
|
149
183
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
150
184
|
Dir.chdir(path) do
|
@@ -155,6 +189,7 @@ module Dependabot
|
|
155
189
|
end
|
156
190
|
end
|
157
191
|
|
192
|
+
sig { params(path: String, lockfile_name: String).returns(T::Hash[String, String]) }
|
158
193
|
def run_bun_updater(path, lockfile_name)
|
159
194
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
160
195
|
Dir.chdir(path) do
|
@@ -167,6 +202,7 @@ module Dependabot
|
|
167
202
|
end
|
168
203
|
end
|
169
204
|
|
205
|
+
sig { params(path: String, lockfile_name: String).returns(T::Hash[String, String]) }
|
170
206
|
def run_npm6_updater(path, lockfile_name)
|
171
207
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
172
208
|
Dir.chdir(path) do
|
@@ -179,53 +215,46 @@ module Dependabot
|
|
179
215
|
end
|
180
216
|
end
|
181
217
|
|
218
|
+
sig { returns(T.class_of(Dependabot::Version)) }
|
182
219
|
def version_class
|
183
220
|
dependency.version_class
|
184
221
|
end
|
185
222
|
|
223
|
+
sig { returns(Dependabot::Dependency) }
|
186
224
|
def updated_dependency
|
187
225
|
Dependabot::Dependency.new(
|
188
226
|
name: dependency.name,
|
189
|
-
version: latest_allowable_version,
|
227
|
+
version: T.cast(latest_allowable_version, T.nilable(T.any(String, Dependabot::Version))),
|
190
228
|
previous_version: dependency.version,
|
191
229
|
requirements: [],
|
192
230
|
package_manager: dependency.package_manager
|
193
231
|
)
|
194
232
|
end
|
195
233
|
|
234
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
196
235
|
def filtered_lockfiles
|
197
|
-
@filtered_lockfiles ||=
|
236
|
+
@filtered_lockfiles ||= T.let(
|
198
237
|
SubDependencyFilesFilterer.new(
|
199
238
|
dependency_files: dependency_files,
|
200
239
|
updated_dependencies: [updated_dependency]
|
201
|
-
).files_requiring_update
|
240
|
+
).files_requiring_update,
|
241
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
242
|
+
)
|
202
243
|
end
|
203
244
|
|
245
|
+
sig { returns(Dependabot::NpmAndYarn::UpdateChecker::DependencyFilesBuilder) }
|
204
246
|
def dependency_files_builder
|
205
|
-
@dependency_files_builder ||=
|
247
|
+
@dependency_files_builder ||= T.let(
|
206
248
|
DependencyFilesBuilder.new(
|
207
249
|
dependency: dependency,
|
208
250
|
dependency_files: dependency_files,
|
209
251
|
credentials: credentials
|
210
|
-
)
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
#
|
217
|
-
# We shouldn't update bundled sub-dependencies as they have been bundled
|
218
|
-
# into the release at an exact version by a parent using
|
219
|
-
# `bundledDependencies`.
|
220
|
-
#
|
221
|
-
# For example, fsevents < 2 bundles node-pre-gyp meaning all it's
|
222
|
-
# sub-dependencies get bundled into the release tarball at publish time
|
223
|
-
# so you always get the same sub-dependency versions if you re-install a
|
224
|
-
# specific version of fsevents.
|
225
|
-
#
|
226
|
-
# Updating the sub-dependency by deleting the entry works but it gets
|
227
|
-
# removed from the bundled set of dependencies and moved top level
|
228
|
-
# resulting in a bunch of package duplication which is pretty confusing.
|
252
|
+
),
|
253
|
+
T.nilable(Dependabot::NpmAndYarn::UpdateChecker::DependencyFilesBuilder)
|
254
|
+
)
|
255
|
+
end
|
256
|
+
|
257
|
+
sig { returns(T::Boolean) }
|
229
258
|
def bundled_dependency?
|
230
259
|
dependency.subdependency_metadata
|
231
260
|
&.any? { |h| h.fetch(:npm_bundled, false) } ||
|
@@ -825,7 +825,7 @@ module Dependabot
|
|
825
825
|
f.name == [path, "package-lock.json"].join("/").sub(%r{\A.?\/}, "")
|
826
826
|
end
|
827
827
|
|
828
|
-
return run_npm8_checker(version: version) if Dependabot::NpmAndYarn::Helpers.
|
828
|
+
return run_npm8_checker(version: version) if Dependabot::NpmAndYarn::Helpers.parse_npm8?(package_lock)
|
829
829
|
|
830
830
|
SharedHelpers.run_helper_subprocess(
|
831
831
|
command: NativeHelpers.helper_path,
|
@@ -43,7 +43,7 @@ module Dependabot
|
|
43
43
|
requirements_update_strategy: nil, dependency_group: nil,
|
44
44
|
update_cooldown: nil, options: {})
|
45
45
|
@latest_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
|
46
|
-
@latest_resolvable_version = T.let(nil, T.nilable(T.any(String,
|
46
|
+
@latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Dependabot::Version)))
|
47
47
|
@updated_requirements = T.let(nil, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
|
48
48
|
@vulnerability_audit = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
|
49
49
|
@vulnerable_versions = T.let(nil, T.nilable(T::Array[T.any(String, Gem::Version)]))
|
@@ -88,17 +88,23 @@ module Dependabot
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
-
sig { override.returns(T.nilable(T.any(String,
|
91
|
+
sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
|
92
92
|
def latest_resolvable_version
|
93
93
|
return unless latest_version
|
94
94
|
|
95
95
|
@latest_resolvable_version ||=
|
96
96
|
if dependency.top_level?
|
97
|
-
|
97
|
+
T.cast(
|
98
|
+
version_resolver.latest_resolvable_version,
|
99
|
+
T.nilable(T.any(String, Dependabot::Version))
|
100
|
+
)
|
98
101
|
else
|
99
102
|
# If the dependency is indirect its version is constrained by the
|
100
103
|
# requirements placed on it by dependencies lower down the tree
|
101
|
-
|
104
|
+
T.cast(
|
105
|
+
subdependency_version_resolver.latest_resolvable_version,
|
106
|
+
T.nilable(T.any(String, Dependabot::Version))
|
107
|
+
)
|
102
108
|
end
|
103
109
|
end
|
104
110
|
|
@@ -133,7 +139,11 @@ module Dependabot
|
|
133
139
|
|
134
140
|
sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
|
135
141
|
def latest_resolvable_version_with_no_unlock
|
136
|
-
|
142
|
+
unless dependency.top_level?
|
143
|
+
# TODO: We should use `Dependabot::Version` everywhere
|
144
|
+
return T.cast(latest_resolvable_version,
|
145
|
+
T.nilable(T.any(String, Dependabot::Version)))
|
146
|
+
end
|
137
147
|
|
138
148
|
return latest_resolvable_version_with_no_unlock_for_git_dependency if git_dependency?
|
139
149
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-npm_and_yarn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.311.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-05-01 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: dependabot-common
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.
|
18
|
+
version: 0.311.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.
|
25
|
+
version: 0.311.0
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: debug
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -223,16 +223,16 @@ dependencies:
|
|
223
223
|
name: webrick
|
224
224
|
requirement: !ruby/object:Gem::Requirement
|
225
225
|
requirements:
|
226
|
-
- - "
|
226
|
+
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
|
-
version: '1.
|
228
|
+
version: '1.9'
|
229
229
|
type: :development
|
230
230
|
prerelease: false
|
231
231
|
version_requirements: !ruby/object:Gem::Requirement
|
232
232
|
requirements:
|
233
|
-
- - "
|
233
|
+
- - "~>"
|
234
234
|
- !ruby/object:Gem::Version
|
235
|
-
version: '1.
|
235
|
+
version: '1.9'
|
236
236
|
description: Dependabot-NPM_And_Yarn provides support for bumping Javascript (npm
|
237
237
|
and yarn) libraries via Dependabot. If you want support for multiple package managers,
|
238
238
|
you probably want the meta-gem dependabot-omnibus.
|
@@ -356,7 +356,7 @@ licenses:
|
|
356
356
|
- MIT
|
357
357
|
metadata:
|
358
358
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
359
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
359
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.311.0
|
360
360
|
rdoc_options: []
|
361
361
|
require_paths:
|
362
362
|
- lib
|