class Licensed::Sources::NuGet::NuGetDependency

Constants

LICENSE_FILE_REGEX
LICENSE_URL_REGEX
PROJECT_DESC_REGEX
PROJECT_URL_REGEX

Public Class Methods

fetch_content(url, redirect_limit = 5) click to toggle source
# File lib/licensed/sources/nuget.rb, line 140
def fetch_content(url, redirect_limit = 5)
  url = URI.parse(url) if url.instance_of? String
  return @response_by_url[url] if (@response_by_url ||= {}).key?(url)
  return if redirect_limit == 0

  begin
    response = Net::HTTP.get_response(url)
    case response
    when Net::HTTPSuccess     then
      @response_by_url[url] = response.body
    when Net::HTTPRedirection then
      redirect_url = URI.parse(response["location"])
      if redirect_url.relative?
        redirect_url = url + redirect_url
      end
      # The redirect might be to a URL that requires transformation, i.e. a github file
      redirect_url = text_content_url(redirect_url.to_s)
      @response_by_url[url] = fetch_content(redirect_url, redirect_limit - 1)
    end
  rescue
    # Host might no longer exist or some other error, ignore
  end
end
ignored_url?(url) click to toggle source
# File lib/licensed/sources/nuget.rb, line 117
def ignored_url?(url)
  # Many Microsoft packages that now use <license> use this for <licenseUrl>
  # No need to fetch this page - it just contains NuGet documentation
  url == "https://aka.ms/deprecateLicenseUrl"
end
retrieve_license(url) click to toggle source
# File lib/licensed/sources/nuget.rb, line 129
def retrieve_license(url)
  return unless url
  return if ignored_url?(url)

  # Transform URLs that are known to return HTML but have a corresponding text-based URL
  text_url = text_content_url(url)

  raw_content = fetch_content(text_url)
  strip_html(raw_content)
end
strip_html(html) click to toggle source
# File lib/licensed/sources/nuget.rb, line 110
def strip_html(html)
  return unless html

  return html unless html.downcase.include?("<html")
  ReverseMarkdown.convert(html, unknown_tags: :bypass)
end
text_content_url(url) click to toggle source
# File lib/licensed/sources/nuget.rb, line 123
def text_content_url(url)
  # Convert github file URLs to raw URLs
  return url unless match = url.match(/https?:\/\/(?:www\.)?github.com\/([^\/]+)\/([^\/]+)\/blob\/(.*)/i)
  "https://github.com/#{match[1]}/#{match[2]}/raw/#{match[3]}"
end

Public Instance Methods

description() click to toggle source
# File lib/licensed/sources/nuget.rb, line 51
def description
  return @description if defined?(@description)
  @description = begin
    return unless nuspec_contents
    match = nuspec_contents.match PROJECT_DESC_REGEX
    match[1] if match && match[1]
  end
end
license_metadata() click to toggle source

Returns the metadata that represents this dependency. This metadata is written to YAML in the dependencys cached text file

Calls superclass method Licensed::Dependency#license_metadata
# File lib/licensed/sources/nuget.rb, line 22
def license_metadata
  super.tap do |record_metadata|
    record_metadata["homepage"] = project_url if project_url
    record_metadata["summary"] = description if description
  end
end
nuspec_contents() click to toggle source
# File lib/licensed/sources/nuget.rb, line 34
def nuspec_contents
  return @nuspec_contents if defined?(@nuspec_contents)
  @nuspec_contents = begin
    return unless nuspec_path && File.exist?(nuspec_path)
    File.read(nuspec_path)
  end
end
nuspec_local_license_file() click to toggle source

Look for a <license type=“file”> element in the nuspec that points to an on-disk license file (which licensee may not find due to a non-standard filename)

# File lib/licensed/sources/nuget.rb, line 81
def nuspec_local_license_file
  return @nuspec_local_license_file if defined?(@nuspec_local_license_file)
  return unless nuspec_contents

  match = nuspec_contents.match LICENSE_FILE_REGEX
  return unless match && match[1]

  license_path = File.join(File.dirname(nuspec_path), match[1])
  return unless File.exist?(license_path)

  license_data = File.read(license_path)
  @nuspec_local_license_file = Licensee::ProjectFiles::LicenseFile.new(license_data, license_path)
end
nuspec_path() click to toggle source
# File lib/licensed/sources/nuget.rb, line 29
def nuspec_path
  name = @metadata["name"]
  File.join(self.path, "#{name.downcase}.nuspec")
end
nuspec_remote_license_file() click to toggle source

Look for a <licenseUrl> element in the nuspec that either is known to contain a license identifier in the URL, or points to license text on the internet that can be downloaded.

# File lib/licensed/sources/nuget.rb, line 97
def nuspec_remote_license_file
  return @nuspec_remote_license_file if defined?(@nuspec_remote_license_file)
  return unless nuspec_contents

  match = nuspec_contents.match LICENSE_URL_REGEX
  return unless match && match[1]

  # Attempt to fetch the license content
  license_content = self.class.retrieve_license(match[1])
  @nuspec_remote_license_file = Licensee::ProjectFiles::LicenseFile.new(license_content, { uri: match[1] }) if license_content
end
project_files() click to toggle source
Calls superclass method Licensed::Dependency#project_files
# File lib/licensed/sources/nuget.rb, line 60
def project_files
  @nuget_project_files ||= begin
    files = super().flatten.compact

    # Only include the local file if it's a file licensee didn't already detect
    nuspec_license_filename = File.basename(nuspec_local_license_file.filename) if nuspec_local_license_file
    if nuspec_license_filename && files.none? { |file| File.basename(file.filename) == nuspec_license_filename }
      files.push(nuspec_local_license_file)
    end

    # Only download licenseUrl if no recognized license was found locally
    if files.none? { |file| file.license && file.license.key != "other" }
      files.push(nuspec_remote_license_file)
    end

    files.compact
  end
end
project_url() click to toggle source
# File lib/licensed/sources/nuget.rb, line 42
def project_url
  return @project_url if defined?(@project_url)
  @project_url = begin
    return unless nuspec_contents
    match = nuspec_contents.match PROJECT_URL_REGEX
    match[1] if match && match[1]
  end
end