Skip to content

Commit

Permalink
Merge pull request dependabot#8915 from dependabot/dev/brettfo/nuspec…
Browse files Browse the repository at this point in the history
…-missing-targetFramework

Don't assume `.nuspec` dependency group has a `targetFramework` attribute.
  • Loading branch information
abdulapopoola authored Jan 26, 2024
2 parents a87eb60 + 9493bd6 commit d17f581
Show file tree
Hide file tree
Showing 12 changed files with 575 additions and 456 deletions.
6 changes: 2 additions & 4 deletions nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -279,14 +279,12 @@ def build_dependency(name, req, version, prop_name, project_file, dev: false)
end

def dependency_has_search_results?(dependency)
dependency_urls = UpdateChecker::RepositoryFinder.new(
dependency_urls = RepositoryFinder.new(
dependency: dependency,
credentials: credentials,
config_files: nuget_configs
).dependency_urls
if dependency_urls.empty?
dependency_urls = [UpdateChecker::RepositoryFinder.get_default_repository_details(dependency.name)]
end
dependency_urls = [RepositoryFinder.get_default_repository_details(dependency.name)] if dependency_urls.empty?
dependency_urls.any? do |dependency_url|
dependency_url_has_matching_result?(dependency.name, dependency_url)
end
Expand Down
2 changes: 1 addition & 1 deletion nuget/lib/dependabot/nuget/nuget_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def self.get_package_versions(dependency_name, repository_details)
response
rescue Excon::Error::Timeout, Excon::Error::Socket
repo_url = repository_url
raise if repo_url == Dependabot::Nuget::UpdateChecker::RepositoryFinder::DEFAULT_REPOSITORY_URL
raise if repo_url == Dependabot::Nuget::RepositoryFinder::DEFAULT_REPOSITORY_URL

raise PrivateSourceTimedOut, repo_url
end
Expand Down
114 changes: 55 additions & 59 deletions nuget/lib/dependabot/nuget/update_checker/compatibility_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,80 +5,76 @@

module Dependabot
module Nuget
class UpdateChecker < Dependabot::UpdateCheckers::Base
class CompatibilityChecker
require_relative "nuspec_fetcher"
require_relative "nupkg_fetcher"
require_relative "tfm_finder"
require_relative "tfm_comparer"

def initialize(dependency_urls:, dependency:, tfm_finder:)
@dependency_urls = dependency_urls
@dependency = dependency
@tfm_finder = tfm_finder
end
class CompatibilityChecker
require_relative "nuspec_fetcher"
require_relative "nupkg_fetcher"
require_relative "tfm_finder"
require_relative "tfm_comparer"

def initialize(dependency_urls:, dependency:, tfm_finder:)
@dependency_urls = dependency_urls
@dependency = dependency
@tfm_finder = tfm_finder
end

def compatible?(version)
nuspec_xml = NuspecFetcher.fetch_nuspec(dependency_urls, dependency.name, version)
return false unless nuspec_xml
def compatible?(version)
nuspec_xml = NuspecFetcher.fetch_nuspec(dependency_urls, dependency.name, version)
return false unless nuspec_xml

# development dependencies are packages such as analyzers which need to be
# compatible with the compiler not the project itself.
return true if development_dependency?(nuspec_xml)
# development dependencies are packages such as analyzers which need to be
# compatible with the compiler not the project itself.
return true if development_dependency?(nuspec_xml)

package_tfms = parse_package_tfms(nuspec_xml)
package_tfms = fetch_package_tfms(version) if package_tfms.empty?
# nil is a special return value that indicates that the package is likely a development dependency
return true if package_tfms.nil?
return false if package_tfms.empty?
package_tfms = parse_package_tfms(nuspec_xml)
package_tfms = fetch_package_tfms(version) if package_tfms.empty?
# nil is a special return value that indicates that the package is likely a development dependency
return true if package_tfms.nil?
return false if package_tfms.empty?

return false if project_tfms.nil? || project_tfms.empty?
return false if project_tfms.nil? || project_tfms.empty?

TfmComparer.are_frameworks_compatible?(project_tfms, package_tfms)
end
TfmComparer.are_frameworks_compatible?(project_tfms, package_tfms)
end

private
private

attr_reader :dependency_urls, :dependency, :tfm_finder
attr_reader :dependency_urls, :dependency, :tfm_finder

def development_dependency?(nuspec_xml)
contents = nuspec_xml.at_xpath("package/metadata/developmentDependency")&.content&.strip
return false unless contents
def development_dependency?(nuspec_xml)
contents = nuspec_xml.at_xpath("package/metadata/developmentDependency")&.content&.strip
return false unless contents

contents.casecmp("true").zero?
end
contents.casecmp("true").zero?
end

def parse_package_tfms(nuspec_xml)
nuspec_xml.xpath("//dependencies/group").map do |group|
group.attribute("targetFramework")
end
end
def parse_package_tfms(nuspec_xml)
nuspec_xml.xpath("//dependencies/group").filter_map { |group| group.attribute("targetFramework") }
end

def project_tfms
return @project_tfms if defined?(@project_tfms)
def project_tfms
return @project_tfms if defined?(@project_tfms)

@project_tfms = tfm_finder.frameworks(dependency)
end
@project_tfms = tfm_finder.frameworks(dependency)
end

def fetch_package_tfms(dependency_version)
nupkg_buffer = NupkgFetcher.fetch_nupkg_buffer(dependency_urls, dependency.name, dependency_version)
return [] unless nupkg_buffer

# Parse tfms from the folders beneath the lib folder
folder_name = "lib/"
tfms = Set.new
Zip::File.open_buffer(nupkg_buffer) do |zip|
lib_file_entries = zip.select { |entry| entry.name.start_with?(folder_name) }
# If there is no lib folder in this package, assume it is a development dependency
return nil if lib_file_entries.empty?

lib_file_entries.each do |entry|
_, tfm = entry.name.split("/").first(2)
tfms << tfm
end
def fetch_package_tfms(dependency_version)
nupkg_buffer = NupkgFetcher.fetch_nupkg_buffer(dependency_urls, dependency.name, dependency_version)
return [] unless nupkg_buffer

# Parse tfms from the folders beneath the lib folder
folder_name = "lib/"
tfms = Set.new
Zip::File.open_buffer(nupkg_buffer) do |zip|
lib_file_entries = zip.select { |entry| entry.name.start_with?(folder_name) }
# If there is no lib folder in this package, assume it is a development dependency
return nil if lib_file_entries.empty?

lib_file_entries.each do |entry|
_, tfm = entry.name.split("/").first(2)
tfms << tfm
end
tfms.to_a
end
tfms.to_a
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ def nuget_configs

def dependency_urls
@dependency_urls ||=
UpdateChecker::RepositoryFinder.new(
RepositoryFinder.new(
dependency: @dependency,
credentials: @credentials,
config_files: nuget_configs
).dependency_urls
.select { |url| url.fetch(:repository_type) == "v3" }
.select { |url| url.fetch(:repository_type) == "v3" }
end

def fetch_transitive_dependencies(package_id, package_version)
Expand Down
Loading

0 comments on commit d17f581

Please sign in to comment.