Skip to content

Commit

Permalink
Merge pull request #8330 from dependabot/deivid-rodriguez/private-reg…
Browse files Browse the repository at this point in the history
…istry-issues

Fix PNPM issues with private registries
  • Loading branch information
deivid-rodriguez authored Nov 15, 2023
2 parents c7930d5 + 7c0354a commit f00f0f9
Show file tree
Hide file tree
Showing 10 changed files with 560 additions and 88 deletions.
2 changes: 1 addition & 1 deletion bin/dry-run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ def handle_dependabot_error(error:)
}
}
else
raise error
raise
end
end
# rubocop:enable Metrics/MethodLength
Expand Down
1 change: 1 addition & 0 deletions npm_and_yarn/helpers/lib/pnpm/lockfile-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function nameVerDevFromPkgSnapshot(depPath, pkgSnapshot, projectSnapshots) {
return {
name: name,
version: version,
resolved: pkgSnapshot.resolution.tarball,
dev: pkgSnapshot.dev,
specifiers: specifiers,
aliased: aliased
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ def dependency_urls
@dependency_urls = dependencies.map do |dependency|
UpdateChecker::RegistryFinder.new(
dependency: dependency,
credentials: credentials
credentials: credentials,
npmrc_file: npmrc_file,
yarnrc_file: yarnrc_file,
yarnrc_yml_file: yarnrc_yml_file
).dependency_url
end
return @dependency_urls
Expand Down Expand Up @@ -309,6 +312,11 @@ def yarnrc_file
.find { |f| f.name.end_with?(".yarnrc") }
end

def yarnrc_yml_file
@yarnrc_yml_file ||= dependency_files
.find { |f| f.name.end_with?(".yarnrc.yml") }
end

def yarn_lock
@yarn_lock ||= dependency_files.find { |f| f.name == "yarn.lock" }
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def initialize(dependency:, credentials:, npmrc_file: nil,
end

def registry
locked_registry || first_registry_with_dependency_details
@registry ||= locked_registry || configured_registry || first_registry_with_dependency_details
end

def auth_headers
Expand All @@ -49,16 +49,22 @@ def self.central_registry?(registry)
end

def registry_from_rc(dependency_name)
return global_registry unless dependency_name.start_with?("@") && dependency_name.include?("/")

scope = dependency_name.split("/").first
scoped_registry(scope)
explicit_registry_from_rc(dependency_name) || global_registry
end

private

attr_reader :dependency, :credentials, :npmrc_file, :yarnrc_file, :yarnrc_yml_file

def explicit_registry_from_rc(dependency_name)
if dependency_name.start_with?("@") && dependency_name.include?("/")
scope = dependency_name.split("/").first
scoped_registry(scope) || configured_global_registry
else
configured_global_registry
end
end

def first_registry_with_dependency_details
@first_registry_with_dependency_details ||=
known_registries.find do |details|
Expand Down Expand Up @@ -126,6 +132,13 @@ def locked_registry
detailed_registry || lockfile_registry
end

def configured_registry
configured_registry_url = explicit_registry_from_rc(dependency.name)
return unless configured_registry_url

normalize_configured_registry(configured_registry_url)
end

def known_registries
@known_registries ||=
begin
Expand Down Expand Up @@ -157,44 +170,13 @@ def npmrc_registries
}
end

npmrc_file.content.scan(NPM_GLOBAL_REGISTRY_REGEX) do
next if Regexp.last_match[:registry].include?("${")

registry = Regexp.last_match[:registry].strip
.sub(%r{/+$}, "")
.sub(%r{^.*?//}, "")
.gsub(/\s+/, "%20")
next if registries.map { |r| r["registry"] }.include?(registry)

registries << {
"type" => "npm_registry",
"registry" => registry,
"token" => nil
}
end

registries
registries += npmrc_global_registries
end

def yarnrc_registries
return [] unless yarnrc_file

registries = []
yarnrc_file.content.scan(YARN_GLOBAL_REGISTRY_REGEX) do
next if Regexp.last_match[:registry].include?("${")

registry = Regexp.last_match[:registry].strip
.sub(%r{/+$}, "")
.sub(%r{^.*?//}, "")
.gsub(/\s+/, "%20")
registries << {
"type" => "npm_registry",
"registry" => registry,
"token" => nil
}
end

registries
yarnrc_global_registries
end

def unique_registries(registries)
Expand All @@ -208,56 +190,83 @@ def unique_registries(registries)
end
end

# rubocop:disable Metrics/PerceivedComplexity
def global_registry
return @global_registry if defined? @global_registry

npmrc_file&.content.to_s.scan(NPM_GLOBAL_REGISTRY_REGEX) do
next if Regexp.last_match[:registry].include?("${")

return @global_registry = Regexp.last_match[:registry].strip
end
@global_registry ||= configured_global_registry || "https://registry.npmjs.org"
end

yarnrc_file&.content.to_s.scan(YARN_GLOBAL_REGISTRY_REGEX) do
next if Regexp.last_match[:registry].include?("${")
# rubocop:disable Metrics/PerceivedComplexity
def configured_global_registry
return @configured_global_registry if defined? @configured_global_registry

return @global_registry = Regexp.last_match[:registry].strip
end
@configured_global_registry = (npmrc_file && npmrc_global_registries.first&.fetch("url")) ||
(yarnrc_file && yarnrc_global_registries.first&.fetch("url"))
return @configured_global_registry if @configured_global_registry

if parsed_yarnrc_yml&.key?("npmRegistryServer")
return @global_registry = parsed_yarnrc_yml["npmRegistryServer"]
return @configured_global_registry = parsed_yarnrc_yml["npmRegistryServer"]
end

replaces_base = credentials.find { |cred| cred["type"] == "npm_registry" && cred["replaces-base"] == true }
if replaces_base
registry = replaces_base["registry"]
registry = "https://#{registry}" unless registry.start_with?("http")
return @global_registry = registry
return @configured_global_registry = registry
end

"https://registry.npmjs.org"
@configured_global_registry = nil
end
# rubocop:enable Metrics/PerceivedComplexity

def npmrc_global_registries
global_rc_registries(npmrc_file, syntax: NPM_GLOBAL_REGISTRY_REGEX)
end

def yarnrc_global_registries
global_rc_registries(yarnrc_file, syntax: YARN_GLOBAL_REGISTRY_REGEX)
end

def scoped_registry(scope)
npmrc_file&.content.to_s.scan(NPM_SCOPED_REGISTRY_REGEX) do
next if Regexp.last_match[:registry].include?("${") || Regexp.last_match[:scope] != scope
scoped_rc_registry = scoped_rc_registry(npmrc_file, syntax: NPM_SCOPED_REGISTRY_REGEX, scope: scope) ||
scoped_rc_registry(yarnrc_file, syntax: YARN_SCOPED_REGISTRY_REGEX, scope: scope)
return scoped_rc_registry if scoped_rc_registry

return Regexp.last_match[:registry].strip
if parsed_yarnrc_yml
yarn_berry_registry = parsed_yarnrc_yml.dig("npmScopes", scope.delete_prefix("@"), "npmRegistryServer")
return yarn_berry_registry if yarn_berry_registry
end

yarnrc_file&.content.to_s.scan(YARN_SCOPED_REGISTRY_REGEX) do
next if Regexp.last_match[:registry].include?("${") || Regexp.last_match[:scope] != scope
nil
end

return Regexp.last_match[:registry].strip
def global_rc_registries(file, syntax:)
registries = []

file.content.scan(syntax) do
next if Regexp.last_match[:registry].include?("${")

url = Regexp.last_match[:registry].strip
registry = normalize_configured_registry(url)
registries << {
"type" => "npm_registry",
"registry" => registry,
"url" => url,
"token" => nil
}
end

if parsed_yarnrc_yml
yarn_berry_registry = parsed_yarnrc_yml.dig("npmScopes", scope.delete_prefix("@"), "npmRegistryServer")
return yarn_berry_registry if yarn_berry_registry
registries
end

def scoped_rc_registry(file, syntax:, scope:)
file&.content.to_s.scan(syntax) do
next if Regexp.last_match[:registry].include?("${") || Regexp.last_match[:scope] != scope

return Regexp.last_match[:registry].strip
end

global_registry
nil
end

# npm registries expect slashes to be escaped
Expand All @@ -279,6 +288,12 @@ def parsed_yarnrc_yml

@parsed_yarnrc_yml = YAML.safe_load(yarnrc_yml_file.content)
end

def normalize_configured_registry(url)
url.sub(%r{/+$}, "")
.sub(%r{^.*?//}, "")
.gsub(/\s+/, "%20")
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,23 @@
)
end
end

context "when tarball urls included" do
let(:dependency_files) { project_dependency_files("pnpm/tarball_urls") }
let(:dependency_name) { "babel-core" }
let(:requirement) { "^6.26.0" }

it "includes the URL in the details" do
expect(lockfile_details).to eq(
"aliased" => false,
"dev" => true,
"name" => "babel-core",
"resolved" => "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
"specifiers" => ["^6.26.0"],
"version" => "6.26.3"
)
end
end
end

context "for npm lockfiles" do
Expand Down
Loading

0 comments on commit f00f0f9

Please sign in to comment.