dependabot-npm_and_yarn 0.216.2 → 0.218.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/helpers/lib/pnpm/index.js +5 -0
- data/helpers/lib/pnpm/lockfile-parser.js +77 -0
- data/helpers/package-lock.json +827 -207
- data/helpers/package.json +4 -2
- data/lib/dependabot/npm_and_yarn/dependency_files_filterer.rb +33 -2
- data/lib/dependabot/npm_and_yarn/file_fetcher.rb +129 -55
- data/lib/dependabot/npm_and_yarn/file_parser/lockfile_parser.rb +13 -4
- data/lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb +68 -0
- data/lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb +6 -0
- data/lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb +6 -4
- data/lib/dependabot/npm_and_yarn/file_updater/package_json_updater.rb +3 -2
- data/lib/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater.rb +145 -0
- data/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb +1 -1
- data/lib/dependabot/npm_and_yarn/file_updater.rb +38 -1
- data/lib/dependabot/npm_and_yarn/helpers.rb +13 -0
- data/lib/dependabot/npm_and_yarn/package_manager.rb +19 -0
- data/lib/dependabot/npm_and_yarn/sub_dependency_files_filterer.rb +2 -1
- data/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb +19 -2
- data/lib/dependabot/npm_and_yarn/update_checker/requirements_updater.rb +3 -1
- data/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb +15 -5
- data/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +56 -21
- data/lib/dependabot/npm_and_yarn/update_checker.rb +4 -0
- metadata +11 -6
data/helpers/package.json
CHANGED
@@ -14,12 +14,14 @@
|
|
14
14
|
"detect-indent": "^6.1.0",
|
15
15
|
"nock": "^13.3.0",
|
16
16
|
"npm": "6.14.18",
|
17
|
+
"@pnpm/lockfile-file": "^8.0.2",
|
18
|
+
"@pnpm/dependency-path": "^2.1.1",
|
17
19
|
"semver": "^7.4.0"
|
18
20
|
},
|
19
21
|
"devDependencies": {
|
20
|
-
"eslint": "^8.
|
22
|
+
"eslint": "^8.39.0",
|
21
23
|
"eslint-config-prettier": "^8.8.0",
|
22
24
|
"jest": "^29.5.0",
|
23
|
-
"prettier": "^2.8.
|
25
|
+
"prettier": "^2.8.8"
|
24
26
|
}
|
25
27
|
}
|
@@ -14,6 +14,10 @@ module Dependabot
|
|
14
14
|
@updated_dependencies = updated_dependencies
|
15
15
|
end
|
16
16
|
|
17
|
+
def paths_requiring_update_check
|
18
|
+
@paths_requiring_update_check ||= fetch_paths_requiring_update_check
|
19
|
+
end
|
20
|
+
|
17
21
|
def files_requiring_update
|
18
22
|
@files_requiring_update ||=
|
19
23
|
dependency_files.select do |file|
|
@@ -34,6 +38,15 @@ module Dependabot
|
|
34
38
|
|
35
39
|
attr_reader :dependency_files, :updated_dependencies
|
36
40
|
|
41
|
+
def fetch_paths_requiring_update_check
|
42
|
+
# if only a root lockfile exists, it tracks all dependencies
|
43
|
+
return [File.dirname(root_lockfile.name)] if lockfiles == [root_lockfile]
|
44
|
+
|
45
|
+
package_files_requiring_update.map do |file|
|
46
|
+
File.dirname(file.name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
37
50
|
def dependency_manifest_requirements
|
38
51
|
@dependency_manifest_requirements ||=
|
39
52
|
updated_dependencies.flat_map do |dep|
|
@@ -50,12 +63,29 @@ module Dependabot
|
|
50
63
|
end
|
51
64
|
|
52
65
|
def workspaces_lockfile?(lockfile)
|
53
|
-
return false unless ["yarn.lock", "package-lock.json"].include?(lockfile.name)
|
54
|
-
|
66
|
+
return false unless ["yarn.lock", "package-lock.json", "pnpm-lock.yaml"].include?(lockfile.name)
|
67
|
+
|
68
|
+
return false unless parsed_root_package_json["workspaces"] || dependency_files.any? do |file|
|
69
|
+
file.name.end_with?("pnpm-workspace.yaml") && File.dirname(file.name) == File.dirname(lockfile.name)
|
70
|
+
end
|
55
71
|
|
56
72
|
updated_dependencies_in_lockfile?(lockfile)
|
57
73
|
end
|
58
74
|
|
75
|
+
def root_lockfile
|
76
|
+
@root_lockfile ||=
|
77
|
+
lockfiles.find do |file|
|
78
|
+
File.dirname(file.name) == "."
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def lockfiles
|
83
|
+
@lockfiles ||=
|
84
|
+
dependency_files.select do |file|
|
85
|
+
lockfile?(file)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
59
89
|
def parsed_root_package_json
|
60
90
|
@parsed_root_package_json ||=
|
61
91
|
begin
|
@@ -88,6 +118,7 @@ module Dependabot
|
|
88
118
|
file.name.end_with?(
|
89
119
|
"package-lock.json",
|
90
120
|
"yarn.lock",
|
121
|
+
"pnpm-lock.yaml",
|
91
122
|
"npm-shrinkwrap.json"
|
92
123
|
)
|
93
124
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
+
require "dependabot/experiments"
|
4
5
|
require "dependabot/logger"
|
5
6
|
require "dependabot/file_fetchers"
|
6
7
|
require "dependabot/file_fetchers/base"
|
7
8
|
require "dependabot/npm_and_yarn/helpers"
|
9
|
+
require "dependabot/npm_and_yarn/package_manager"
|
8
10
|
require "dependabot/npm_and_yarn/file_parser"
|
9
11
|
require "dependabot/npm_and_yarn/file_parser/lockfile_parser"
|
10
12
|
|
@@ -55,6 +57,7 @@ module Dependabot
|
|
55
57
|
|
56
58
|
package_managers["npm"] = Helpers.npm_version_numeric(package_lock.content) if package_lock
|
57
59
|
package_managers["yarn"] = yarn_version if yarn_version
|
60
|
+
package_managers["pnpm"] = pnpm_version if pnpm_version
|
58
61
|
package_managers["shrinkwrap"] = 1 if shrinkwrap
|
59
62
|
package_managers["unknown"] = 1 if package_managers.empty?
|
60
63
|
|
@@ -69,22 +72,48 @@ module Dependabot
|
|
69
72
|
def fetch_files
|
70
73
|
fetched_files = []
|
71
74
|
fetched_files << package_json
|
72
|
-
fetched_files
|
73
|
-
fetched_files
|
74
|
-
fetched_files
|
75
|
-
fetched_files
|
76
|
-
fetched_files << npmrc if npmrc
|
77
|
-
fetched_files << yarnrc if yarnrc
|
78
|
-
fetched_files << yarnrc_yml if yarnrc_yml
|
75
|
+
fetched_files += npm_files
|
76
|
+
fetched_files += yarn_files
|
77
|
+
fetched_files += pnpm_files if Experiments.enabled?(:pnpm_updates)
|
78
|
+
fetched_files += lerna_files
|
79
79
|
fetched_files += workspace_package_jsons
|
80
|
-
fetched_files += lerna_packages
|
81
80
|
fetched_files += path_dependencies(fetched_files)
|
82
81
|
|
83
|
-
fetched_files << inferred_npmrc if inferred_npmrc
|
84
|
-
|
85
82
|
fetched_files.uniq
|
86
83
|
end
|
87
84
|
|
85
|
+
def npm_files
|
86
|
+
fetched_npm_files = []
|
87
|
+
fetched_npm_files << package_lock if package_lock
|
88
|
+
fetched_npm_files << shrinkwrap if shrinkwrap
|
89
|
+
fetched_npm_files << npmrc if npmrc
|
90
|
+
fetched_npm_files << inferred_npmrc if inferred_npmrc
|
91
|
+
fetched_npm_files
|
92
|
+
end
|
93
|
+
|
94
|
+
def yarn_files
|
95
|
+
fetched_yarn_files = []
|
96
|
+
fetched_yarn_files << yarn_lock if yarn_lock
|
97
|
+
fetched_yarn_files << yarnrc if yarnrc
|
98
|
+
fetched_yarn_files << yarnrc_yml if yarnrc_yml
|
99
|
+
fetched_yarn_files
|
100
|
+
end
|
101
|
+
|
102
|
+
def pnpm_files
|
103
|
+
fetched_pnpm_files = []
|
104
|
+
fetched_pnpm_files << pnpm_lock if pnpm_lock
|
105
|
+
fetched_pnpm_files << pnpm_workspace_yaml if pnpm_workspace_yaml
|
106
|
+
fetched_pnpm_files += pnpm_workspace_package_jsons
|
107
|
+
fetched_pnpm_files
|
108
|
+
end
|
109
|
+
|
110
|
+
def lerna_files
|
111
|
+
fetched_lerna_files = []
|
112
|
+
fetched_lerna_files << lerna_json if lerna_json
|
113
|
+
fetched_lerna_files += lerna_packages
|
114
|
+
fetched_lerna_files
|
115
|
+
end
|
116
|
+
|
88
117
|
# If every entry in the lockfile uses the same registry, we can infer
|
89
118
|
# that there is a global .npmrc file, so add it here as if it were in the repo.
|
90
119
|
|
@@ -135,17 +164,29 @@ module Dependabot
|
|
135
164
|
def yarn_version
|
136
165
|
return @yarn_version if defined?(@yarn_version)
|
137
166
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
167
|
+
@yarn_version = package_manager.locked_version("yarn") || guess_yarn_version
|
168
|
+
end
|
169
|
+
|
170
|
+
def guess_yarn_version
|
171
|
+
return unless yarn_lock
|
172
|
+
|
173
|
+
Helpers.yarn_version_numeric(yarn_lock)
|
174
|
+
end
|
175
|
+
|
176
|
+
def pnpm_version
|
177
|
+
return @pnpm_version if defined?(@pnpm_version)
|
178
|
+
|
179
|
+
@pnpm_version = package_manager.locked_version("pnpm") || guess_pnpm_version
|
180
|
+
end
|
181
|
+
|
182
|
+
def guess_pnpm_version
|
183
|
+
return unless pnpm_lock
|
184
|
+
|
185
|
+
Helpers.pnpm_major_version
|
144
186
|
end
|
145
187
|
|
146
|
-
def
|
147
|
-
|
148
|
-
version_match&.named_captures&.fetch("version", nil)
|
188
|
+
def package_manager
|
189
|
+
@package_manager ||= PackageManager.new(parsed_package_json)
|
149
190
|
end
|
150
191
|
|
151
192
|
def package_json
|
@@ -153,15 +194,27 @@ module Dependabot
|
|
153
194
|
end
|
154
195
|
|
155
196
|
def package_lock
|
156
|
-
@package_lock
|
197
|
+
return @package_lock if defined?(@package_lock)
|
198
|
+
|
199
|
+
@package_lock = fetch_file_if_present("package-lock.json") unless skip_package_lock?
|
157
200
|
end
|
158
201
|
|
159
202
|
def yarn_lock
|
160
|
-
@yarn_lock
|
203
|
+
return @yarn_lock if defined?(@yarn_lock)
|
204
|
+
|
205
|
+
@yarn_lock = fetch_file_if_present("yarn.lock")
|
206
|
+
end
|
207
|
+
|
208
|
+
def pnpm_lock
|
209
|
+
return @pnpm_lock if defined?(@pnpm_lock)
|
210
|
+
|
211
|
+
@pnpm_lock = fetch_file_if_present("pnpm-lock.yaml") unless skip_pnpm_lock?
|
161
212
|
end
|
162
213
|
|
163
214
|
def shrinkwrap
|
164
|
-
@shrinkwrap
|
215
|
+
return @shrinkwrap if defined?(@shrinkwrap)
|
216
|
+
|
217
|
+
@shrinkwrap = fetch_file_if_present("npm-shrinkwrap.json")
|
165
218
|
end
|
166
219
|
|
167
220
|
def npmrc
|
@@ -207,6 +260,11 @@ module Dependabot
|
|
207
260
|
tap { |f| f.support_file = true }
|
208
261
|
end
|
209
262
|
|
263
|
+
def pnpm_workspace_yaml
|
264
|
+
@pnpm_workspace_yaml ||= fetch_file_if_present("pnpm-workspace.yaml")&.
|
265
|
+
tap { |f| f.support_file = true }
|
266
|
+
end
|
267
|
+
|
210
268
|
def lerna_json
|
211
269
|
@lerna_json ||= fetch_file_if_present("lerna.json")&.
|
212
270
|
tap { |f| f.support_file = true }
|
@@ -220,6 +278,10 @@ module Dependabot
|
|
220
278
|
@lerna_packages ||= fetch_lerna_packages
|
221
279
|
end
|
222
280
|
|
281
|
+
def pnpm_workspace_package_jsons
|
282
|
+
@pnpm_workspace_package_jsons ||= fetch_pnpm_workspace_package_jsons
|
283
|
+
end
|
284
|
+
|
223
285
|
# rubocop:disable Metrics/PerceivedComplexity
|
224
286
|
def path_dependencies(fetched_files)
|
225
287
|
package_json_files = []
|
@@ -344,50 +406,36 @@ module Dependabot
|
|
344
406
|
def fetch_workspace_package_jsons
|
345
407
|
return [] unless parsed_package_json["workspaces"]
|
346
408
|
|
347
|
-
|
348
|
-
|
349
|
-
workspace_paths(parsed_package_json["workspaces"]).each do |workspace|
|
350
|
-
file = File.join(workspace, "package.json")
|
351
|
-
|
352
|
-
begin
|
353
|
-
package_json_files << fetch_file_from_host(file)
|
354
|
-
rescue Dependabot::DependencyFileNotFound
|
355
|
-
nil
|
356
|
-
end
|
409
|
+
workspace_paths(parsed_package_json["workspaces"]).filter_map do |workspace|
|
410
|
+
fetch_package_json_if_present(workspace)
|
357
411
|
end
|
358
|
-
|
359
|
-
package_json_files
|
360
412
|
end
|
361
413
|
|
362
414
|
def fetch_lerna_packages
|
363
415
|
return [] unless parsed_lerna_json["packages"]
|
364
416
|
|
365
|
-
|
417
|
+
workspace_paths(parsed_lerna_json["packages"]).flat_map do |workspace|
|
418
|
+
fetch_lerna_packages_from_path(workspace)
|
419
|
+
end.compact
|
420
|
+
end
|
366
421
|
|
367
|
-
|
368
|
-
|
369
|
-
end
|
422
|
+
def fetch_pnpm_workspace_package_jsons
|
423
|
+
return [] unless parsed_pnpm_workspace_yaml["packages"]
|
370
424
|
|
371
|
-
|
425
|
+
workspace_paths(parsed_pnpm_workspace_yaml["packages"]).filter_map do |workspace|
|
426
|
+
fetch_package_json_if_present(workspace)
|
427
|
+
end
|
372
428
|
end
|
373
429
|
|
374
430
|
def fetch_lerna_packages_from_path(path)
|
375
|
-
|
376
|
-
|
377
|
-
package_json_path = File.join(path, "package.json")
|
378
|
-
|
379
|
-
begin
|
380
|
-
dependency_files << fetch_file_from_host(package_json_path)
|
381
|
-
dependency_files += [
|
382
|
-
fetch_file_if_present(File.join(path, "package-lock.json")),
|
383
|
-
fetch_file_if_present(File.join(path, "yarn.lock")),
|
384
|
-
fetch_file_if_present(File.join(path, "npm-shrinkwrap.json"))
|
385
|
-
].compact
|
386
|
-
rescue Dependabot::DependencyFileNotFound
|
387
|
-
nil
|
388
|
-
end
|
431
|
+
package_json = fetch_package_json_if_present(path)
|
432
|
+
return unless package_json
|
389
433
|
|
390
|
-
|
434
|
+
[package_json] + [
|
435
|
+
fetch_file_if_present(File.join(path, "package-lock.json")),
|
436
|
+
fetch_file_if_present(File.join(path, "yarn.lock")),
|
437
|
+
fetch_file_if_present(File.join(path, "npm-shrinkwrap.json"))
|
438
|
+
]
|
391
439
|
end
|
392
440
|
|
393
441
|
def workspace_paths(workspace_object)
|
@@ -449,6 +497,18 @@ module Dependabot
|
|
449
497
|
matching_paths(prefix + glob, paths)
|
450
498
|
end
|
451
499
|
|
500
|
+
def fetch_package_json_if_present(workspace)
|
501
|
+
file = File.join(workspace, "package.json")
|
502
|
+
|
503
|
+
begin
|
504
|
+
fetch_file_from_host(file)
|
505
|
+
rescue Dependabot::DependencyFileNotFound
|
506
|
+
# Not all paths matched by a workspace glob may contain a package.json
|
507
|
+
# file. Ignore if that's the case
|
508
|
+
nil
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
452
512
|
# The packages/!(not-this-package) syntax is unique to Yarn
|
453
513
|
def yarn_ignored_glob(glob)
|
454
514
|
glob.match?(/!\(.*?\)/) && glob.gsub(/(!\((.*?)\))/, '\2')
|
@@ -476,12 +536,26 @@ module Dependabot
|
|
476
536
|
{}
|
477
537
|
end
|
478
538
|
|
479
|
-
def
|
539
|
+
def parsed_pnpm_workspace_yaml
|
540
|
+
return {} unless pnpm_workspace_yaml
|
541
|
+
|
542
|
+
YAML.safe_load(pnpm_workspace_yaml.content)
|
543
|
+
rescue Pysch::SyntaxError
|
544
|
+
raise Dependabot::DependencyFileNotParseable, pnpm_workspace_yaml.path
|
545
|
+
end
|
546
|
+
|
547
|
+
def skip_package_lock?
|
480
548
|
return false unless npmrc
|
481
549
|
|
482
550
|
npmrc.content.match?(/^package-lock\s*=\s*false/)
|
483
551
|
end
|
484
552
|
|
553
|
+
def skip_pnpm_lock?
|
554
|
+
return false unless npmrc
|
555
|
+
|
556
|
+
npmrc.content.match?(/^lockfile\s*=\s*false/)
|
557
|
+
end
|
558
|
+
|
485
559
|
def build_unfetchable_deps(unfetchable_deps)
|
486
560
|
return [] unless package_lock || yarn_lock
|
487
561
|
|
@@ -9,6 +9,7 @@ module Dependabot
|
|
9
9
|
class FileParser
|
10
10
|
class LockfileParser
|
11
11
|
require "dependabot/npm_and_yarn/file_parser/yarn_lock"
|
12
|
+
require "dependabot/npm_and_yarn/file_parser/pnpm_lock"
|
12
13
|
require "dependabot/npm_and_yarn/file_parser/json_lock"
|
13
14
|
|
14
15
|
def initialize(dependency_files:)
|
@@ -22,7 +23,7 @@ module Dependabot
|
|
22
23
|
# end up unique by name. That's not a perfect representation of
|
23
24
|
# the nested nature of JS resolution, but it makes everything work
|
24
25
|
# comparably to other flat-resolution strategies
|
25
|
-
(yarn_locks + package_locks + shrinkwraps).each do |file|
|
26
|
+
(yarn_locks + pnpm_locks + package_locks + shrinkwraps).each do |file|
|
26
27
|
dependency_set += lockfile_for(file).dependencies
|
27
28
|
end
|
28
29
|
|
@@ -50,10 +51,10 @@ module Dependabot
|
|
50
51
|
def potential_lockfiles_for_manifest(manifest_filename)
|
51
52
|
dir_name = File.dirname(manifest_filename)
|
52
53
|
possible_lockfile_names =
|
53
|
-
%w(package-lock.json npm-shrinkwrap.json yarn.lock).map do |f|
|
54
|
+
%w(package-lock.json npm-shrinkwrap.json pnpm-lock.yaml yarn.lock).map do |f|
|
54
55
|
Pathname.new(File.join(dir_name, f)).cleanpath.to_path
|
55
56
|
end +
|
56
|
-
%w(yarn.lock package-lock.json npm-shrinkwrap.json)
|
57
|
+
%w(yarn.lock pnpm-lock.yaml package-lock.json npm-shrinkwrap.json)
|
57
58
|
|
58
59
|
possible_lockfile_names.uniq.
|
59
60
|
filter_map { |nm| dependency_files.find { |f| f.name == nm } }
|
@@ -67,8 +68,10 @@ module Dependabot
|
|
67
68
|
@lockfiles ||= {}
|
68
69
|
@lockfiles[file.name] ||= if [*package_locks, *shrinkwraps].include?(file)
|
69
70
|
JsonLock.new(file)
|
70
|
-
|
71
|
+
elsif yarn_locks.include?(file)
|
71
72
|
YarnLock.new(file)
|
73
|
+
else
|
74
|
+
PnpmLock.new(file)
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
@@ -78,6 +81,12 @@ module Dependabot
|
|
78
81
|
select { |f| f.name.end_with?("package-lock.json") }
|
79
82
|
end
|
80
83
|
|
84
|
+
def pnpm_locks
|
85
|
+
@pnpm_locks ||=
|
86
|
+
dependency_files.
|
87
|
+
select { |f| f.name.end_with?("pnpm-lock.yaml") }
|
88
|
+
end
|
89
|
+
|
81
90
|
def yarn_locks
|
82
91
|
@yarn_locks ||=
|
83
92
|
dependency_files.
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dependabot/errors"
|
4
|
+
|
5
|
+
module Dependabot
|
6
|
+
module NpmAndYarn
|
7
|
+
class FileParser
|
8
|
+
class PnpmLock
|
9
|
+
def initialize(dependency_file)
|
10
|
+
@dependency_file = dependency_file
|
11
|
+
end
|
12
|
+
|
13
|
+
def parsed
|
14
|
+
@parsed ||= SharedHelpers.in_a_temporary_directory do
|
15
|
+
File.write("pnpm-lock.yaml", @dependency_file.content)
|
16
|
+
|
17
|
+
SharedHelpers.run_helper_subprocess(
|
18
|
+
command: NativeHelpers.helper_path,
|
19
|
+
function: "pnpm:parseLockfile",
|
20
|
+
args: [Dir.pwd]
|
21
|
+
)
|
22
|
+
rescue SharedHelpers::HelperSubprocessFailed
|
23
|
+
raise Dependabot::DependencyFileNotParseable, @dependency_file.path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def dependencies
|
28
|
+
dependency_set = Dependabot::NpmAndYarn::FileParser::DependencySet.new
|
29
|
+
|
30
|
+
parsed.each do |details|
|
31
|
+
next if details["aliased"]
|
32
|
+
|
33
|
+
name = details["name"]
|
34
|
+
version = details["version"]
|
35
|
+
|
36
|
+
dependency_args = {
|
37
|
+
name: name,
|
38
|
+
version: version,
|
39
|
+
package_manager: "npm_and_yarn",
|
40
|
+
requirements: []
|
41
|
+
}
|
42
|
+
|
43
|
+
if details["dev"]
|
44
|
+
dependency_args[:subdependency_metadata] =
|
45
|
+
[{ production: !details["dev"] }]
|
46
|
+
end
|
47
|
+
|
48
|
+
dependency_set << Dependency.new(**dependency_args)
|
49
|
+
end
|
50
|
+
|
51
|
+
dependency_set
|
52
|
+
end
|
53
|
+
|
54
|
+
def details(dependency_name, requirement, _manifest_name)
|
55
|
+
details_candidates = parsed.select { |info| info["name"] == dependency_name }
|
56
|
+
|
57
|
+
# If there's only one entry for this dependency, use it, even if
|
58
|
+
# the requirement in the lockfile doesn't match
|
59
|
+
if details_candidates.one?
|
60
|
+
details_candidates.first
|
61
|
+
else
|
62
|
+
details_candidates.find { |info| info["specifiers"]&.include?(requirement) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -418,6 +418,12 @@ module Dependabot
|
|
418
418
|
raise Dependabot::DependencyFileNotParseable, msg
|
419
419
|
end
|
420
420
|
|
421
|
+
if error_message.include?("EBADENGINE")
|
422
|
+
msg = "Dependabot uses Node.js #{`node --version`} and NPM #{`npm --version`}. " \
|
423
|
+
"Due to the engine-strict setting, the update will not succeed."
|
424
|
+
raise Dependabot::DependencyFileNotResolvable, msg
|
425
|
+
end
|
426
|
+
|
421
427
|
raise error
|
422
428
|
end
|
423
429
|
# rubocop:enable Metrics/AbcSize
|
@@ -81,7 +81,9 @@ module Dependabot
|
|
81
81
|
next false if CENTRAL_REGISTRIES.include?(cred["registry"])
|
82
82
|
|
83
83
|
# If all the URLs include this registry, it's global
|
84
|
-
next true if dependency_urls.all?
|
84
|
+
next true if dependency_urls.size.positive? && dependency_urls.all? do |url|
|
85
|
+
url.include?(cred["registry"])
|
86
|
+
end
|
85
87
|
|
86
88
|
# Check if this registry has already been defined in .npmrc as a scoped registry
|
87
89
|
next false if npmrc_scoped_registries.any? { |sr| sr.include?(cred["registry"]) }
|
@@ -133,8 +135,8 @@ module Dependabot
|
|
133
135
|
@dependency_urls = []
|
134
136
|
if package_lock
|
135
137
|
@dependency_urls +=
|
136
|
-
|
137
|
-
|
138
|
+
package_lock.content.scan(/"resolved"\s*:\s*"(.*)"/).
|
139
|
+
flatten.
|
138
140
|
select { |url| url.is_a?(String) }.
|
139
141
|
reject { |url| url.start_with?("git") }
|
140
142
|
end
|
@@ -267,7 +269,7 @@ module Dependabot
|
|
267
269
|
|
268
270
|
scopes = affected_urls.map do |url|
|
269
271
|
url.split(/\%40|@/)[1]&.split(%r{\%2[fF]|/})&.first
|
270
|
-
end
|
272
|
+
end.uniq
|
271
273
|
|
272
274
|
# Registry used for unscoped packages
|
273
275
|
return if scopes.include?(nil)
|
@@ -108,8 +108,9 @@ module Dependabot
|
|
108
108
|
def update_package_json_resolutions(package_json_content:, new_req:,
|
109
109
|
dependency:, old_req:)
|
110
110
|
dep = dependency
|
111
|
+
parsed_json_content = JSON.parse(package_json_content)
|
111
112
|
resolutions =
|
112
|
-
|
113
|
+
parsed_json_content.fetch("resolutions", parsed_json_content.dig("pnpm", "overrides") || {}).
|
113
114
|
reject { |_, v| v != old_req && v != dep.previous_version }.
|
114
115
|
select { |k, _| k == dep.name || k.end_with?("/#{dep.name}") }
|
115
116
|
|
@@ -132,7 +133,7 @@ module Dependabot
|
|
132
133
|
)
|
133
134
|
|
134
135
|
content = update_package_json_sections(
|
135
|
-
|
136
|
+
%w(resolutions overrides), content, original_line, replacement_line
|
136
137
|
)
|
137
138
|
end
|
138
139
|
content
|