dependabot-npm_and_yarn 0.214.0 → 0.216.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/helpers/build +1 -1
- data/helpers/lib/yarn/subdependency-updater.js +15 -44
- data/helpers/package-lock.json +2584 -1559
- data/helpers/package.json +7 -8
- data/helpers/test/npm6/conflicting-dependency-parser.test.js +1 -2
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package-lock.json +3 -3
- data/helpers/test/npm6/updater.test.js +1 -2
- data/helpers/test/yarn/conflicting-dependency-parser.test.js +1 -2
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/yarn.lock +3 -3
- data/helpers/test/yarn/updater.test.js +1 -2
- data/lib/dependabot/npm_and_yarn/file_fetcher.rb +26 -38
- data/lib/dependabot/npm_and_yarn/file_parser/json_lock.rb +86 -0
- data/lib/dependabot/npm_and_yarn/file_parser/lockfile_parser.rb +21 -183
- data/lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb +80 -0
- data/lib/dependabot/npm_and_yarn/file_parser.rb +23 -36
- data/lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb +58 -31
- data/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb +43 -16
- data/lib/dependabot/npm_and_yarn/file_updater.rb +1 -4
- data/lib/dependabot/npm_and_yarn/helpers.rb +17 -4
- data/lib/dependabot/npm_and_yarn/native_helpers.rb +15 -2
- data/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb +6 -0
- data/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb +5 -4
- data/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +20 -13
- data/lib/dependabot/npm_and_yarn/update_checker.rb +7 -24
- data/lib/dependabot/npm_and_yarn/version.rb +13 -2
- metadata +37 -32
@@ -95,7 +95,7 @@ module Dependabot
|
|
95
95
|
requirement: requirement,
|
96
96
|
manifest_name: file.name
|
97
97
|
)
|
98
|
-
version = version_for(
|
98
|
+
version = version_for(requirement, lockfile_details)
|
99
99
|
|
100
100
|
return if lockfile_details && !version
|
101
101
|
return if ignore_requirement?(requirement)
|
@@ -116,7 +116,7 @@ module Dependabot
|
|
116
116
|
requirement: requirement_for(requirement),
|
117
117
|
file: file.name,
|
118
118
|
groups: [type],
|
119
|
-
source: source_for(name, requirement,
|
119
|
+
source: source_for(name, requirement, lockfile_details)
|
120
120
|
}]
|
121
121
|
)
|
122
122
|
end
|
@@ -165,29 +165,21 @@ module Dependabot
|
|
165
165
|
package_files.filter_map { |f| JSON.parse(f.content)["name"] }
|
166
166
|
end
|
167
167
|
|
168
|
-
def version_for(
|
168
|
+
def version_for(requirement, lockfile_details)
|
169
169
|
if git_url_with_semver?(requirement)
|
170
|
-
semver_version = semver_version_for(
|
170
|
+
semver_version = semver_version_for(lockfile_details)
|
171
171
|
return semver_version if semver_version
|
172
172
|
|
173
|
-
git_revision = git_revision_for(
|
173
|
+
git_revision = git_revision_for(lockfile_details)
|
174
174
|
version_from_git_revision(requirement, git_revision) || git_revision
|
175
175
|
elsif git_url?(requirement)
|
176
|
-
git_revision_for(
|
176
|
+
git_revision_for(lockfile_details)
|
177
177
|
else
|
178
|
-
semver_version_for(
|
178
|
+
semver_version_for(lockfile_details)
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
-
def git_revision_for(
|
183
|
-
return unless git_url?(requirement)
|
184
|
-
|
185
|
-
lockfile_details = lockfile_parser.lockfile_details(
|
186
|
-
dependency_name: name,
|
187
|
-
requirement: requirement,
|
188
|
-
manifest_name: manifest_name
|
189
|
-
)
|
190
|
-
|
182
|
+
def git_revision_for(lockfile_details)
|
191
183
|
[
|
192
184
|
lockfile_details&.fetch("version", nil)&.split("#")&.last,
|
193
185
|
lockfile_details&.fetch("resolved", nil)&.split("#")&.last,
|
@@ -224,29 +216,13 @@ module Dependabot
|
|
224
216
|
nil
|
225
217
|
end
|
226
218
|
|
227
|
-
def semver_version_for(
|
228
|
-
|
229
|
-
dependency_name: name,
|
230
|
-
requirement: requirement,
|
231
|
-
manifest_name: manifest_name
|
232
|
-
)&.fetch("version", nil)
|
233
|
-
|
234
|
-
# This line is to guard against improperly formatted versions in a
|
235
|
-
# lockfile, such as additional characters. NPM/yarn fixes these when
|
236
|
-
# running an update, so we can safely ignore these versions.
|
237
|
-
return unless version_class.correct?(lock_version)
|
238
|
-
|
239
|
-
lock_version
|
219
|
+
def semver_version_for(lockfile_details)
|
220
|
+
version_class.semver_for(lockfile_details&.fetch("version", ""))
|
240
221
|
end
|
241
222
|
|
242
|
-
def source_for(name, requirement,
|
223
|
+
def source_for(name, requirement, lockfile_details)
|
243
224
|
return git_source_for(requirement) if git_url?(requirement)
|
244
225
|
|
245
|
-
lockfile_details = lockfile_parser.lockfile_details(
|
246
|
-
dependency_name: name,
|
247
|
-
requirement: requirement,
|
248
|
-
manifest_name: manifest_name
|
249
|
-
)
|
250
226
|
resolved_url = lockfile_details&.fetch("resolved", nil)
|
251
227
|
|
252
228
|
resolution = lockfile_details&.fetch("resolution", nil)
|
@@ -313,11 +289,22 @@ module Dependabot
|
|
313
289
|
end
|
314
290
|
|
315
291
|
def url_for_relevant_cred(resolved_url)
|
292
|
+
resolved_url_host = URI(resolved_url).host
|
293
|
+
|
316
294
|
credential_matching_url =
|
317
295
|
credentials.
|
318
296
|
select { |cred| cred["type"] == "npm_registry" }.
|
319
297
|
sort_by { |cred| cred["registry"].length }.
|
320
|
-
find
|
298
|
+
find do |details|
|
299
|
+
next true if resolved_url_host == details["registry"]
|
300
|
+
|
301
|
+
uri = if details["registry"]&.include?("://")
|
302
|
+
URI(details["registry"])
|
303
|
+
else
|
304
|
+
URI("https://#{details['registry']}")
|
305
|
+
end
|
306
|
+
resolved_url_host == uri.host
|
307
|
+
end
|
321
308
|
|
322
309
|
return unless credential_matching_url
|
323
310
|
|
@@ -176,36 +176,28 @@ module Dependabot
|
|
176
176
|
dependency_in_package_json?(dependency)
|
177
177
|
end
|
178
178
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
*install_args,
|
202
|
-
"--force",
|
203
|
-
"--dry-run",
|
204
|
-
"false",
|
205
|
-
"--ignore-scripts",
|
206
|
-
"--package-lock-only"
|
207
|
-
].join(" ")
|
208
|
-
SharedHelpers.run_shell_command(command)
|
179
|
+
unless dependencies_in_current_package_json
|
180
|
+
# NOTE: When updating a dependency in a nested workspace project, npm
|
181
|
+
# will add the dependency as a new top-level dependency to the root
|
182
|
+
# lockfile. To overcome this, we save the content before the update,
|
183
|
+
# and then re-run `npm install` after the update against the previous
|
184
|
+
# content to remove that
|
185
|
+
previous_package_json = File.read(package_json.name)
|
186
|
+
end
|
187
|
+
|
188
|
+
# TODO: Update the npm 6 updater to use these args as we currently
|
189
|
+
# do the same in the js updater helper, we've kept it separate for
|
190
|
+
# the npm 7 rollout
|
191
|
+
install_args = top_level_dependencies.map { |dependency| npm_install_args(dependency) }
|
192
|
+
|
193
|
+
run_npm_install_lockfile_only(*install_args)
|
194
|
+
|
195
|
+
unless dependencies_in_current_package_json
|
196
|
+
File.write(package_json.name, previous_package_json)
|
197
|
+
|
198
|
+
run_npm_install_lockfile_only
|
199
|
+
end
|
200
|
+
|
209
201
|
{ lockfile_basename => File.read(lockfile_basename) }
|
210
202
|
end
|
211
203
|
|
@@ -223,7 +215,7 @@ module Dependabot
|
|
223
215
|
|
224
216
|
def run_npm8_subdependency_updater(sub_dependencies:)
|
225
217
|
dependency_names = sub_dependencies.map(&:name)
|
226
|
-
|
218
|
+
NativeHelpers.run_npm8_subdependency_update_command(dependency_names)
|
227
219
|
{ lockfile_basename => File.read(lockfile_basename) }
|
228
220
|
end
|
229
221
|
|
@@ -244,6 +236,41 @@ module Dependabot
|
|
244
236
|
end
|
245
237
|
end
|
246
238
|
|
239
|
+
# Runs `npm install` with `--package-lock-only` flag to update the
|
240
|
+
# lockfiile.
|
241
|
+
#
|
242
|
+
# Other npm flags:
|
243
|
+
# - `--force` ignores checks for platform (os, cpu) and engines
|
244
|
+
# - `--dry-run=false` the updater sets a global .npmrc with `dry-run: true`
|
245
|
+
# to work around an issue in npm 6, we don't want that here
|
246
|
+
# - `--ignore-scripts` disables prepare and prepack scripts which are
|
247
|
+
# run when installing git dependencies
|
248
|
+
def run_npm_install_lockfile_only(*install_args)
|
249
|
+
command = [
|
250
|
+
"npm",
|
251
|
+
"install",
|
252
|
+
*install_args,
|
253
|
+
"--force",
|
254
|
+
"--dry-run",
|
255
|
+
"false",
|
256
|
+
"--ignore-scripts",
|
257
|
+
"--package-lock-only"
|
258
|
+
].join(" ")
|
259
|
+
|
260
|
+
fingerprint = [
|
261
|
+
"npm",
|
262
|
+
"install",
|
263
|
+
install_args.empty? ? "" : "<install_args>",
|
264
|
+
"--force",
|
265
|
+
"--dry-run",
|
266
|
+
"false",
|
267
|
+
"--ignore-scripts",
|
268
|
+
"--package-lock-only"
|
269
|
+
].join(" ")
|
270
|
+
|
271
|
+
SharedHelpers.run_shell_command(command, fingerprint: fingerprint)
|
272
|
+
end
|
273
|
+
|
247
274
|
def npm_install_args(dependency)
|
248
275
|
git_requirement = dependency.requirements.find { |req| req[:source] && req[:source][:type] == "git" }
|
249
276
|
|
@@ -149,16 +149,18 @@ module Dependabot
|
|
149
149
|
# lockfile in the right state. Otherwise we'll need to manually update
|
150
150
|
# the lockfile.
|
151
151
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
152
|
+
if top_level_dependency_updates.all? { |dep| requirements_changed?(dep[:name]) }
|
153
|
+
Helpers.run_yarn_command("yarn install #{yarn_berry_args}".strip)
|
154
|
+
else
|
155
|
+
updates = top_level_dependency_updates.collect do |dep|
|
156
|
+
dep[:name]
|
157
|
+
end
|
158
|
+
|
159
|
+
Helpers.run_yarn_command(
|
160
|
+
"yarn up -R #{updates.join(' ')} #{yarn_berry_args}".strip,
|
161
|
+
fingerprint: "yarn up -R <dependency_names> #{yarn_berry_args}".strip
|
162
|
+
)
|
163
|
+
end
|
162
164
|
{ yarn_lock.name => File.read(yarn_lock.name) }
|
163
165
|
end
|
164
166
|
|
@@ -171,14 +173,20 @@ module Dependabot
|
|
171
173
|
dep = sub_dependencies.first
|
172
174
|
update = "#{dep.name}@#{dep.version}"
|
173
175
|
|
174
|
-
|
175
|
-
"yarn add #{update} #{
|
176
|
-
"yarn dedupe #{dep.name} #{
|
177
|
-
"yarn remove #{dep.name} #{
|
178
|
-
|
176
|
+
commands = [
|
177
|
+
["yarn add #{update} #{yarn_berry_args}".strip, "yarn add <update> #{yarn_berry_args}".strip],
|
178
|
+
["yarn dedupe #{dep.name} #{yarn_berry_args}".strip, "yarn dedupe <dep_name> #{yarn_berry_args}".strip],
|
179
|
+
["yarn remove #{dep.name} #{yarn_berry_args}".strip, "yarn remove <dep_name> #{yarn_berry_args}".strip]
|
180
|
+
]
|
181
|
+
|
182
|
+
Helpers.run_yarn_commands(*commands)
|
179
183
|
{ yarn_lock.name => File.read(yarn_lock.name) }
|
180
184
|
end
|
181
185
|
|
186
|
+
def yarn_berry_args
|
187
|
+
Helpers.yarn_berry_args
|
188
|
+
end
|
189
|
+
|
182
190
|
def run_yarn_top_level_updater(top_level_dependency_updates:)
|
183
191
|
SharedHelpers.run_helper_subprocess(
|
184
192
|
command: NativeHelpers.helper_path,
|
@@ -195,7 +203,7 @@ module Dependabot
|
|
195
203
|
SharedHelpers.run_helper_subprocess(
|
196
204
|
command: NativeHelpers.helper_path,
|
197
205
|
function: "yarn:updateSubdependency",
|
198
|
-
args: [Dir.pwd, lockfile_name, sub_dependencies.
|
206
|
+
args: [Dir.pwd, lockfile_name, sub_dependencies.map(&:to_h)]
|
199
207
|
)
|
200
208
|
end
|
201
209
|
|
@@ -358,6 +366,25 @@ module Dependabot
|
|
358
366
|
updated_content = sanitized_package_json_content(updated_content)
|
359
367
|
File.write(file.name, updated_content)
|
360
368
|
end
|
369
|
+
|
370
|
+
clean_npmrc_in_path(yarn_lock)
|
371
|
+
end
|
372
|
+
|
373
|
+
def clean_npmrc_in_path(yarn_lock)
|
374
|
+
# Berry does not read npmrc files.
|
375
|
+
return if Helpers.yarn_berry?(yarn_lock)
|
376
|
+
|
377
|
+
# Find .npmrc files in parent directories and remove variables in them
|
378
|
+
# to avoid errors when running yarn 1.
|
379
|
+
dirs = Dir.getwd.split("/")
|
380
|
+
dirs.pop
|
381
|
+
while dirs.any?
|
382
|
+
npmrc = dirs.join("/") + "/.npmrc"
|
383
|
+
break unless File.exist?(npmrc)
|
384
|
+
|
385
|
+
File.write(npmrc, File.read(npmrc).gsub(/\$\{.*\}/, ""))
|
386
|
+
dirs.pop
|
387
|
+
end
|
361
388
|
end
|
362
389
|
|
363
390
|
def write_lockfiles
|
@@ -64,10 +64,7 @@ module Dependabot
|
|
64
64
|
pnp_updater.updated_vendor_cache_files(base_directory: base_dir).each do |file|
|
65
65
|
updated_files << file if file.name == ".pnp.cjs" || file.name == ".pnp.data.json"
|
66
66
|
end
|
67
|
-
|
68
|
-
if updated_files.find { |f| f.name == ".pnp.cjs" }
|
69
|
-
vendor_updater.updated_vendor_cache_files(base_directory: base_dir).each { |file| updated_files << file }
|
70
|
-
end
|
67
|
+
vendor_updater.updated_vendor_cache_files(base_directory: base_dir).each { |file| updated_files << file }
|
71
68
|
install_state_updater.updated_vendor_cache_files(base_directory: base_dir).each do |file|
|
72
69
|
updated_files << file
|
73
70
|
end
|
@@ -40,19 +40,32 @@ module Dependabot
|
|
40
40
|
File.exist?(".pnp.cjs")
|
41
41
|
end
|
42
42
|
|
43
|
+
def self.yarn_offline_cache?
|
44
|
+
yarn_cache_dir = fetch_yarnrc_yml_value("cacheFolder", ".yarn/cache")
|
45
|
+
File.exist?(yarn_cache_dir) && (fetch_yarnrc_yml_value("nodeLinker", "") == "node-modules")
|
46
|
+
end
|
47
|
+
|
43
48
|
def self.yarn_berry_args
|
44
49
|
if yarn_major_version == 2
|
45
50
|
""
|
46
|
-
elsif
|
51
|
+
elsif yarn_berry_skip_build?
|
47
52
|
"--mode=skip-build"
|
48
53
|
else
|
54
|
+
# We only want this mode if the cache is not being updated/managed
|
55
|
+
# as this improperly leaves old versions in the cache
|
49
56
|
"--mode=update-lockfile"
|
50
57
|
end
|
51
58
|
end
|
52
59
|
|
60
|
+
def self.yarn_berry_skip_build?
|
61
|
+
yarn_major_version >= 3 && (yarn_zero_install? || yarn_offline_cache?)
|
62
|
+
end
|
63
|
+
|
53
64
|
def self.setup_yarn_berry
|
54
65
|
# Always disable immutable installs so yarn's CI detection doesn't prevent updates.
|
55
66
|
SharedHelpers.run_shell_command("yarn config set enableImmutableInstalls false")
|
67
|
+
# Do not generate a cache if offline cache disabled. Otherwise side effects may confuse further checks
|
68
|
+
SharedHelpers.run_shell_command("yarn config set enableGlobalCache true") unless yarn_berry_skip_build?
|
56
69
|
# We never want to execute postinstall scripts, either set this config or mode=skip-build must be set
|
57
70
|
if yarn_major_version == 2 || !yarn_zero_install?
|
58
71
|
SharedHelpers.run_shell_command("yarn config set enableScripts false")
|
@@ -78,13 +91,13 @@ module Dependabot
|
|
78
91
|
# contain malicious code.
|
79
92
|
def self.run_yarn_commands(*commands)
|
80
93
|
setup_yarn_berry
|
81
|
-
commands.each { |cmd| SharedHelpers.run_shell_command(cmd) }
|
94
|
+
commands.each { |cmd, fingerprint| SharedHelpers.run_shell_command(cmd, fingerprint: fingerprint) }
|
82
95
|
end
|
83
96
|
|
84
97
|
# Run a single yarn command returning stdout/stderr
|
85
|
-
def self.run_yarn_command(command)
|
98
|
+
def self.run_yarn_command(command, fingerprint: nil)
|
86
99
|
setup_yarn_berry
|
87
|
-
SharedHelpers.run_shell_command(command)
|
100
|
+
SharedHelpers.run_shell_command(command, fingerprint: fingerprint)
|
88
101
|
end
|
89
102
|
|
90
103
|
def self.dependencies_with_all_versions_metadata(dependency_set)
|
@@ -14,14 +14,14 @@ module Dependabot
|
|
14
14
|
File.join(__dir__, "../../../helpers")
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.
|
17
|
+
def self.run_npm8_subdependency_update_command(dependency_names)
|
18
18
|
# NOTE: npm options
|
19
19
|
# - `--force` ignores checks for platform (os, cpu) and engines
|
20
20
|
# - `--dry-run=false` the updater sets a global .npmrc with dry-run: true to
|
21
21
|
# work around an issue in npm 6, we don't want that here
|
22
22
|
# - `--ignore-scripts` disables prepare and prepack scripts which are run
|
23
23
|
# when installing git dependencies
|
24
|
-
[
|
24
|
+
command = [
|
25
25
|
"npm",
|
26
26
|
"update",
|
27
27
|
*dependency_names,
|
@@ -31,6 +31,19 @@ module Dependabot
|
|
31
31
|
"--ignore-scripts",
|
32
32
|
"--package-lock-only"
|
33
33
|
].join(" ")
|
34
|
+
|
35
|
+
fingerprint = [
|
36
|
+
"npm",
|
37
|
+
"update",
|
38
|
+
"<dependency_names>",
|
39
|
+
"--force",
|
40
|
+
"--dry-run",
|
41
|
+
"false",
|
42
|
+
"--ignore-scripts",
|
43
|
+
"--package-lock-only"
|
44
|
+
].join(" ")
|
45
|
+
|
46
|
+
SharedHelpers.run_shell_command(command, fingerprint: fingerprint)
|
34
47
|
end
|
35
48
|
end
|
36
49
|
end
|
@@ -95,7 +95,7 @@ module Dependabot
|
|
95
95
|
SharedHelpers.run_helper_subprocess(
|
96
96
|
command: NativeHelpers.helper_path,
|
97
97
|
function: "yarn:updateSubdependency",
|
98
|
-
args: [Dir.pwd, lockfile_name]
|
98
|
+
args: [Dir.pwd, lockfile_name, [dependency.to_h]]
|
99
99
|
)
|
100
100
|
end
|
101
101
|
end
|
@@ -116,8 +116,9 @@ module Dependabot
|
|
116
116
|
def run_yarn_berry_updater(path, lockfile_name)
|
117
117
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
118
118
|
Dir.chdir(path) do
|
119
|
-
Helpers.
|
120
|
-
"yarn up -R #{dependency.name} #{Helpers.yarn_berry_args}".strip
|
119
|
+
Helpers.run_yarn_command(
|
120
|
+
"yarn up -R #{dependency.name} #{Helpers.yarn_berry_args}".strip,
|
121
|
+
fingerprint: "yarn up -R <dependency_name> #{Helpers.yarn_berry_args}".strip
|
121
122
|
)
|
122
123
|
{ lockfile_name => File.read(lockfile_name) }
|
123
124
|
end
|
@@ -130,7 +131,7 @@ module Dependabot
|
|
130
131
|
npm_version = Dependabot::NpmAndYarn::Helpers.npm_version(lockfile_content)
|
131
132
|
|
132
133
|
if npm_version == "npm8"
|
133
|
-
|
134
|
+
NativeHelpers.run_npm8_subdependency_update_command([dependency.name])
|
134
135
|
{ lockfile_name => File.read(lockfile_name) }
|
135
136
|
else
|
136
137
|
SharedHelpers.run_helper_subprocess(
|
@@ -27,13 +27,12 @@ module Dependabot
|
|
27
27
|
}.freeze
|
28
28
|
|
29
29
|
# Error message from yarn add:
|
30
|
-
# " > @reach/router@1.2.1" has incorrect
|
31
|
-
#
|
32
|
-
# " > react-burger-menu@1.9.9" has unmet
|
33
|
-
# peer dependency "react@>=0.14.0 <16.0.0".
|
30
|
+
# " > @reach/router@1.2.1" has incorrect peer dependency "react@15.x || 16.x || 16.4.0-alpha.0911da3"
|
31
|
+
# "workspace-aggregator-<random-string> > test > react-dom@15.6.2" has incorrect peer dependency "react@^15.6.2"
|
32
|
+
# " > react-burger-menu@1.9.9" has unmet peer dependency "react@>=0.14.0 <16.0.0"
|
34
33
|
YARN_PEER_DEP_ERROR_REGEX =
|
35
34
|
/
|
36
|
-
|
35
|
+
\s>\s(?<requiring_dep>[^>"]+)"\s
|
37
36
|
has\s(incorrect|unmet)\speer\sdependency\s
|
38
37
|
"(?<required_dep>[^"]+)"
|
39
38
|
/x
|
@@ -324,8 +323,6 @@ module Dependabot
|
|
324
323
|
filtered_package_files.flat_map do |file|
|
325
324
|
path = Pathname.new(file.name).dirname
|
326
325
|
run_checker(path: path, version: version)
|
327
|
-
rescue SharedHelpers::HelperSubprocessFailed => e
|
328
|
-
handle_peer_dependency_errors(e)
|
329
326
|
end.compact
|
330
327
|
end
|
331
328
|
rescue SharedHelpers::HelperSubprocessFailed
|
@@ -488,14 +485,24 @@ module Dependabot
|
|
488
485
|
def run_checker(path:, version:)
|
489
486
|
# If there are both yarn lockfiles and npm lockfiles only run the
|
490
487
|
# yarn updater
|
491
|
-
|
492
|
-
if
|
493
|
-
return run_yarn_berry_checker(path: path, version: version) if Helpers.yarn_berry?(lockfiles.first)
|
488
|
+
yarn_lockfiles = lockfiles_for_path(lockfiles: dependency_files_builder.yarn_locks, path: path)
|
489
|
+
return run_yarn_checker(path: path, version: version, lockfile: yarn_lockfiles.first) if yarn_lockfiles.any?
|
494
490
|
|
495
|
-
|
496
|
-
|
491
|
+
npm_lockfiles = lockfiles_for_path(lockfiles: dependency_files_builder.package_locks, path: path)
|
492
|
+
return run_npm_checker(path: path, version: version) if npm_lockfiles.any?
|
493
|
+
|
494
|
+
root_yarn_lock = dependency_files_builder.root_yarn_lock
|
495
|
+
return run_yarn_checker(path: path, version: version, lockfile: root_yarn_lock) if root_yarn_lock
|
497
496
|
|
498
497
|
run_npm_checker(path: path, version: version)
|
498
|
+
rescue SharedHelpers::HelperSubprocessFailed => e
|
499
|
+
handle_peer_dependency_errors(e)
|
500
|
+
end
|
501
|
+
|
502
|
+
def run_yarn_checker(path:, version:, lockfile:)
|
503
|
+
return run_yarn_berry_checker(path: path, version: version) if Helpers.yarn_berry?(lockfile)
|
504
|
+
|
505
|
+
run_yarn_classic_checker(path: path, version: version)
|
499
506
|
end
|
500
507
|
|
501
508
|
def run_yarn_berry_checker(path:, version:)
|
@@ -519,7 +526,7 @@ module Dependabot
|
|
519
526
|
end
|
520
527
|
end
|
521
528
|
|
522
|
-
def
|
529
|
+
def run_yarn_classic_checker(path:, version:)
|
523
530
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
524
531
|
Dir.chdir(path) do
|
525
532
|
SharedHelpers.run_helper_subprocess(
|
@@ -118,6 +118,7 @@ module Dependabot
|
|
118
118
|
dependency: dependency,
|
119
119
|
target_version: lowest_security_fix_version
|
120
120
|
)
|
121
|
+
return conflicts unless vulnerability_audit_performed?
|
121
122
|
|
122
123
|
vulnerable = [vulnerability_audit].select do |hash|
|
123
124
|
!hash["fix_available"] && hash["explanation"]
|
@@ -128,6 +129,10 @@ module Dependabot
|
|
128
129
|
|
129
130
|
private
|
130
131
|
|
132
|
+
def vulnerability_audit_performed?
|
133
|
+
defined?(@vulnerability_audit)
|
134
|
+
end
|
135
|
+
|
131
136
|
def vulnerability_audit
|
132
137
|
@vulnerability_audit ||=
|
133
138
|
VulnerabilityAuditor.new(
|
@@ -279,9 +284,7 @@ module Dependabot
|
|
279
284
|
|
280
285
|
def latest_version_for_git_dependency
|
281
286
|
@latest_version_for_git_dependency ||=
|
282
|
-
if
|
283
|
-
latest_released_version
|
284
|
-
elsif version_class.correct?(dependency.version)
|
287
|
+
if version_class.correct?(dependency.version)
|
285
288
|
latest_git_version_details[:version] &&
|
286
289
|
version_class.new(latest_git_version_details[:version])
|
287
290
|
else
|
@@ -294,26 +297,9 @@ module Dependabot
|
|
294
297
|
latest_version_finder.latest_version_from_registry
|
295
298
|
end
|
296
299
|
|
297
|
-
def should_switch_source_from_git_to_registry?
|
298
|
-
return false unless git_dependency?
|
299
|
-
return false unless git_branch_or_ref_in_latest_release?
|
300
|
-
return false if latest_version_for_git_dependency.nil?
|
301
|
-
|
302
|
-
version_class.correct?(latest_version_for_git_dependency)
|
303
|
-
end
|
304
|
-
|
305
|
-
def git_branch_or_ref_in_latest_release?
|
306
|
-
return false unless latest_released_version
|
307
|
-
|
308
|
-
return @git_branch_or_ref_in_latest_release if defined?(@git_branch_or_ref_in_latest_release)
|
309
|
-
|
310
|
-
@git_branch_or_ref_in_latest_release ||=
|
311
|
-
git_commit_checker.branch_or_ref_in_release?(latest_released_version)
|
312
|
-
end
|
313
|
-
|
314
300
|
def latest_version_details
|
315
301
|
@latest_version_details ||=
|
316
|
-
if git_dependency?
|
302
|
+
if git_dependency?
|
317
303
|
latest_git_version_details
|
318
304
|
else
|
319
305
|
{ version: latest_released_version }
|
@@ -389,9 +375,6 @@ module Dependabot
|
|
389
375
|
# Never need to update source, unless a git_dependency
|
390
376
|
return dependency_source_details unless git_dependency?
|
391
377
|
|
392
|
-
# Source becomes `nil` if switching to default rubygems
|
393
|
-
return nil if should_switch_source_from_git_to_registry?
|
394
|
-
|
395
378
|
# Update the git tag if updating a pinned version
|
396
379
|
if git_commit_checker.pinned_ref_looks_like_version? &&
|
397
380
|
!git_commit_checker.local_tag_for_latest_version.nil?
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "dependabot/version"
|
3
4
|
require "dependabot/utils"
|
4
|
-
require "rubygems_version_patch"
|
5
5
|
|
6
6
|
# JavaScript pre-release versions use 1.0.1-rc1 syntax, which Gem::Version
|
7
7
|
# converts into 1.0.1.pre.rc1. We override the `to_s` method to stop that
|
@@ -11,7 +11,7 @@ require "rubygems_version_patch"
|
|
11
11
|
|
12
12
|
module Dependabot
|
13
13
|
module NpmAndYarn
|
14
|
-
class Version <
|
14
|
+
class Version < Dependabot::Version
|
15
15
|
attr_reader :build_info
|
16
16
|
|
17
17
|
VERSION_PATTERN = Gem::Version::VERSION_PATTERN + '(\+[0-9a-zA-Z\-.]+)?'
|
@@ -25,6 +25,17 @@ module Dependabot
|
|
25
25
|
version.to_s.match?(ANCHORED_VERSION_PATTERN)
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.semver_for(version)
|
29
|
+
# The next two lines are to guard against improperly formatted
|
30
|
+
# versions in a lockfile, such as an empty string or additional
|
31
|
+
# characters. NPM/yarn fixes these when running an update, so we can
|
32
|
+
# safely ignore these versions.
|
33
|
+
return if version == ""
|
34
|
+
return unless correct?(version)
|
35
|
+
|
36
|
+
version
|
37
|
+
end
|
38
|
+
|
28
39
|
def initialize(version)
|
29
40
|
@version_string = version.to_s
|
30
41
|
version = version.gsub(/^v/, "") if version.is_a?(String)
|