class Bibliothecary::Runner

A class that allows bibliothecary to run with multiple configurations at once, rather than with one global. A runner is created every time a file is targeted to be parsed. Don’t call parse methods directory! Use a Runner.

Public Class Methods

new(configuration) click to toggle source
# File lib/bibliothecary/runner.rb, line 6
def initialize(configuration)
  @configuration = configuration
  @options = {
    cache: {},
  }
end

Public Instance Methods

analyse(path, ignore_unparseable_files: true) click to toggle source
# File lib/bibliothecary/runner.rb, line 13
def analyse(path, ignore_unparseable_files: true)
  info_list = load_file_info_list(path)

  info_list = info_list.reject { |info| info.package_manager.nil? } if ignore_unparseable_files

  # Each package manager needs to see its entire list so it can
  # associate related manifests and lockfiles for example.
  analyses = package_managers.map do |pm|
    matching_infos = info_list.select { |info| info.package_manager == pm }
    pm.analyse_file_info(matching_infos, options: @options)
  end
  analyses = analyses.flatten.compact

  info_list.select { |info| info.package_manager.nil? }.each do |info|
    analyses.push(Bibliothecary::Analyser::create_error_analysis("unknown", info.relative_path, "unknown",
                                                                 "No parser for this file type"))
  end

  analyses
end
Also aliased as: analyze
analyse_file(file_path, contents) click to toggle source

Read a manifest file and extract the list of dependencies from that file.

# File lib/bibliothecary/runner.rb, line 118
def analyse_file(file_path, contents)
  contents = Bibliothecary.utf8_string(contents)

  package_managers.select { |pm| pm.match?(file_path, contents) }.map do |pm|
    pm.analyse_contents(file_path, contents, options: @options)
  end.flatten.uniq.compact
end
Also aliased as: analyze_file
analyze(path, ignore_unparseable_files: true)
Alias for: analyse
analyze_file(file_path, contents)
Alias for: analyse_file
applicable_package_managers(info) click to toggle source
# File lib/bibliothecary/runner.rb, line 40
def applicable_package_managers(info)
  managers = package_managers.select { |pm| pm.match_info?(info) }
  managers.length > 0 ? managers : [nil]
end
filter_multi_manifest_entries(path, related_files_info_entries) click to toggle source

We don’t know what file groups are in multi file manifests until we process them. In those cases, process those, then reject the RelatedFilesInfo objects that aren’t in the manifest.

This means we’re likely analyzing these files twice in processing, but we need that accurate package manager information.

# File lib/bibliothecary/runner.rb, line 161
def filter_multi_manifest_entries(path, related_files_info_entries)
  MultiManifestFilter.new(path: path, related_files_info_entries: related_files_info_entries , runner: self).results
end
find_manifests(path) click to toggle source

Get a list of files in this path grouped by filename and repeated by package manager.

@return [Array<Bibliothecary::RelatedFilesInfo>]

# File lib/bibliothecary/runner.rb, line 100
def find_manifests(path)
  RelatedFilesInfo.create_from_file_infos(load_file_info_list(path).reject { |info| info.package_manager.nil? })
end
find_manifests_from_contents(file_path_contents_hash) click to toggle source

file_path_contents_hash contains an Array of { file_path, contents }

# File lib/bibliothecary/runner.rb, line 109
def find_manifests_from_contents(file_path_contents_hash)
  RelatedFilesInfo.create_from_file_infos(
    load_file_info_list_from_contents(
      file_path_contents_hash
    ).reject { |info| info.package_manager.nil? }
  )
end
find_manifests_from_paths(paths) click to toggle source
# File lib/bibliothecary/runner.rb, line 104
def find_manifests_from_paths(paths)
  RelatedFilesInfo.create_from_file_infos(load_file_info_list_from_paths(paths).reject { |info| info.package_manager.nil? })
end
identify_manifests(file_list) click to toggle source

this skips manifests sometimes because it doesn’t look at file contents and can’t establish from only regexes that the thing is a manifest. We exclude rather than include ambiguous filenames because this API is used by libraries.io and we don’t want to download all .xml files from GitHub.

# File lib/bibliothecary/runner.rb, line 132
def identify_manifests(file_list)
  ignored_dirs_with_slash = ignored_dirs.map { |d| if d.end_with?("/") then d else d + "/" end }
  allowed_file_list = file_list.reject do |f|
    ignored_dirs.include?(f) || f.start_with?(*ignored_dirs_with_slash)
  end
  allowed_file_list = allowed_file_list.reject{|f| ignored_files.include?(f)}
  package_managers.map do |pm|
    allowed_file_list.select do |file_path|
      # this is a call to match? without file contents, which will skip
      # ambiguous filenames that are only possibly a manifest
      pm.match?(file_path)
    end
  end.flatten.uniq.compact
end
ignored_dirs() click to toggle source
# File lib/bibliothecary/runner.rb, line 147
def ignored_dirs
  @configuration.ignored_dirs
end
ignored_files() click to toggle source
# File lib/bibliothecary/runner.rb, line 151
def ignored_files
  @configuration.ignored_files
end
load_file_info_list(path) click to toggle source
# File lib/bibliothecary/runner.rb, line 81
def load_file_info_list(path)
  file_list = []

  Find.find(path) do |subpath|
    info = FileInfo.new(path, subpath)

    Find.prune if FileTest.directory?(subpath) && ignored_dirs.include?(info.relative_path)
    next unless FileTest.file?(subpath)
    next if ignored_files.include?(info.relative_path)

    add_matching_package_managers_for_file_to_list(file_list, info)
  end

  file_list
end
load_file_info_list_from_contents(file_path_contents_hash) click to toggle source

Parses an array of format [{file_path: “”, contents: “”},] to match on both filename matches and on content_match patterns.

@return [Array<Bibliothecary::FileInfo>] A list of FileInfo, one for each package manager match for each file

# File lib/bibliothecary/runner.rb, line 53
def load_file_info_list_from_contents(file_path_contents_hash)
  file_list = []

  file_path_contents_hash.each do |file|
    info = FileInfo.new(nil, file[:file_path], file[:contents])

    next if ignored_files.include?(info.relative_path)

    add_matching_package_managers_for_file_to_list(file_list, info)
  end

  file_list
end
load_file_info_list_from_paths(paths) click to toggle source
# File lib/bibliothecary/runner.rb, line 67
def load_file_info_list_from_paths(paths)
  file_list = []

  paths.each do |path|
    info = FileInfo.new(nil, path)

    next if ignored_files.include?(info.relative_path)

    add_matching_package_managers_for_file_to_list(file_list, info)
  end

  file_list
end
load_file_list(path) click to toggle source

deprecated; use load_file_info_list.

# File lib/bibliothecary/runner.rb, line 36
def load_file_list(path)
  load_file_info_list(path).map { |info| info.full_path }
end
package_managers() click to toggle source
# File lib/bibliothecary/runner.rb, line 45
def package_managers
  Bibliothecary::Parsers.constants.map{|c| Bibliothecary::Parsers.const_get(c) }.sort_by{|c| c.to_s.downcase }
end

Private Instance Methods

add_matching_package_managers_for_file_to_list(file_list, file_info) click to toggle source

Get the list of all package managers that apply to the file provided as file_info, and, for each one, duplicate file_info and fill in the appropriate package manager.

# File lib/bibliothecary/runner.rb, line 170
def add_matching_package_managers_for_file_to_list(file_list, file_info)
  applicable_package_managers(file_info).each do |package_manager|
    new_file_info = file_info.dup
    new_file_info.package_manager = package_manager

    file_list.push(new_file_info)
  end
end