lib/license_finder/package_managers/dotnet.rb
# frozen_string_literal: true
require 'pathname'
require 'json'
module LicenseFinder
class Dotnet < PackageManager
class AssetFile
def initialize(path)
@manifest = JSON.parse(File.read(path))
end
def dependencies
libs = @manifest.fetch('libraries').reject do |_, v|
v.fetch('type') == 'project'
end
libs.keys.map do |name|
parts = name.split('/')
PackageMetadata.new(parts[0], parts[1], possible_spec_paths(name))
end
end
def possible_spec_paths(package_key)
lib = @manifest.fetch('libraries').fetch(package_key)
spec_filename = lib.fetch('files').find { |f| f.end_with?('.nuspec') }
return [] if spec_filename.nil?
@manifest.fetch('packageFolders').keys.map do |root|
Pathname(root).join(lib.fetch('path'), spec_filename).to_s
end
end
end
class PackageMetadata
attr_reader :name, :version, :possible_spec_paths
def initialize(name, version, possible_spec_paths)
@name = name
@version = version
@possible_spec_paths = possible_spec_paths
end
def read_license_urls
raw_licenses = possible_spec_paths.flat_map do |path|
Nuget.nuspec_license_urls(File.read(path)) if File.exist? path
end.compact
raw_licenses&.map! do |license|
license.gsub('https://licenses.nuget.org/', '')
end
end
def ==(other)
other.name == name && other.version == version && other.possible_spec_paths == possible_spec_paths
end
end
def possible_package_paths
paths = Dir[project_path.join('*.csproj')]
paths.map { |p| Pathname(p) }
end
def current_packages
package_metadatas = asset_files
.flat_map { |path| AssetFile.new(path).dependencies }
.uniq { |d| [d.name, d.version] }
package_metadatas.map do |d|
path = Dir.glob("#{Dir.home}/.nuget/packages/#{d.name.downcase}/#{d.version}").first
NugetPackage.new(d.name, d.version, spec_licenses: d.read_license_urls, install_path: path)
end
end
def asset_files
Dir[project_path.join('**/project.assets.json')]
end
def package_management_command
'dotnet'
end
def prepare_command
"#{package_management_command} restore"
end
end
end