Skip to content

Commit

Permalink
Merge pull request #11026 from dependabot/dev/brettfo/nuget-file-fetcher
Browse files Browse the repository at this point in the history
use content of discovery JSON to report dependency files
  • Loading branch information
randhircs authored Dec 3, 2024
2 parents f4a4964 + c74664d commit 41ce1b0
Show file tree
Hide file tree
Showing 14 changed files with 554 additions and 2,062 deletions.
404 changes: 11 additions & 393 deletions nuget/lib/dependabot/nuget/file_fetcher.rb

Large diffs are not rendered by default.

73 changes: 0 additions & 73 deletions nuget/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb

This file was deleted.

This file was deleted.

77 changes: 17 additions & 60 deletions nuget/lib/dependabot/nuget/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,79 +16,36 @@ class FileParser < Dependabot::FileParsers::Base
extend T::Sig

require "dependabot/file_parsers/base/dependency_set"
require_relative "cache_manager"

sig { returns(T::Hash[String, T::Array[Dependabot::Dependency]]) }
def self.file_dependency_cache
T.let(CacheManager.cache("file_parser.parse"), T::Hash[String, T::Array[Dependabot::Dependency]])
end

sig { override.returns(T::Array[Dependabot::Dependency]) }
def parse
return [] unless repo_contents_path

key = NativeDiscoveryJsonReader.create_cache_key(dependency_files)
workspace_path = source&.directory || "/"
self.class.file_dependency_cache[key] ||= begin
# run discovery for the repo
discovery_json_path = NativeDiscoveryJsonReader.create_discovery_file_path_from_dependency_files(
dependency_files
)
NativeHelpers.run_nuget_discover_tool(job_path: job_file_path,
repo_root: T.must(repo_contents_path),
workspace_path: workspace_path,
output_path: discovery_json_path,
credentials: credentials)

discovery_json = NativeDiscoveryJsonReader.discovery_json_from_path(discovery_json_path)
return [] unless discovery_json

Dependabot.logger.info("Discovery JSON content: #{discovery_json.content}")
discovery_json_reader = NativeDiscoveryJsonReader.new(
discovery_json: discovery_json
)

# cache discovery results
NativeDiscoveryJsonReader.set_discovery_from_dependency_files(dependency_files: dependency_files,
discovery: discovery_json_reader)
discovery_json_reader.dependency_set.dependencies
end

T.must(self.class.file_dependency_cache[key])
dependencies
end

private

sig { returns(String) }
def job_file_path
ENV.fetch("DEPENDABOT_JOB_PATH")
end

sig { returns(T::Array[Dependabot::DependencyFile]) }
def proj_files
projfile = /\.proj$/

dependency_files.select do |df|
df.name.match?(projfile)
end
end

sig { returns(T::Array[Dependabot::DependencyFile]) }
def project_files
projectfile = /\.(cs|vb|fs)proj$/

dependency_files.select do |df|
df.name.match?(projectfile)
end
sig { returns(T::Array[Dependabot::Dependency]) }
def dependencies
@dependencies ||= T.let(NativeDiscoveryJsonReader.load_discovery_for_directory(
repo_contents_path: T.must(repo_contents_path),
directory: source&.directory || "/"
).dependency_set.dependencies, T.nilable(T::Array[Dependabot::Dependency]))
end

sig { override.void }
def check_required_files
return if project_files.any? || proj_files.any?
requirement_files = dependencies.flat_map do |dep|
dep.requirements.map { |r| T.let(r.fetch(:file), String) }
end.uniq

project_files = requirement_files.select { |f| File.basename(f).match?(/\.(cs|vb|fs)proj$/) }
global_json_file = requirement_files.select { |f| File.basename(f) == "global.json" }
dotnet_tools_json_file = requirement_files.select { |f| File.basename(f) == "dotnet-tools.json" }
return if project_files.any? || global_json_file.any? || dotnet_tools_json_file.any?

