module Bibliothecary::Analyser::Analysis

Public Instance Methods

analyse(folder_path, file_list, options: {}) click to toggle source

Convenience method to create FileInfo objects from folder path and file list.

@param folder_path [String] @param file_list [Array<String>] @param options [Hash]

# File lib/bibliothecary/analyser/analysis.rb, line 10
def analyse(folder_path, file_list, options: {})
  analyse_file_info(file_list.map { |full_path| FileInfo.new(folder_path, full_path) }, options: options)
end
Also aliased as: analyze
analyse_contents(filename, contents, options: {}) click to toggle source
# File lib/bibliothecary/analyser/analysis.rb, line 29
def analyse_contents(filename, contents, options: {})
  analyse_contents_from_info(FileInfo.new(nil, filename, contents), options: options)
end
Also aliased as: analyze_contents
analyse_contents_from_info(info, options: {}) click to toggle source

This is the place a parsing operation will eventually end up.

@param info [FileInfo]

# File lib/bibliothecary/analyser/analysis.rb, line 37
def analyse_contents_from_info(info, options: {})
  # If your Parser needs to return multiple responses for one file, please override this method
  # For example see conda.rb
  kind = determine_kind_from_info(info)
  dependencies = parse_file(info.relative_path, info.contents, options: options)

  dependencies_to_analysis(info, kind, dependencies)
rescue Bibliothecary::FileParsingError => e
  Bibliothecary::Analyser::create_error_analysis(platform_name, info.relative_path, kind, e.message, e.location)
end
Also aliased as: analyze_contents_from_info
analyse_file_info(file_info_list, options: {}) click to toggle source

Analyze a set of FileInfo objects and extract manifests from them all.

@params file_info_list [Array<FileInfo>]

# File lib/bibliothecary/analyser/analysis.rb, line 18
def analyse_file_info(file_info_list, options: {})
  matching_info = file_info_list
    .select(&method(:match_info?))

  matching_info.flat_map do |info|
    analyse_contents_from_info(info, options: options)
      .merge(related_paths: related_paths(info, matching_info))
  end
end
Also aliased as: analyze_file_info
analyze(folder_path, file_list, options: {})
Alias for: analyse
analyze_contents(filename, contents, options: {})
Alias for: analyse_contents
analyze_contents_from_info(info, options: {})
analyze_file_info(file_info_list, options: {})
Alias for: analyse_file_info
dependencies_to_analysis(info, kind, dependencies) click to toggle source
# File lib/bibliothecary/analyser/analysis.rb, line 49
def dependencies_to_analysis(info, kind, dependencies)
  dependencies = dependencies || [] # work around any legacy parsers that return nil
  if generic?
    grouped = dependencies.group_by { |dep| dep[:platform] }
    all_analyses = grouped.keys.map do |platform|
      deplatformed_dependencies = grouped[platform].map { |d| d.delete(:platform); d }
      Bibliothecary::Analyser::create_analysis(platform, info.relative_path, kind, deplatformed_dependencies)
    end
    # this is to avoid a larger refactor for the time being. The larger refactor
    # needs to make analyse_contents return multiple analysis, or add another
    # method that can return multiple and deprecate analyse_contents, perhaps.
    raise "File contains zero or multiple platforms, currently must have exactly one" if all_analyses.length != 1
    all_analyses.first
  else
    Bibliothecary::Analyser::create_analysis(platform_name, info.relative_path, kind, dependencies)
  end
end
parse_file(filename, contents, options: {}) click to toggle source

Call the matching parse class method for this file with these contents

# File lib/bibliothecary/analyser/analysis.rb, line 69
def parse_file(filename, contents, options: {})
  details = first_matching_mapping_details(FileInfo.new(nil, filename, contents))

  # this can be raised if we don't check match?/match_info?,
  # OR don't have the file contents when we check them, so
  # it turns out for example that a .xml file isn't a
  # manifest after all.
  raise Bibliothecary::FileParsingError.new("No parser for this file type", filename) unless details[:parser]

  # The `parser` method should raise an exception if the file is malformed,
  # should return empty [] if the file is fine but simply doesn't contain
  # any dependencies, and should never return nil. At the time of writing
  # this comment, some of the parsers return [] or nil to mean an error
  # which is confusing to users.
  send(details[:parser], contents, options: options.merge(filename: filename))

rescue Exception => e # default is StandardError but C bindings throw Exceptions
  # the C xml parser also puts a newline at the end of the message
  location = e.backtrace_locations[0]
    .to_s
    .then { |l| l =~ /bibliothecary\// ? l.split("bibliothecary/").last : l.split("gems/").last }
  raise Bibliothecary::FileParsingError.new(e.message.strip, filename, location)
end

Private Instance Methods