class Dependabot::NpmAndYarn::FileParser::YarnLockfileParser

Attributes

content[R]

Public Class Methods

new(lockfile:) click to toggle source
# File lib/dependabot/npm_and_yarn/file_parser/yarn_lockfile_parser.rb, line 10
def initialize(lockfile:)
  @content = lockfile.content
end

Public Instance Methods

parse() click to toggle source

This is extremely crude, but saves us from having to shell out to Yarn, which may not be safe

# File lib/dependabot/npm_and_yarn/file_parser/yarn_lockfile_parser.rb, line 16
def parse
  yaml = convert_to_yaml
  lockfile_object = parse_as_yaml(yaml)
  expand_lockfile_requirements(lockfile_object)
end

Private Instance Methods

convert_to_yaml() click to toggle source

Transform lockfile to parseable YAML by wrapping requirements in quotes, e.g. (“pkg@1.0.0”:) and adding colon to nested properties (version: “1.0.0”)

# File lib/dependabot/npm_and_yarn/file_parser/yarn_lockfile_parser.rb, line 29
def convert_to_yaml
  sanitize_requirement = lambda do |line|
    return line unless line.match?(/^[\w"]/)

    "\"#{line.gsub(/\"|:\n$/, '')}\":\n"
  end
  add_missing_colon = ->(l) { l.sub(/(?<=\w|")\s(?=\w|")/, ": ") }

  content.lines.map(&sanitize_requirement).map(&add_missing_colon).join
end
expand_lockfile_requirements(lockfile_object) click to toggle source

Split all comma separated keys and duplicate the lockfile entry so we get one entry per version requirement, this is needed when one of the requirements specifies a file: requirement, e.g. “pkga@file:./pkg, pkgb@1.0.0 and we want to check this in `details_from_yarn_lock`

# File lib/dependabot/npm_and_yarn/file_parser/yarn_lockfile_parser.rb, line 51
def expand_lockfile_requirements(lockfile_object)
  lockfile_object.to_a.each_with_object({}) do |(names, val), res|
    names.split(", ").each { |name| res[name] = val }
  end
end
parse_as_yaml(yaml) click to toggle source
# File lib/dependabot/npm_and_yarn/file_parser/yarn_lockfile_parser.rb, line 40
def parse_as_yaml(yaml)
  YAML.safe_load(yaml)
rescue Psych::SyntaxError, Psych::DisallowedClass, Psych::BadAlias
  {}
end