raise Dependabot::DependencyFileNotFound.new(
"*.(cs|vb|fs)proj, *.proj",
"No project file or *.proj!"
"*.(cs|vb|fs)proj",
"No project file."
)
end
end
Expand Down
37 changes: 21 additions & 16 deletions nuget/lib/dependabot/nuget/file_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ def updated_dependency_files
try_update_projects(dependency) || try_update_json(dependency)
end
updated_files = dependency_files.filter_map do |f|
updated_content = File.read(dependency_file_path(f))
dependency_file_path = NativeDiscoveryJsonReader.dependency_file_path(
repo_contents_path: T.must(repo_contents_path),
dependency_file: f
)
dependency_file_path = File.join(repo_contents_path, dependency_file_path)
updated_content = File.read(dependency_file_path)
next if updated_content == f.content

normalized_content = normalize_content(f, updated_content)
Expand Down Expand Up @@ -92,7 +97,11 @@ def try_update_projects(dependency)
# run update for each project file
project_files.each do |project_file|
project_dependencies = project_dependencies(project_file)
proj_path = dependency_file_path(project_file)
dependency_file_path = NativeDiscoveryJsonReader.dependency_file_path(
repo_contents_path: T.must(repo_contents_path),
dependency_file: project_file
)
proj_path = dependency_file_path

next unless project_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) }

Expand All @@ -119,7 +128,11 @@ def try_update_json(dependency)

# We just need to feed the updater a project file, grab the first
project_file = T.must(project_files.first)
proj_path = dependency_file_path(project_file)
dependency_file_path = NativeDiscoveryJsonReader.dependency_file_path(
repo_contents_path: T.must(repo_contents_path),
dependency_file: project_file
)
proj_path = dependency_file_path

return false unless repo_contents_path

Expand Down Expand Up @@ -157,8 +170,11 @@ def testonly_update_tooling_calls

sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
def workspace
discovery_json_reader = NativeDiscoveryJsonReader.get_discovery_from_dependency_files(dependency_files)
discovery_json_reader.workspace_discovery
dependency_file_paths = dependency_files.map do |f|
NativeDiscoveryJsonReader.dependency_file_path(repo_contents_path: T.must(repo_contents_path),
dependency_file: f)
end
NativeDiscoveryJsonReader.load_discovery_for_dependency_file_paths(dependency_file_paths).workspace_discovery
end

sig { params(project_file: Dependabot::DependencyFile).returns(T::Array[String]) }
Expand Down Expand Up @@ -215,17 +231,6 @@ def normalize_content(dependency_file, updated_content)
end
# rubocop:enable Metrics/PerceivedComplexity

sig { params(dependency_file: Dependabot::DependencyFile).returns(String) }
def dependency_file_path(dependency_file)
if dependency_file.directory.start_with?(T.must(repo_contents_path))
File.join(dependency_file.directory, dependency_file.name)
else
file_directory = dependency_file.directory
file_directory = file_directory[1..-1] if file_directory.start_with?("/")
File.join(repo_contents_path || "", file_directory, dependency_file.name)
end
end

sig { returns(T::Array[Dependabot::DependencyFile]) }
def project_files
dependency_files.select { |df| df.name.match?(/\.(cs|vb|fs)proj$/) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def initialize(file_path:, dependencies:)
attr_reader :dependencies

sig { overridable.returns(Dependabot::FileParsers::Base::DependencySet) }
def dependency_set # rubocop:disable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/AbcSize
def dependency_set # rubocop:disable Metrics/PerceivedComplexity
dependency_set = Dependabot::FileParsers::Base::DependencySet.new

file_name = Pathname.new(file_path).cleanpath.to_path
Expand All @@ -65,14 +65,7 @@ def dependency_set # rubocop:disable Metrics/PerceivedComplexity,Metrics/Cycloma
# Exclude any dependencies which reference an item type
next if dependency.name.include?("@(")

dependency_file_name = file_name
if dependency.type == "PackagesConfig"
dir_name = File.dirname(file_name)
dependency_file_name = "packages.config"
dependency_file_name = File.join(dir_name, "packages.config") unless dir_name == "."
end

dependency_set << build_dependency(dependency_file_name, dependency)
dependency_set << build_dependency(file_name, dependency)
end

dependency_set
Expand Down
Loading

0 comments on commit 41ce1b0

Please sign in to comment.