Class: Bibliothecary::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/bibliothecary/runner.rb,
lib/bibliothecary/runner/multi_manifest_filter.rb

Overview

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.

Defined Under Namespace

Classes: MultiManifestFilter

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Runner

Returns a new instance of Runner.



6
7
8
9
10
11
# File 'lib/bibliothecary/runner.rb', line 6

def initialize(configuration)
  @configuration = configuration
  @options = {
    cache: {}
  }
end

Instance Method Details

#analyse(path, ignore_unparseable_files: true) ⇒ Object Also known as: analyze



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 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

#analyse_file(file_path, contents) ⇒ Object Also known as: analyze_file

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



118
119
120
121
122
123
124
# 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

#applicable_package_managers(info) ⇒ Object



40
41
42
43
# 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) ⇒ Object

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.



161
162
163
# 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) ⇒ Array<Bibliothecary::RelatedFilesInfo>

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



100
101
102
# 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) ⇒ Object

file_path_contents_hash contains an Array of { file_path, contents }



109
110
111
112
113
114
115
# 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) ⇒ Object



104
105
106
# 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) ⇒ Object

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.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# 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_dirsObject



147
148
149
# File 'lib/bibliothecary/runner.rb', line 147

def ignored_dirs
  @configuration.ignored_dirs
end

#ignored_filesObject



151
152
153
# File 'lib/bibliothecary/runner.rb', line 151

def ignored_files
  @configuration.ignored_files
end

#load_file_info_list(path) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# 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) ⇒ Array<Bibliothecary::FileInfo>

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

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
65
# 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) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# 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) ⇒ Object

deprecated; use load_file_info_list.



36
37
38
# File 'lib/bibliothecary/runner.rb', line 36

def load_file_list(path)
  load_file_info_list(path).map { |info| info.full_path }
end

#package_managersObject



45
46
47
# 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