dependabot-npm_and_yarn 0.289.0 → 0.290.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/file_fetcher.rb +14 -1
- data/lib/dependabot/npm_and_yarn/file_parser.rb +33 -1
- data/lib/dependabot/npm_and_yarn/helpers.rb +70 -18
- data/lib/dependabot/npm_and_yarn/package_manager.rb +21 -11
- data/lib/dependabot/npm_and_yarn/registry_helper.rb +188 -0
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8a094096ac6049e60970f2435585ab4cde21182030752133351f3b211f83d2b
|
4
|
+
data.tar.gz: 78e3e5f474091fa12526c005a4309a65d71420cbfd64d6a835cae7a1d387f031
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a264a72f6140fae85f8f5d03519381060c44093838cf8828130d30b8489bfe334790106fcf874d2805d62edfe295d2cc7963118e768806da61d879df5ff9863d
|
7
|
+
data.tar.gz: 82d5056fa18f3f7592a0471e4ce29d9feebb68108f5793f7e07b7603d63f6bba1294912ad1b56ba8bbfbc3e676ad74adfbda3d5a8446533e63463f88988569d8
|
@@ -207,7 +207,9 @@ module Dependabot
|
|
207
207
|
@package_manager_helper ||= T.let(
|
208
208
|
PackageManagerHelper.new(
|
209
209
|
parsed_package_json,
|
210
|
-
lockfiles
|
210
|
+
lockfiles,
|
211
|
+
registry_config_files,
|
212
|
+
credentials
|
211
213
|
), T.nilable(PackageManagerHelper)
|
212
214
|
)
|
213
215
|
end
|
@@ -221,6 +223,17 @@ module Dependabot
|
|
221
223
|
}
|
222
224
|
end
|
223
225
|
|
226
|
+
# Returns the .npmrc, and .yarnrc files for the repository.
|
227
|
+
# @return [Hash{Symbol => Dependabot::DependencyFile}]
|
228
|
+
sig { returns(T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)]) }
|
229
|
+
def registry_config_files
|
230
|
+
{
|
231
|
+
npmrc: npmrc,
|
232
|
+
yarnrc: yarnrc,
|
233
|
+
yarnrc_yml: yarnrc_yml
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
224
237
|
sig { returns(DependencyFile) }
|
225
238
|
def package_json
|
226
239
|
@package_json ||= T.let(fetch_file_from_host(MANIFEST_FILENAME), T.nilable(DependencyFile))
|
@@ -98,7 +98,9 @@ module Dependabot
|
|
98
98
|
@package_manager_helper ||= T.let(
|
99
99
|
PackageManagerHelper.new(
|
100
100
|
parsed_package_json,
|
101
|
-
lockfiles
|
101
|
+
lockfiles,
|
102
|
+
registry_config_files,
|
103
|
+
credentials
|
102
104
|
), T.nilable(PackageManagerHelper)
|
103
105
|
)
|
104
106
|
end
|
@@ -112,6 +114,15 @@ module Dependabot
|
|
112
114
|
}
|
113
115
|
end
|
114
116
|
|
117
|
+
sig { returns(T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)]) }
|
118
|
+
def registry_config_files
|
119
|
+
{
|
120
|
+
npmrc: npmrc,
|
121
|
+
yarnrc: yarnrc,
|
122
|
+
yarnrc_yml: yarnrc_yml
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
115
126
|
sig { returns(T.untyped) }
|
116
127
|
def parsed_package_json
|
117
128
|
JSON.parse(T.must(package_json.content))
|
@@ -156,6 +167,27 @@ module Dependabot
|
|
156
167
|
end, T.nilable(Dependabot::DependencyFile))
|
157
168
|
end
|
158
169
|
|
170
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
171
|
+
def npmrc
|
172
|
+
@npmrc ||= T.let(dependency_files.find do |f|
|
173
|
+
f.name == NpmPackageManager::RC_FILENAME
|
174
|
+
end, T.nilable(Dependabot::DependencyFile))
|
175
|
+
end
|
176
|
+
|
177
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
178
|
+
def yarnrc
|
179
|
+
@yarnrc ||= T.let(dependency_files.find do |f|
|
180
|
+
f.name == YarnPackageManager::RC_FILENAME
|
181
|
+
end, T.nilable(Dependabot::DependencyFile))
|
182
|
+
end
|
183
|
+
|
184
|
+
sig { returns(T.nilable(DependencyFile)) }
|
185
|
+
def yarnrc_yml
|
186
|
+
@yarnrc_yml ||= T.let(dependency_files.find do |f|
|
187
|
+
f.name == YarnPackageManager::RC_YML_FILENAME
|
188
|
+
end, T.nilable(Dependabot::DependencyFile))
|
189
|
+
end
|
190
|
+
|
159
191
|
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
160
192
|
def manifest_dependencies
|
161
193
|
dependency_set = DependencySet.new
|
@@ -9,7 +9,7 @@ require "sorbet-runtime"
|
|
9
9
|
|
10
10
|
module Dependabot
|
11
11
|
module NpmAndYarn
|
12
|
-
module Helpers
|
12
|
+
module Helpers # rubocop:disable Metrics/ModuleLength
|
13
13
|
extend T::Sig
|
14
14
|
|
15
15
|
YARN_PATH_NOT_FOUND =
|
@@ -332,7 +332,7 @@ module Dependabot
|
|
332
332
|
version.strip.delete_prefix("v") # Remove the "v" prefix if present
|
333
333
|
end
|
334
334
|
rescue StandardError => e
|
335
|
-
|
335
|
+
Dependabot.logger.error("Error retrieving Node.js version: #{e.message}")
|
336
336
|
nil
|
337
337
|
end
|
338
338
|
|
@@ -388,35 +388,89 @@ module Dependabot
|
|
388
388
|
end
|
389
389
|
|
390
390
|
# Install the package manager for specified version by using corepack
|
391
|
-
|
392
|
-
|
393
|
-
|
391
|
+
sig do
|
392
|
+
params(
|
393
|
+
name: String,
|
394
|
+
version: String,
|
395
|
+
env: T.nilable(T::Hash[String, String])
|
396
|
+
)
|
397
|
+
.returns(String)
|
398
|
+
end
|
399
|
+
def self.install(name, version, env: {})
|
394
400
|
Dependabot.logger.info("Installing \"#{name}@#{version}\"")
|
395
401
|
|
396
|
-
|
397
|
-
|
398
|
-
|
402
|
+
begin
|
403
|
+
# Try to install the specified version
|
404
|
+
output = package_manager_install(name, version, env: env)
|
405
|
+
|
406
|
+
# Confirm success based on the output
|
407
|
+
if output.match?(/Adding #{name}@.* to the cache/)
|
408
|
+
Dependabot.logger.info("#{name}@#{version} successfully installed.")
|
399
409
|
|
400
|
-
|
410
|
+
Dependabot.logger.info("Activating currently installed version of #{name}: #{version}")
|
411
|
+
package_manager_activate(name, version)
|
412
|
+
|
413
|
+
else
|
414
|
+
Dependabot.logger.error("Corepack installation output unexpected: #{output}")
|
415
|
+
fallback_to_local_version(name)
|
416
|
+
end
|
417
|
+
rescue StandardError => e
|
418
|
+
Dependabot.logger.error("Error installing #{name}@#{version}: #{e.message}")
|
419
|
+
fallback_to_local_version(name)
|
420
|
+
end
|
421
|
+
|
422
|
+
# Verify the installed version
|
423
|
+
installed_version = package_manager_version(name)
|
401
424
|
|
402
425
|
installed_version
|
403
426
|
end
|
404
427
|
|
428
|
+
# Attempt to activate the local version of the package manager
|
429
|
+
sig { params(name: String).void }
|
430
|
+
def self.fallback_to_local_version(name)
|
431
|
+
Dependabot.logger.info("Falling back to activate the currently installed version of #{name}.")
|
432
|
+
|
433
|
+
# Fetch the currently installed version directly from the environment
|
434
|
+
current_version = local_package_manager_version(name)
|
435
|
+
Dependabot.logger.info("Activating currently installed version of #{name}: #{current_version}")
|
436
|
+
|
437
|
+
# Prepare the existing version
|
438
|
+
package_manager_activate(name, current_version)
|
439
|
+
end
|
440
|
+
|
405
441
|
# Install the package manager for specified version by using corepack
|
406
|
-
sig
|
407
|
-
|
442
|
+
sig do
|
443
|
+
params(
|
444
|
+
name: String,
|
445
|
+
version: String,
|
446
|
+
env: T.nilable(T::Hash[String, String])
|
447
|
+
)
|
448
|
+
.returns(String)
|
449
|
+
end
|
450
|
+
def self.package_manager_install(name, version, env: {})
|
408
451
|
Dependabot::SharedHelpers.run_shell_command(
|
409
452
|
"corepack install #{name}@#{version} --global --cache-only",
|
410
|
-
fingerprint: "corepack install <name>@<version> --global --cache-only"
|
453
|
+
fingerprint: "corepack install <name>@<version> --global --cache-only",
|
454
|
+
env: env
|
411
455
|
).strip
|
412
456
|
end
|
413
457
|
|
414
458
|
# Prepare the package manager for use by using corepack
|
415
|
-
sig { params(name: String, version: String).
|
459
|
+
sig { params(name: String, version: String).returns(String) }
|
416
460
|
def self.package_manager_activate(name, version)
|
417
461
|
Dependabot::SharedHelpers.run_shell_command(
|
418
462
|
"corepack prepare #{name}@#{version} --activate",
|
419
|
-
fingerprint: "corepack prepare --activate"
|
463
|
+
fingerprint: "corepack prepare <name>@<version> --activate"
|
464
|
+
).strip
|
465
|
+
end
|
466
|
+
|
467
|
+
# Fetch the currently installed version of the package manager directly
|
468
|
+
# from the system without involving Corepack
|
469
|
+
sig { params(name: String).returns(String) }
|
470
|
+
def self.local_package_manager_version(name)
|
471
|
+
Dependabot::SharedHelpers.run_shell_command(
|
472
|
+
"#{name} -v",
|
473
|
+
fingerprint: "#{name} -v"
|
420
474
|
).strip
|
421
475
|
end
|
422
476
|
|
@@ -427,7 +481,8 @@ module Dependabot
|
|
427
481
|
|
428
482
|
version = package_manager_run_command(name, "-v").strip
|
429
483
|
|
430
|
-
Dependabot.logger.info("
|
484
|
+
Dependabot.logger.info("Installed version of #{name}: #{version}")
|
485
|
+
|
431
486
|
version
|
432
487
|
rescue StandardError => e
|
433
488
|
Dependabot.logger.error("Error fetching version for package manager #{name}: #{e.message}")
|
@@ -445,14 +500,11 @@ module Dependabot
|
|
445
500
|
def self.package_manager_run_command(name, command, fingerprint: nil)
|
446
501
|
full_command = "corepack #{name} #{command}"
|
447
502
|
|
448
|
-
Dependabot.logger.info("Running package manager command: #{full_command}")
|
449
|
-
|
450
503
|
result = Dependabot::SharedHelpers.run_shell_command(
|
451
504
|
full_command,
|
452
505
|
fingerprint: "corepack #{name} #{fingerprint || command}"
|
453
506
|
).strip
|
454
507
|
|
455
|
-
Dependabot.logger.info("Command executed successfully: #{full_command}")
|
456
508
|
result
|
457
509
|
rescue StandardError => e
|
458
510
|
Dependabot.logger.error("Error running package manager command: #{full_command}, Error: #{e.message}")
|
@@ -5,6 +5,7 @@ require "dependabot/shared_helpers"
|
|
5
5
|
require "dependabot/ecosystem"
|
6
6
|
require "dependabot/npm_and_yarn/requirement"
|
7
7
|
require "dependabot/npm_and_yarn/version_selector"
|
8
|
+
require "dependabot/npm_and_yarn/registry_helper"
|
8
9
|
|
9
10
|
module Dependabot
|
10
11
|
module NpmAndYarn
|
@@ -311,17 +312,24 @@ module Dependabot
|
|
311
312
|
sig do
|
312
313
|
params(
|
313
314
|
package_json: T.nilable(T::Hash[String, T.untyped]),
|
314
|
-
lockfiles: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)]
|
315
|
+
lockfiles: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)],
|
316
|
+
registry_config_files: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)],
|
317
|
+
credentials: T.nilable(T::Array[Dependabot::Credential])
|
315
318
|
).void
|
316
319
|
end
|
317
|
-
def initialize(package_json, lockfiles
|
320
|
+
def initialize(package_json, lockfiles, registry_config_files, credentials)
|
318
321
|
@package_json = package_json
|
319
322
|
@lockfiles = lockfiles
|
323
|
+
@registry_helper = T.let(
|
324
|
+
RegistryHelper.new(registry_config_files, credentials),
|
325
|
+
Dependabot::NpmAndYarn::RegistryHelper
|
326
|
+
)
|
320
327
|
@package_manager_detector = T.let(PackageManagerDetector.new(lockfiles, package_json), PackageManagerDetector)
|
321
328
|
@manifest_package_manager = T.let(package_json&.fetch(MANIFEST_PACKAGE_MANAGER_KEY, nil), T.nilable(String))
|
322
329
|
@engines = T.let(package_json&.fetch(MANIFEST_ENGINES_KEY, nil), T.nilable(T::Hash[String, T.untyped]))
|
323
330
|
|
324
331
|
@installed_versions = T.let({}, T::Hash[String, String])
|
332
|
+
@registries = T.let({}, T::Hash[String, String])
|
325
333
|
|
326
334
|
@language = T.let(nil, T.nilable(Ecosystem::VersionManager))
|
327
335
|
@language_requirement = T.let(nil, T.nilable(Requirement))
|
@@ -379,8 +387,8 @@ module Dependabot
|
|
379
387
|
end
|
380
388
|
|
381
389
|
# rubocop:disable Metrics/CyclomaticComplexity
|
382
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
383
390
|
# rubocop:disable Metrics/AbcSize
|
391
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
384
392
|
sig { params(name: String).returns(T.nilable(T.any(Integer, String))) }
|
385
393
|
def setup(name)
|
386
394
|
# we prioritize version mentioned in "packageManager" instead of "engines"
|
@@ -438,6 +446,9 @@ module Dependabot
|
|
438
446
|
end
|
439
447
|
version
|
440
448
|
end
|
449
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
450
|
+
# rubocop:enable Metrics/AbcSize
|
451
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
441
452
|
|
442
453
|
sig { params(name: T.nilable(String)).returns(Ecosystem::VersionManager) }
|
443
454
|
def package_manager_by_name(name)
|
@@ -456,21 +467,15 @@ module Dependabot
|
|
456
467
|
Dependabot.logger.info("No version requirement found for #{name}")
|
457
468
|
end
|
458
469
|
|
459
|
-
|
470
|
+
package_manager_class.new(
|
460
471
|
installed_version,
|
461
472
|
requirement: package_manager_requirement
|
462
473
|
)
|
463
|
-
|
464
|
-
Dependabot.logger.info("Package manager resolved for #{name}: #{package_manager_instance}")
|
465
|
-
package_manager_instance
|
466
474
|
rescue StandardError => e
|
467
475
|
Dependabot.logger.error("Error resolving package manager for #{name || 'default'}: #{e.message}")
|
468
476
|
raise
|
469
477
|
end
|
470
478
|
|
471
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
472
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
473
|
-
# rubocop:enable Metrics/AbcSize
|
474
479
|
# Retrieve the installed version of the package manager by executing
|
475
480
|
# the "corepack <name> -v" command and using the output.
|
476
481
|
# If the output does not match the expected version format (PACKAGE_MANAGER_VERSION_REGEX),
|
@@ -510,7 +515,12 @@ module Dependabot
|
|
510
515
|
sig { params(name: String, version: T.nilable(String)).void }
|
511
516
|
def install(name, version)
|
512
517
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
513
|
-
|
518
|
+
env = {}
|
519
|
+
if Dependabot::Experiments.enabled?(:enable_private_registry_for_corepack)
|
520
|
+
env = @registry_helper.find_corepack_env_variables
|
521
|
+
end
|
522
|
+
# Use the Helpers.install method to install the package manager
|
523
|
+
return Helpers.install(name, version.to_s, env: env)
|
514
524
|
end
|
515
525
|
|
516
526
|
Dependabot.logger.info("Installing \"#{name}@#{version}\"")
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "yaml"
|
5
|
+
require "dependabot/dependency_file"
|
6
|
+
require "sorbet-runtime"
|
7
|
+
|
8
|
+
module Dependabot
|
9
|
+
module NpmAndYarn
|
10
|
+
class RegistryHelper
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
# Keys for configurations
|
14
|
+
REGISTRY_KEY = "registry"
|
15
|
+
AUTH_KEY = "authToken"
|
16
|
+
|
17
|
+
# Yarn-specific keys
|
18
|
+
NPM_AUTH_TOKEN_KEY_FOR_YARN = "npmAuthToken"
|
19
|
+
NPM_SCOPE_KEY_FOR_YARN = "npmScopes"
|
20
|
+
NPM_REGISTER_KEY_FOR_YARN = "npmRegistryServer"
|
21
|
+
|
22
|
+
# Environment variable keys
|
23
|
+
COREPACK_NPM_REGISTRY_ENV = "COREPACK_NPM_REGISTRY"
|
24
|
+
COREPACK_NPM_TOKEN_ENV = "COREPACK_NPM_TOKEN"
|
25
|
+
|
26
|
+
sig do
|
27
|
+
params(
|
28
|
+
registry_config_files: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)],
|
29
|
+
credentials: T.nilable(T::Array[Dependabot::Credential])
|
30
|
+
).void
|
31
|
+
end
|
32
|
+
def initialize(registry_config_files, credentials)
|
33
|
+
@registry_config_files = T.let(registry_config_files, T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)])
|
34
|
+
@credentials = T.let(credentials, T.nilable(T::Array[Dependabot::Credential]))
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { returns(T::Hash[String, String]) }
|
38
|
+
def find_corepack_env_variables
|
39
|
+
registry_info = find_registry_and_token
|
40
|
+
|
41
|
+
env_variables = {}
|
42
|
+
env_variables[COREPACK_NPM_REGISTRY_ENV] = registry_info[:registry] if registry_info[:registry]
|
43
|
+
env_variables[COREPACK_NPM_TOKEN_ENV] = registry_info[:auth_token] if registry_info[:auth_token]
|
44
|
+
|
45
|
+
env_variables
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
sig { returns(T::Hash[Symbol, T.nilable(String)]) }
|
51
|
+
def find_registry_and_token
|
52
|
+
# Step 1: Check dependabot.yml configuration
|
53
|
+
dependabot_config = config_npm_registry_and_token
|
54
|
+
return dependabot_config if dependabot_config[:registry]
|
55
|
+
|
56
|
+
# Step 2: Check .npmrc
|
57
|
+
npmrc_config = @registry_config_files[:npmrc]
|
58
|
+
npmrc_result = parse_registry_from_npmrc_yarnrc(npmrc_config, "=", "npm")
|
59
|
+
|
60
|
+
return npmrc_result if npmrc_result[:registry]
|
61
|
+
|
62
|
+
# Step 3: Check .yarnrc
|
63
|
+
yarnrc_config = @registry_config_files[:yarnrc]
|
64
|
+
yarnrc_result = parse_registry_from_npmrc_yarnrc(yarnrc_config, " ", "npm")
|
65
|
+
return yarnrc_result if yarnrc_result[:registry]
|
66
|
+
|
67
|
+
# Step 4: Check yarnrc.yml
|
68
|
+
yarnrc_yml_config = @registry_config_files[:yarnrc_yml]
|
69
|
+
yarnrc_yml_result = parse_npm_from_yarnrc_yml(yarnrc_yml_config)
|
70
|
+
return yarnrc_yml_result if yarnrc_yml_result[:registry]
|
71
|
+
|
72
|
+
# Default values if no registry is found
|
73
|
+
{}
|
74
|
+
end
|
75
|
+
|
76
|
+
sig { returns(T::Hash[Symbol, T.nilable(String)]) }
|
77
|
+
def config_npm_registry_and_token
|
78
|
+
registries = {}
|
79
|
+
|
80
|
+
return registries unless @credentials&.any?
|
81
|
+
|
82
|
+
@credentials.each do |cred|
|
83
|
+
next unless cred["type"] == "npm_registry" # Skip if not an npm registry
|
84
|
+
next unless cred["replaces-base"] # Skip if not a reverse-proxy registry
|
85
|
+
|
86
|
+
# Set the registry if it's not already set
|
87
|
+
registries[:registry] ||= cred["registry"]
|
88
|
+
|
89
|
+
# Set the token if it's not already set
|
90
|
+
registries[:auth_token] ||= cred["token"]
|
91
|
+
end
|
92
|
+
registries
|
93
|
+
end
|
94
|
+
|
95
|
+
# Find registry and token in .npmrc or .yarnrc file
|
96
|
+
sig do
|
97
|
+
params(
|
98
|
+
file: T.nilable(Dependabot::DependencyFile),
|
99
|
+
separator: String
|
100
|
+
).returns(T::Hash[Symbol, T.nilable(String)])
|
101
|
+
end
|
102
|
+
def parse_npm_from_npm_or_yarn_rc(file, separator = "=")
|
103
|
+
parse_registry_from_npmrc_yarnrc(file, separator, NpmPackageManager::NAME)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Find registry and token in .npmrc or .yarnrc file
|
107
|
+
sig do
|
108
|
+
params(
|
109
|
+
file: T.nilable(Dependabot::DependencyFile),
|
110
|
+
separator: String,
|
111
|
+
scope: T.nilable(String)
|
112
|
+
).returns(T::Hash[Symbol, T.nilable(String)])
|
113
|
+
end
|
114
|
+
def parse_registry_from_npmrc_yarnrc(file, separator = "=", scope = nil)
|
115
|
+
content = file&.content
|
116
|
+
return { registry: nil, auth_token: nil } unless content
|
117
|
+
|
118
|
+
global_registry = T.let(nil, T.nilable(String))
|
119
|
+
scoped_registry = T.let(nil, T.nilable(String))
|
120
|
+
auth_token = T.let(nil, T.nilable(String))
|
121
|
+
|
122
|
+
content.split("\n").each do |line|
|
123
|
+
# Split using the provided separator
|
124
|
+
key, value = line.strip.split(separator, 2)
|
125
|
+
next unless key && value
|
126
|
+
|
127
|
+
# Remove surrounding quotes from keys and values
|
128
|
+
cleaned_key = key.strip.gsub(/\A["']|["']\z/, "")
|
129
|
+
cleaned_value = value.strip.gsub(/\A["']|["']\z/, "")
|
130
|
+
|
131
|
+
case cleaned_key
|
132
|
+
when "registry"
|
133
|
+
# Case 1: Found a global registry
|
134
|
+
global_registry = cleaned_value
|
135
|
+
when "_authToken"
|
136
|
+
# Case 2: Found an auth token
|
137
|
+
auth_token = cleaned_value
|
138
|
+
else
|
139
|
+
# Handle scoped registry if a scope is provided
|
140
|
+
scoped_registry = cleaned_value if scope && cleaned_key == "@#{scope}:registry"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Determine the registry to return (global first, fallback to scoped)
|
145
|
+
registry = global_registry || scoped_registry
|
146
|
+
|
147
|
+
{ registry: registry, auth_token: auth_token }
|
148
|
+
end
|
149
|
+
|
150
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
151
|
+
sig { params(file: T.nilable(Dependabot::DependencyFile)).returns(T::Hash[Symbol, T.nilable(String)]) }
|
152
|
+
def parse_npm_from_yarnrc_yml(file)
|
153
|
+
content = file&.content
|
154
|
+
return { registry: nil, auth_token: nil } unless content
|
155
|
+
|
156
|
+
result = {}
|
157
|
+
yaml_data = safe_load_yaml(content)
|
158
|
+
|
159
|
+
# Step 1: Extract global registry and auth token
|
160
|
+
result[:registry] = yaml_data[NPM_REGISTER_KEY_FOR_YARN] if yaml_data.key?(NPM_REGISTER_KEY_FOR_YARN)
|
161
|
+
result[:auth_token] = yaml_data[NPM_AUTH_TOKEN_KEY_FOR_YARN] if yaml_data.key?(NPM_AUTH_TOKEN_KEY_FOR_YARN)
|
162
|
+
|
163
|
+
# Step 2: Fallback to any scoped registry and auth token if global is missing
|
164
|
+
if result[:registry].nil? && yaml_data.key?(NPM_SCOPE_KEY_FOR_YARN)
|
165
|
+
yaml_data[NPM_SCOPE_KEY_FOR_YARN].each do |_current_scope, config|
|
166
|
+
next unless config.is_a?(Hash)
|
167
|
+
|
168
|
+
result[:registry] ||= config[NPM_REGISTER_KEY_FOR_YARN]
|
169
|
+
result[:auth_token] ||= config[NPM_AUTH_TOKEN_KEY_FOR_YARN]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
result
|
174
|
+
end
|
175
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
176
|
+
|
177
|
+
# Safely loads the YAML content and logs any parsing errors
|
178
|
+
sig { params(content: String).returns(T::Hash[String, T.untyped]) }
|
179
|
+
def safe_load_yaml(content)
|
180
|
+
YAML.safe_load(content, permitted_classes: [Symbol, String]) || {}
|
181
|
+
rescue Psych::SyntaxError => e
|
182
|
+
# Log the error instead of raising it
|
183
|
+
Dependabot.logger.error("YAML parsing error: #{e.message}")
|
184
|
+
{}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
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.290.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-12 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.290.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.290.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: debug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -326,6 +326,7 @@ files:
|
|
326
326
|
- lib/dependabot/npm_and_yarn/native_helpers.rb
|
327
327
|
- lib/dependabot/npm_and_yarn/package_manager.rb
|
328
328
|
- lib/dependabot/npm_and_yarn/package_name.rb
|
329
|
+
- lib/dependabot/npm_and_yarn/registry_helper.rb
|
329
330
|
- lib/dependabot/npm_and_yarn/registry_parser.rb
|
330
331
|
- lib/dependabot/npm_and_yarn/requirement.rb
|
331
332
|
- lib/dependabot/npm_and_yarn/sub_dependency_files_filterer.rb
|
@@ -346,8 +347,8 @@ licenses:
|
|
346
347
|
- MIT
|
347
348
|
metadata:
|
348
349
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
349
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
350
|
-
post_install_message:
|
350
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.290.0
|
351
|
+
post_install_message:
|
351
352
|
rdoc_options: []
|
352
353
|
require_paths:
|
353
354
|
- lib
|
@@ -363,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
363
364
|
version: 3.1.0
|
364
365
|
requirements: []
|
365
366
|
rubygems_version: 3.5.9
|
366
|
-
signing_key:
|
367
|
+
signing_key:
|
367
368
|
specification_version: 4
|
368
369
|
summary: Provides Dependabot support for Javascript (npm and yarn)
|
369
370
|
test_files: []
|