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
# File lib/bibliothecary/runner.rb, line 6 def initialize(configuration) @configuration = configuration @options = { cache: {}, } end
Public Instance Methods
# 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
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
# 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
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
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
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
# 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
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
# File lib/bibliothecary/runner.rb, line 147 def ignored_dirs @configuration.ignored_dirs end
# File lib/bibliothecary/runner.rb, line 151 def ignored_files @configuration.ignored_files end
# 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
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
# 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
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
# 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
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