class Licensed::Sources::Yarn::V1

Constants

YARN_NAME_HEAD

‘yarn licenses list –json` returns data in a table format with header ordering specified in the output. Look for these specific headers and use their indices to get data from the table body

YARN_URL_HEAD
YARN_VERSION_HEAD

Public Class Methods

version_requirement() click to toggle source
# File lib/licensed/sources/yarn/v1.rb, line 16
def self.version_requirement
  Gem::Requirement.new("< 2.0")
end

Public Instance Methods

dependency_urls() click to toggle source

Returns a mapping of unique dependency identifiers to urls

# File lib/licensed/sources/yarn/v1.rb, line 90
def dependency_urls
  @dependency_urls ||= begin
    table = yarn_licenses_command.lines
                                 .map(&:strip)
                                 .map(&JSON.method(:parse))
                                 .find { |json| json["type"] == "table" }
    return {} if table.nil?

    head = table.dig("data", "head")
    return {} if head.nil?

    name_index = head.index YARN_NAME_HEAD
    version_index = head.index YARN_VERSION_HEAD
    url_index = head.index YARN_URL_HEAD
    return {} if name_index.nil? || version_index.nil? || url_index.nil?

    body = table.dig("data", "body")
    return {} if body.nil?

    body.each_with_object({}) do |row, hsh|
      id = "#{row[name_index]}@#{row[version_index]}"
      hsh[id] = row[url_index]
    end
  end
end
enumerate_dependencies() click to toggle source
# File lib/licensed/sources/yarn/v1.rb, line 20
def enumerate_dependencies
  packages.map do |name, package|
    Dependency.new(
      name: name,
      version: package["version"],
      path: package["path"],
      metadata: {
        "type"     => self.class.type,
        "name"     => package["name"],
        "homepage" => dependency_urls[package["id"]]
      }
    )
  end
end
include_non_production?() click to toggle source

Returns whether to include non production dependencies based on the licensed configuration settings

# File lib/licensed/sources/yarn/v1.rb, line 131
def include_non_production?
  config.dig("yarn", "production_only") == false
end
packages() click to toggle source

Finds packages that the current project relies on

# File lib/licensed/sources/yarn/v1.rb, line 36
def packages
  return [] if yarn_package_tree.nil?
  all_dependencies = {}
  recursive_dependencies(yarn_package_tree).each do |name, results|
    results.uniq! { |package| package["version"] }
    if results.size == 1
      # if there is only one package for a name, reference it by name
      all_dependencies[name] = results[0]
    else
      # if there is more than one package for a name, reference each by
      # "<name>-<version>"
      results.each do |package|
        all_dependencies["#{name}-#{package["version"]}"] = package
      end
    end
  end

  all_dependencies
end
recursive_dependencies(dependencies, result = {}) click to toggle source

Recursively parse dependency JSON data. Returns a hash mapping the package name to it’s metadata

# File lib/licensed/sources/yarn/v1.rb, line 58
def recursive_dependencies(dependencies, result = {})
  dependencies.each do |dependency|
    # "shadow" indicate a dependency requirement only, not a
    # resolved package identifier
    next if dependency["shadow"]
    name, _, version = dependency["name"].rpartition("@")

    (result[name] ||= []) << {
      "id" => dependency["name"],
      "name" => name,
      "version" => version,
      "path" => dependency_paths[dependency["name"]]
    }
    recursive_dependencies(dependency["children"], result)
  end
  result
end
yarn_licenses_command() click to toggle source

Returns the output from running ‘yarn licenses list` to get project urls

# File lib/licensed/sources/yarn/v1.rb, line 124
def yarn_licenses_command
  args = %w(--json -s --no-progress)
  args << "--production" unless include_non_production?
  Licensed::Shell.execute("yarn", "licenses", "list", *args, allow_failure: true)
end
yarn_list_command() click to toggle source

Returns the output from running ‘yarn list` to get project dependencies

# File lib/licensed/sources/yarn/v1.rb, line 117
def yarn_list_command
  args = %w(--json -s --no-progress)
  args << "--production" unless include_non_production?
  Licensed::Shell.execute("yarn", "list", *args, allow_failure: true)
end
yarn_package_tree() click to toggle source

Finds and returns the yarn package tree listing from ‘yarn list` output

# File lib/licensed/sources/yarn/v1.rb, line 77
def yarn_package_tree
  return @yarn_package_tree if defined?(@yarn_package_tree)
  @yarn_package_tree = begin
    # parse all lines of output to json and find one that is "type": "tree"
    tree = yarn_list_command.lines
                            .map(&:strip)
                            .map(&JSON.method(:parse))
                            .find { |json| json["type"] == "tree" }
    tree&.dig("data", "trees")
  end
end