dependabot-npm_and_yarn 0.287.0 → 0.288.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dependabot/npm_and_yarn/helpers.rb +40 -15
- data/lib/dependabot/npm_and_yarn/package_manager.rb +73 -22
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef19e7ca0938baa0bee66d3db0500574f6d3b42b181fef8fe38d36396587a2f4
|
4
|
+
data.tar.gz: 4905508434d0e5ac9ef7cbe1b71dcc10d466c5932291b8c9abb4473d53d854b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9981d5b93d3b36479e9500d54fcfcc2d0de8aed94ac5d382a84b7189d570277348e5d421e77f0fc8fee9d20c18511352a60ce855cdc95c178e74ff94640fc175
|
7
|
+
data.tar.gz: c8015a50c6732baf3435b7be9ebef4393f312c20d154bf15c516bcad80f8dc39d1fd093c09df6aeb70a59feabe02385dcf9ae15e4b46f3eb6a61916736f04f6a
|
@@ -1,9 +1,10 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/dependency"
|
5
5
|
require "dependabot/file_parsers"
|
6
6
|
require "dependabot/file_parsers/base"
|
7
|
+
require "dependabot/shared_helpers"
|
7
8
|
require "sorbet-runtime"
|
8
9
|
|
9
10
|
module Dependabot
|
@@ -110,9 +111,14 @@ module Dependabot
|
|
110
111
|
def self.pnpm_version_numeric(pnpm_lock)
|
111
112
|
lockfile_content = pnpm_lock&.content
|
112
113
|
|
113
|
-
return PNPM_DEFAULT_VERSION if lockfile_content
|
114
|
+
return PNPM_DEFAULT_VERSION if !lockfile_content || lockfile_content.strip.empty?
|
115
|
+
|
116
|
+
pnpm_lockfile_version_str = pnpm_lockfile_version(pnpm_lock)
|
117
|
+
|
118
|
+
return PNPM_FALLBACK_VERSION unless pnpm_lockfile_version_str
|
119
|
+
|
120
|
+
pnpm_lockfile_version = pnpm_lockfile_version_str.to_f
|
114
121
|
|
115
|
-
pnpm_lockfile_version = pnpm_lockfile_version(pnpm_lock).to_f
|
116
122
|
return PNPM_V9 if pnpm_lockfile_version >= 9.0
|
117
123
|
return PNPM_V8 if pnpm_lockfile_version >= 6.0
|
118
124
|
return PNPM_V7 if pnpm_lockfile_version >= 5.4
|
@@ -120,6 +126,7 @@ module Dependabot
|
|
120
126
|
PNPM_FALLBACK_VERSION
|
121
127
|
end
|
122
128
|
|
129
|
+
sig { params(key: String, default_value: String).returns(T.untyped) }
|
123
130
|
def self.fetch_yarnrc_yml_value(key, default_value)
|
124
131
|
if File.exist?(".yarnrc.yml") && (yarnrc = YAML.load_file(".yarnrc.yml"))
|
125
132
|
yarnrc.fetch(key, default_value)
|
@@ -252,9 +259,12 @@ module Dependabot
|
|
252
259
|
# set to false. Yarn commands should _not_ be ran outside of this helper
|
253
260
|
# to ensure that postinstall scripts are never executed, as they could
|
254
261
|
# contain malicious code.
|
262
|
+
sig { params(commands: T::Array[String]).void }
|
255
263
|
def self.run_yarn_commands(*commands)
|
256
264
|
setup_yarn_berry
|
257
|
-
commands.each
|
265
|
+
commands.each do |cmd, fingerprint|
|
266
|
+
run_single_yarn_command(cmd, fingerprint: fingerprint) if cmd
|
267
|
+
end
|
258
268
|
end
|
259
269
|
|
260
270
|
# Run single npm command returning stdout/stderr.
|
@@ -267,7 +277,10 @@ module Dependabot
|
|
267
277
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
268
278
|
package_manager_run_command(NpmPackageManager::NAME, command, fingerprint: fingerprint)
|
269
279
|
else
|
270
|
-
SharedHelpers.run_shell_command(
|
280
|
+
Dependabot::SharedHelpers.run_shell_command(
|
281
|
+
"corepack npm #{command}",
|
282
|
+
fingerprint: "corepack npm #{fingerprint}"
|
283
|
+
)
|
271
284
|
end
|
272
285
|
end
|
273
286
|
|
@@ -284,7 +297,10 @@ module Dependabot
|
|
284
297
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
285
298
|
package_manager_run_command(PNPMPackageManager::NAME, command, fingerprint: fingerprint)
|
286
299
|
else
|
287
|
-
SharedHelpers.run_shell_command(
|
300
|
+
Dependabot::SharedHelpers.run_shell_command(
|
301
|
+
"pnpm #{command}",
|
302
|
+
fingerprint: "pnpm #{fingerprint || command}"
|
303
|
+
)
|
288
304
|
end
|
289
305
|
end
|
290
306
|
|
@@ -294,13 +310,16 @@ module Dependabot
|
|
294
310
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
295
311
|
package_manager_run_command(YarnPackageManager::NAME, command, fingerprint: fingerprint)
|
296
312
|
else
|
297
|
-
SharedHelpers.run_shell_command(
|
313
|
+
Dependabot::SharedHelpers.run_shell_command(
|
314
|
+
"yarn #{command}",
|
315
|
+
fingerprint: "yarn #{fingerprint || command}"
|
316
|
+
)
|
298
317
|
end
|
299
318
|
end
|
300
319
|
|
301
320
|
# Install the package manager for specified version by using corepack
|
302
321
|
# and prepare it for use by using corepack
|
303
|
-
sig { params(name: String, version: String).
|
322
|
+
sig { params(name: String, version: String).returns(String) }
|
304
323
|
def self.install(name, version)
|
305
324
|
Dependabot.logger.info("Installing \"#{name}@#{version}\"")
|
306
325
|
|
@@ -309,24 +328,26 @@ module Dependabot
|
|
309
328
|
installed_version = package_manager_version(name)
|
310
329
|
|
311
330
|
Dependabot.logger.info("Installed version of #{name}: #{installed_version}")
|
331
|
+
|
332
|
+
installed_version
|
312
333
|
end
|
313
334
|
|
314
335
|
# Install the package manager for specified version by using corepack
|
315
336
|
sig { params(name: String, version: String).void }
|
316
337
|
def self.package_manager_install(name, version)
|
317
|
-
SharedHelpers.run_shell_command(
|
338
|
+
Dependabot::SharedHelpers.run_shell_command(
|
318
339
|
"corepack install #{name}@#{version} --global --cache-only",
|
319
340
|
fingerprint: "corepack install <name>@<version> --global --cache-only"
|
320
|
-
)
|
341
|
+
).strip
|
321
342
|
end
|
322
343
|
|
323
344
|
# Prepare the package manager for use by using corepack
|
324
345
|
sig { params(name: String, version: String).void }
|
325
346
|
def self.package_manager_activate(name, version)
|
326
|
-
SharedHelpers.run_shell_command(
|
347
|
+
Dependabot::SharedHelpers.run_shell_command(
|
327
348
|
"corepack prepare #{name}@#{version} --activate",
|
328
349
|
fingerprint: "corepack prepare --activate"
|
329
|
-
)
|
350
|
+
).strip
|
330
351
|
end
|
331
352
|
|
332
353
|
# Get the version of the package manager by using corepack
|
@@ -344,15 +365,19 @@ module Dependabot
|
|
344
365
|
).returns(String)
|
345
366
|
end
|
346
367
|
def self.package_manager_run_command(name, command, fingerprint: nil)
|
347
|
-
SharedHelpers.run_shell_command(
|
368
|
+
Dependabot::SharedHelpers.run_shell_command(
|
348
369
|
"corepack #{name} #{command}",
|
349
370
|
fingerprint: "corepack #{name} #{fingerprint || command}"
|
350
|
-
)
|
371
|
+
).strip
|
351
372
|
end
|
352
373
|
private_class_method :run_single_yarn_command
|
353
374
|
|
375
|
+
sig { params(pnpm_lock: DependencyFile).returns(T.nilable(String)) }
|
354
376
|
def self.pnpm_lockfile_version(pnpm_lock)
|
355
|
-
pnpm_lock.content.match(/^lockfileVersion: ['"]?(?<version>[\d.]+)/)
|
377
|
+
match = T.must(pnpm_lock.content).match(/^lockfileVersion: ['"]?(?<version>[\d.]+)/)
|
378
|
+
return match[:version] if match
|
379
|
+
|
380
|
+
nil
|
356
381
|
end
|
357
382
|
|
358
383
|
sig { params(dependency_set: Dependabot::FileParsers::Base::DependencySet).returns(T::Array[Dependency]) }
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/shared_helpers"
|
@@ -10,6 +10,7 @@ module Dependabot
|
|
10
10
|
ECOSYSTEM = "npm_and_yarn"
|
11
11
|
MANIFEST_FILENAME = "package.json"
|
12
12
|
LERNA_JSON_FILENAME = "lerna.json"
|
13
|
+
PACKAGE_MANAGER_VERSION_REGEX = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<pre_release>[a-zA-Z0-9.]+))?(?:\+(?<build>[a-zA-Z0-9.]+))?$/ # rubocop:disable Layout/LineLength
|
13
14
|
|
14
15
|
MANIFEST_PACKAGE_MANAGER_KEY = "packageManager"
|
15
16
|
MANIFEST_ENGINES_KEY = "engines"
|
@@ -138,11 +139,20 @@ module Dependabot
|
|
138
139
|
|
139
140
|
DEFAULT_PACKAGE_MANAGER = NpmPackageManager::NAME
|
140
141
|
|
141
|
-
|
142
|
+
# Define a type alias for the expected class interface
|
143
|
+
NpmAndYarnPackageManagerClassType = T.type_alias do
|
144
|
+
T.any(
|
145
|
+
T.class_of(Dependabot::NpmAndYarn::NpmPackageManager),
|
146
|
+
T.class_of(Dependabot::NpmAndYarn::YarnPackageManager),
|
147
|
+
T.class_of(Dependabot::NpmAndYarn::PNPMPackageManager)
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
151
|
+
PACKAGE_MANAGER_CLASSES = T.let({
|
142
152
|
NpmPackageManager::NAME => NpmPackageManager,
|
143
153
|
YarnPackageManager::NAME => YarnPackageManager,
|
144
154
|
PNPMPackageManager::NAME => PNPMPackageManager
|
145
|
-
}.freeze
|
155
|
+
}.freeze, T::Hash[String, NpmAndYarnPackageManagerClassType])
|
146
156
|
|
147
157
|
class PackageManagerDetector
|
148
158
|
extend T::Sig
|
@@ -151,14 +161,14 @@ module Dependabot
|
|
151
161
|
sig do
|
152
162
|
params(
|
153
163
|
lockfiles: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)],
|
154
|
-
package_json: T::Hash[String, T.untyped]
|
164
|
+
package_json: T.nilable(T::Hash[String, T.untyped])
|
155
165
|
).void
|
156
166
|
end
|
157
167
|
def initialize(lockfiles, package_json)
|
158
168
|
@lockfiles = lockfiles
|
159
169
|
@package_json = package_json
|
160
|
-
@manifest_package_manager = package_json
|
161
|
-
@engines = package_json
|
170
|
+
@manifest_package_manager = T.let(package_json&.fetch(MANIFEST_PACKAGE_MANAGER_KEY, nil), T.nilable(String))
|
171
|
+
@engines = T.let(package_json&.fetch(MANIFEST_ENGINES_KEY, {}), T::Hash[String, T.untyped])
|
162
172
|
end
|
163
173
|
|
164
174
|
# Returns npm, yarn, or pnpm based on the lockfiles, package.json, and engines
|
@@ -201,16 +211,18 @@ module Dependabot
|
|
201
211
|
|
202
212
|
sig do
|
203
213
|
params(
|
204
|
-
package_json: T::Hash[String, T.untyped],
|
214
|
+
package_json: T.nilable(T::Hash[String, T.untyped]),
|
205
215
|
lockfiles: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)]
|
206
216
|
).void
|
207
217
|
end
|
208
218
|
def initialize(package_json, lockfiles:)
|
209
219
|
@package_json = package_json
|
210
220
|
@lockfiles = lockfiles
|
211
|
-
@
|
212
|
-
@
|
213
|
-
@
|
221
|
+
@package_manager_detector = T.let(PackageManagerDetector.new(lockfiles, package_json), PackageManagerDetector)
|
222
|
+
@manifest_package_manager = T.let(package_json&.fetch(MANIFEST_PACKAGE_MANAGER_KEY, nil), T.nilable(String))
|
223
|
+
@engines = T.let(package_json&.fetch(MANIFEST_ENGINES_KEY, nil), T.nilable(T::Hash[String, T.untyped]))
|
224
|
+
|
225
|
+
@installed_versions = T.let({}, T::Hash[String, String])
|
214
226
|
end
|
215
227
|
|
216
228
|
sig { returns(Ecosystem::VersionManager) }
|
@@ -222,6 +234,8 @@ module Dependabot
|
|
222
234
|
|
223
235
|
# rubocop:disable Metrics/CyclomaticComplexity
|
224
236
|
# rubocop:disable Metrics/PerceivedComplexity
|
237
|
+
# rubocop:disable Metrics/AbcSize
|
238
|
+
sig { params(name: String).returns(T.nilable(T.any(Integer, String))) }
|
225
239
|
def setup(name)
|
226
240
|
# we prioritize version mentioned in "packageManager" instead of "engines"
|
227
241
|
# i.e. if { engines : "pnpm" : "6" } and { packageManager: "pnpm@6.0.2" },
|
@@ -257,13 +271,13 @@ module Dependabot
|
|
257
271
|
|
258
272
|
if version
|
259
273
|
raise_if_unsupported!(name, version.to_s)
|
260
|
-
install(name, version)
|
274
|
+
install(name, version.to_s)
|
261
275
|
end
|
262
276
|
else
|
263
277
|
version ||= requested_version(name)
|
264
278
|
|
265
279
|
if version
|
266
|
-
raise_if_unsupported!(name, version)
|
280
|
+
raise_if_unsupported!(name, version.to_s)
|
267
281
|
|
268
282
|
install(name, version)
|
269
283
|
else
|
@@ -272,30 +286,56 @@ module Dependabot
|
|
272
286
|
if version
|
273
287
|
raise_if_unsupported!(name, version.to_s)
|
274
288
|
|
275
|
-
install(name, version) if name == PNPMPackageManager::NAME
|
289
|
+
install(name, version.to_s) if name == PNPMPackageManager::NAME
|
276
290
|
end
|
277
291
|
end
|
278
292
|
end
|
279
293
|
version
|
280
294
|
end
|
281
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
282
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
283
|
-
|
284
|
-
private
|
285
295
|
|
286
296
|
sig { params(name: T.nilable(String)).returns(Ecosystem::VersionManager) }
|
287
297
|
def package_manager_by_name(name)
|
288
|
-
name =
|
298
|
+
name = ensure_valid_package_manager(name)
|
289
299
|
|
290
|
-
package_manager_class = PACKAGE_MANAGER_CLASSES[name]
|
300
|
+
package_manager_class = T.must(PACKAGE_MANAGER_CLASSES[name])
|
291
301
|
|
292
|
-
|
302
|
+
installed_version = installed_version(name)
|
293
303
|
|
294
|
-
|
304
|
+
package_manager_class.new(installed_version)
|
305
|
+
end
|
295
306
|
|
296
|
-
|
307
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
308
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
309
|
+
# rubocop:enable Metrics/AbcSize
|
310
|
+
# Retrieve the installed version of the package manager by executing
|
311
|
+
# the "corepack <name> -v" command and using the output.
|
312
|
+
# If the output does not match the expected version format (PACKAGE_MANAGER_VERSION_REGEX),
|
313
|
+
# fall back to the version inferred from the dependency files.
|
314
|
+
sig { params(name: String).returns(String) }
|
315
|
+
def installed_version(name)
|
316
|
+
# Return the memoized version if it has already been computed
|
317
|
+
return T.must(@installed_versions[name]) if @installed_versions.key?(name)
|
318
|
+
|
319
|
+
# Attempt to get the installed version through the package manager version command
|
320
|
+
@installed_versions[name] = Helpers.package_manager_version(name)
|
321
|
+
|
322
|
+
# If we can't get the installed version, we need to install the package manager and get the version
|
323
|
+
unless @installed_versions[name]&.match?(PACKAGE_MANAGER_VERSION_REGEX)
|
324
|
+
setup(name)
|
325
|
+
@installed_versions[name] = Helpers.package_manager_version(name)
|
326
|
+
end
|
327
|
+
|
328
|
+
# If we can't get the installed version or the version is invalid, we need to get inferred version
|
329
|
+
unless @installed_versions[name]&.match?(PACKAGE_MANAGER_VERSION_REGEX)
|
330
|
+
@installed_versions[name] = Helpers.public_send(:"#{name}_version_numeric", @lockfiles[name.to_sym]).to_s
|
331
|
+
end
|
332
|
+
|
333
|
+
T.must(@installed_versions[name])
|
297
334
|
end
|
298
335
|
|
336
|
+
private
|
337
|
+
|
338
|
+
sig { params(name: String, version: String).void }
|
299
339
|
def raise_if_unsupported!(name, version)
|
300
340
|
return unless name == PNPMPackageManager::NAME
|
301
341
|
return unless Version.new(version) < Version.new("7")
|
@@ -303,6 +343,7 @@ module Dependabot
|
|
303
343
|
raise ToolVersionNotSupported.new(PNPMPackageManager::NAME.upcase, version, "7.*, 8.*")
|
304
344
|
end
|
305
345
|
|
346
|
+
sig { params(name: String, version: T.nilable(String)).void }
|
306
347
|
def install(name, version)
|
307
348
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
308
349
|
return Helpers.install(name, version.to_s)
|
@@ -316,6 +357,13 @@ module Dependabot
|
|
316
357
|
)
|
317
358
|
end
|
318
359
|
|
360
|
+
sig { params(name: T.nilable(String)).returns(String) }
|
361
|
+
def ensure_valid_package_manager(name)
|
362
|
+
name = DEFAULT_PACKAGE_MANAGER if name.nil? || PACKAGE_MANAGER_CLASSES[name].nil?
|
363
|
+
name
|
364
|
+
end
|
365
|
+
|
366
|
+
sig { params(name: String).returns(T.nilable(String)) }
|
319
367
|
def requested_version(name)
|
320
368
|
return unless @manifest_package_manager
|
321
369
|
|
@@ -326,6 +374,7 @@ module Dependabot
|
|
326
374
|
match["version"]
|
327
375
|
end
|
328
376
|
|
377
|
+
sig { params(name: String).returns(T.nilable(T.any(Integer, String))) }
|
329
378
|
def guessed_version(name)
|
330
379
|
lockfile = @lockfiles[name.to_sym]
|
331
380
|
return unless lockfile
|
@@ -339,6 +388,8 @@ module Dependabot
|
|
339
388
|
|
340
389
|
sig { params(name: T.untyped).returns(T.nilable(String)) }
|
341
390
|
def check_engine_version(name)
|
391
|
+
return if @package_json.nil?
|
392
|
+
|
342
393
|
version_selector = VersionSelector.new
|
343
394
|
engine_versions = version_selector.setup(@package_json, name)
|
344
395
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.288.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dependabot-common
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.288.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.288.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: debug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -346,7 +346,7 @@ licenses:
|
|
346
346
|
- MIT
|
347
347
|
metadata:
|
348
348
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
349
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
349
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.288.0
|
350
350
|
post_install_message:
|
351
351
|
rdoc_options: []
|
352
352
|
require_paths:
|