Class: Dependabot::NpmAndYarn::FileParser::YarnLock

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb

Instance Method Summary collapse

Constructor Details

#initialize(dependency_file, dealias_packages: false) ⇒ YarnLock

Returns a new instance of YarnLock.



16
17
18
19
# File 'lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb', line 16

def initialize(dependency_file, dealias_packages: false)
  @dependency_file = dependency_file
  @dealias_packages = dealias_packages
end

Instance Method Details

#dependenciesObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb', line 47

def dependencies
  dependency_set = Dependabot::FileParsers::Base::DependencySet.new

  parsed.each do |reqs, details|
    reqs.split(", ").each do |req|
      version = Version.semver_for(details["version"])
      next unless version
      next if workspace_package?(req)
      next if req == "__metadata"

      if alias_package?(req)
        # Skip unless we are dealiasing packages
        next unless dealias_packages?

        real_name = extract_real_name_from_yarn_alias(req)
        next unless real_name

        alias_name = T.must(req.split(/(?<=\w)\@npm:/).first)

        dependency_set << Dependency.new(
          name: real_name,
          version: version.to_s,
          package_manager: "npm_and_yarn",
          requirements: [],
          metadata: { alias: alias_name }
        )
      else
        dependency_set << Dependency.new(
          name: T.must(req.split(/(?<=\w)\@/).first),
          version: version.to_s,
          package_manager: "npm_and_yarn",
          requirements: []
        )
      end
    end
  end

  dependency_set
end

#details(dependency_name, requirement, _manifest_name) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb', line 95

def details(dependency_name, requirement, _manifest_name)
  details_candidates =
    parsed
    .select { |k, _| k.split(/(?<=\w)\@/)[0] == dependency_name }

  # If there's only one entry for this dependency, use it, even if
  # the requirement in the lockfile doesn't match
  if details_candidates.one?
    T.must(details_candidates.first).last
  else
    details_candidates.find do |k, _|
      k.scan(/(?<=\w)\@(?:npm:)?([^\s,]+)/).flatten.include?(requirement)
    end&.last
  end
end

#parsedObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb', line 22

def parsed
  @parsed ||= T.let(
    T.cast(
      SharedHelpers.in_a_temporary_directory do
        File.write("yarn.lock", @dependency_file.content)

        SharedHelpers.run_helper_subprocess(
          command: NativeHelpers.helper_path,
          function: "yarn:parseLockfile",
          args: [Dir.pwd]
        )
      rescue SharedHelpers::HelperSubprocessFailed => e
        raise Dependabot::OutOfDisk, e.message if e.message.end_with?("No space left on device")
        raise Dependabot::OutOfDisk, e.message if e.message.end_with?("Out of diskspace")
        raise Dependabot::OutOfMemory, e.message if e.message.end_with?("MemoryError")

        raise Dependabot::DependencyFileNotParseable, @dependency_file.path
      end,
      T::Hash[String, T::Hash[String, T.untyped]]
    ),
    T.nilable(T::Hash[String, T::Hash[String, T.untyped]])
  )
end