Skip to content

Commit

Permalink
fix(npm): registry inferring should include the full registry path
Browse files Browse the repository at this point in the history
Co-authored-by: David Rodríguez <deivid.rodriguez@riseup.net>
  • Loading branch information
yeikel and deivid-rodriguez committed Apr 17, 2023
1 parent aa63ce1 commit fec6461
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 9 deletions.
31 changes: 23 additions & 8 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

module Dependabot
module NpmAndYarn
class FileFetcher < Dependabot::FileFetchers::Base
class FileFetcher < Dependabot::FileFetchers::Base # rubocop:disable Metrics/ClassLength
require_relative "file_fetcher/path_dependency_builder"

# Npm always prefixes file paths in the lockfile "version" with "file:"
Expand All @@ -22,6 +22,7 @@ class FileFetcher < Dependabot::FileFetchers::Base
# "yarn link", e.g. "link:react"
PATH_DEPENDENCY_STARTS = %w(file: link:. link:/ link:~/ / ./ ../ ~/).freeze
PATH_DEPENDENCY_CLEAN_REGEX = /^file:|^link:/
DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org"

def self.required_files_in?(filenames)
filenames.include?("package.json")
Expand Down Expand Up @@ -86,25 +87,39 @@ def fetch_files

# If every entry in the lockfile uses the same registry, we can infer
# that there is a global .npmrc file, so add it here as if it were in the repo.
def inferred_npmrc

def inferred_npmrc # rubocop:disable Metrics/PerceivedComplexity
return @inferred_npmrc if defined?(@inferred_npmrc)
return @inferred_npmrc = nil unless npmrc.nil? && package_lock

known_registries = []
JSON.parse(package_lock.content).fetch("dependencies", {}).each do |_name, details|
resolved = details.fetch("resolved", "https://registry.npmjs.org")
JSON.parse(package_lock.content).fetch("dependencies", {}).each do |dependency_name, details|
resolved = details.fetch("resolved", DEFAULT_NPM_REGISTRY)

begin
uri = URI.parse(resolved)
rescue URI::InvalidURIError
# Ignoring non-URIs since they're not registries.
# This can happen if resolved is false, for instance.
next
end
# Check for scheme since path dependencies will not have one
known_registries << "#{uri.scheme}://#{uri.host}" if uri.scheme && uri.host

next unless uri.scheme && uri.host

known_registry = "#{uri.scheme}://#{uri.host}"
path = uri.path

next unless path

index = path.index(dependency_name)
if index
registry_base_path = path[0...index].delete_suffix("/")
known_registry << registry_base_path
end

known_registries << known_registry
end

if known_registries.uniq.length == 1 && known_registries.first != "https://registry.npmjs.org"
if known_registries.uniq.length == 1 && known_registries.first != DEFAULT_NPM_REGISTRY
Dependabot.logger.info("Inferred global NPM registry is: #{known_registries.first}")
return @inferred_npmrc = Dependabot::DependencyFile.new(
name: ".npmrc",
Expand Down
31 changes: 30 additions & 1 deletion npm_and_yarn/spec/dependabot/npm_and_yarn/file_fetcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1787,7 +1787,36 @@
expect(file_fetcher_instance.files.map(&:name)).
to eq(%w(package.json package-lock.json .npmrc))
expect(file_fetcher_instance.files.find { |f| f.name == ".npmrc" }.content).
to eq("registry=https://npm.fury.io")
to eq("registry=https://npm.fury.io/dependabot")
end
end

context "with no .npmrc but package-lock.json contains a artifactory repository" do
before do
allow(file_fetcher_instance).to receive(:commit).and_return("sha")

stub_request(:get, File.join(url, "package.json?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture_to_response("projects/npm6/private_artifactory_repository", "package.json"),
headers: json_header
)

stub_request(:get, File.join(url, "package-lock.json?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture_to_response("projects/npm6/private_artifactory_repository", "package-lock.json"),
headers: json_header
)
end

it "infers an npmrc file" do
expect(file_fetcher_instance.files.map(&:name)).
to eq(%w(package.json package-lock.json .npmrc))
expect(file_fetcher_instance.files.find { |f| f.name == ".npmrc" }.content).
to eq("registry=https://myRegistry/api/npm/npm")
end
end
end
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"fetch-factory": "0.0.1"
},
"devDependencies": {
"etag": "1.0.0"
}
}

0 comments on commit fec6461

Please sign in to comment.