class Dependabot::Hex::FileParser

Public Instance Methods

parse() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 17
def parse
  # TODO: git sourced dependency's mixfiles are evaluated. Provide guards before removing this.
  raise ::Dependabot::UnexpectedExternalCode if @reject_external_code

  dependency_set = DependencySet.new

  dependency_details.each do |dep|
    git_dependency = dep["source"]&.fetch("type") == "git"

    dependency_set <<
      Dependency.new(
        name: dep["name"],
        version: git_dependency ? dep["checksum"] : dep["version"],
        requirements: [{
          requirement: dep["requirement"],
          groups: dep["groups"],
          source: dep["source"] && symbolize_keys(dep["source"]),
          file: dep["from"]
        }],
        package_manager: "hex"
      )
  end

  dependency_set.dependencies.sort_by(&:name)
end

Private Instance Methods

check_required_files() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 110
def check_required_files
  raise "No mixfile!" if mixfiles.none?
end
dependency_details() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 45
def dependency_details
  SharedHelpers.in_a_temporary_directory do
    write_sanitized_mixfiles
    write_sanitized_supporting_files
    File.write("mix.lock", lockfile.content) if lockfile
    FileUtils.cp(elixir_helper_parse_deps_path, "parse_deps.exs")

    SharedHelpers.run_helper_subprocess(
      env: mix_env,
      command: "mix run #{elixir_helper_path}",
      function: "parse",
      args: [Dir.pwd],
      stderr_to_stdout: true
    )
  end
rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
  result_json =
    e.message.lines.
    drop_while { |l| !l.start_with?('{"result":') }.
    join

  raise DependencyFileNotEvaluatable, e.message if result_json.empty?

  JSON.parse(result_json).fetch("result")
end
elixir_helper_parse_deps_path() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 106
def elixir_helper_parse_deps_path
  File.join(NativeHelpers.hex_helpers_dir, "lib/parse_deps.exs")
end
elixir_helper_path() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 102
def elixir_helper_path
  File.join(NativeHelpers.hex_helpers_dir, "lib/run.exs")
end
lockfile() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 122
def lockfile
  @lockfile ||= get_original_file("mix.lock")
end
mix_env() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 93
def mix_env
  {
    "MIX_EXS" => File.join(NativeHelpers.hex_helpers_dir, "mix.exs"),
    "MIX_LOCK" => File.join(NativeHelpers.hex_helpers_dir, "mix.lock"),
    "MIX_DEPS" => File.join(NativeHelpers.hex_helpers_dir, "deps"),
    "MIX_QUIET" => "1"
  }
end
mixfiles() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 118
def mixfiles
  dependency_files.select { |f| f.name.end_with?("mix.exs") }
end
sanitize_mixfile(content) click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 87
def sanitize_mixfile(content)
  Hex::FileUpdater::MixfileSanitizer.new(
    mixfile_content: content
  ).sanitized_content
end
symbolize_keys(hash) click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 114
def symbolize_keys(hash)
  hash.keys.map { |k| [k.to_sym, hash[k]] }.to_h
end
write_sanitized_mixfiles() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 71
def write_sanitized_mixfiles
  mixfiles.each do |file|
    path = file.name
    FileUtils.mkdir_p(Pathname.new(path).dirname)
    File.write(path, sanitize_mixfile(file.content))
  end
end
write_sanitized_supporting_files() click to toggle source
# File lib/dependabot/hex/file_parser.rb, line 79
def write_sanitized_supporting_files
  dependency_files.select(&:support_file).each do |file|
    path = file.name
    FileUtils.mkdir_p(Pathname.new(path).dirname)
    File.write(path, sanitize_mixfile(file.content))
  end
end