bibliothecary 7.3.0 → 7.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6bf41693f3224f06747aa8ea8799d369d68b262033689b900fe1a18c35803b85
4
- data.tar.gz: 4cee903aaa6fff7e24e7ca4f8ddd162d2dd42af4ec04161fac21397622e6f5cd
3
+ metadata.gz: f9cdc8b0bab4370b5ae6a4a6762e3284bf5c2d8dac3ea8245e58951035d23bd3
4
+ data.tar.gz: ed8b124a915ef7abc4453b0108e0ddbf491b5e1958f6e44df592ba3386a7de58
5
5
  SHA512:
6
- metadata.gz: c178932cf88d945686cfa34ab2e9cf581c2b99878d51e2fc783e98804b63737f7f852a1017c81c4aec9c8ca7f425b54b3092722f95b767e37be07fce343a2740
7
- data.tar.gz: b11a8ea3373f61fb2d1def0f203a400c864f30eec52faa77551d256cdc1a9c27e20e960b4151713982987faea0af8529e83f0d8606129613591487a358c26755
6
+ metadata.gz: 337ad0b7fb2585f5d557458176be1933ba89c0be4863486a310e3e7cc4cce6b230b0461b42bbca4e76f058e6a10031e24799f8a6d72adc49d0ff30f7bc1cd257
7
+ data.tar.gz: f4a6b28b6e815a255fa6e7e2917df95b70204bb657b2a92c58f8d85badfe71cbe1f7e83c43fbe23fdc53f016cc3b417c4de47832841d7105e3b3f5f4295ca57d
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ *.gem
@@ -25,6 +25,10 @@ module Bibliothecary
25
25
  base.extend(ClassMethods)
26
26
  end
27
27
  module ClassMethods
28
+ def generic?
29
+ platform_name == "generic"
30
+ end
31
+
28
32
  def mapping_entry_match?(matcher, details, info)
29
33
  if matcher.call(info.relative_path)
30
34
  # we only want to load contents if we don't have them already
@@ -119,13 +123,32 @@ module Bibliothecary
119
123
  end
120
124
  alias analyze_contents analyse_contents
121
125
 
126
+ def dependencies_to_analysis(info, kind, dependencies)
127
+ dependencies = dependencies || [] # work around any legacy parsers that return nil
128
+ if generic?
129
+ analyses = []
130
+ grouped = dependencies.group_by { |dep| dep[:platform] }
131
+ all_analyses = grouped.keys.map do |platform|
132
+ deplatformed_dependencies = grouped[platform].map { |d| d.delete(:platform); d }
133
+ Bibliothecary::Analyser::create_analysis(platform, info.relative_path, kind, deplatformed_dependencies)
134
+ end
135
+ # this is to avoid a larger refactor for the time being. The larger refactor
136
+ # needs to make analyse_contents return multiple analysis, or add another
137
+ # method that can return multiple and deprecate analyse_contents, perhaps.
138
+ raise "File contains zero or multiple platforms, currently must have exactly one" if all_analyses.length != 1
139
+ all_analyses.first
140
+ else
141
+ Bibliothecary::Analyser::create_analysis(platform_name, info.relative_path, kind, dependencies)
142
+ end
143
+ end
144
+
122
145
  def analyse_contents_from_info(info)
123
146
  # If your Parser needs to return multiple responses for one file, please override this method
124
147
  # For example see conda.rb
125
148
  kind = determine_kind_from_info(info)
126
149
  dependencies = parse_file(info.relative_path, info.contents)
127
150
 
128
- Bibliothecary::Analyser::create_analysis(platform_name, info.relative_path, kind, dependencies || [])
151
+ dependencies_to_analysis(info, kind, dependencies)
129
152
  rescue Bibliothecary::FileParsingError => e
130
153
  Bibliothecary::Analyser::create_error_analysis(platform_name, info.relative_path, kind, e.message)
131
154
  end
@@ -0,0 +1,39 @@
1
+ require 'csv'
2
+
3
+ module Bibliothecary
4
+ module Parsers
5
+ class Generic
6
+ include Bibliothecary::Analyser
7
+
8
+ def self.mapping
9
+ {
10
+ match_filename("dependencies.csv") => {
11
+ kind: 'lockfile',
12
+ parser: :parse_lockfile
13
+ }
14
+ }
15
+ end
16
+
17
+ def self.parse_lockfile(file_contents)
18
+ table = CSV.parse(file_contents, headers: true)
19
+
20
+ required_headers = ["platform", "name", "requirement"]
21
+ missing_headers = required_headers - table.headers
22
+ raise "Missing headers #{missing_headers} in CSV" unless missing_headers.empty?
23
+
24
+ table.map.with_index do |row, idx|
25
+ line = idx + 1
26
+ required_headers.each do |h|
27
+ raise "missing field '#{h}' on line #{line}" if row[h].empty?
28
+ end
29
+ {
30
+ platform: row['platform'],
31
+ name: row['name'],
32
+ requirement: row['requirement'],
33
+ type: row.fetch('type', 'runtime'),
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -127,10 +127,12 @@ module Bibliothecary
127
127
 
128
128
  split = gradle_dep_match.captures[0]
129
129
 
130
- # org.springframework.boot:spring-boot-starter-web:2.1.0.M3 (*)
131
- # Lines can end with (c), (n), or (*)
132
- # to indicate that something was a dependency constraint (c), not resolved (n), or resolved previously (*).
133
- dep = line.split(split)[1].sub(/(\((c|n|\*)\))$/, "").sub(" -> ", ":").strip.split(":")
130
+
131
+ dep = line
132
+ .split(split)[1].sub(/(\((c|n|\*)\))$/, "") # line ending legend: (c) means a dependency constraint, (n) means not resolved, or (*) means resolved previously, e.g. org.springframework.boot:spring-boot-starter-web:2.1.0.M3 (*)
133
+ .sub(/ FAILED$/, "") # dependency could not be resolved (but still may have a version)
134
+ .sub(" -> ", ":") # handle version arrow syntax
135
+ .strip.split(":")
134
136
 
135
137
  # A testImplementation line can look like this so just skip those
136
138
  # \--- org.springframework.security:spring-security-test (n)
@@ -279,7 +281,7 @@ module Bibliothecary
279
281
  non_prop_name = property_name.gsub(".", "/").gsub("project/", "")
280
282
  return "${#{property_name}}" if !xml.respond_to?("properties") && parent_properties.empty? && xml.locate(non_prop_name).empty?
281
283
 
282
- prop_field = xml.properties.locate(property_name).first
284
+ prop_field = xml.properties.locate(property_name).first if xml.respond_to?("properties")
283
285
  parent_prop = parent_properties[property_name]
284
286
  if prop_field
285
287
  prop_field.nodes.first
@@ -97,6 +97,18 @@ module Bibliothecary
97
97
  transform_tree_to_array(manifest.fetch('dependencies', {}))
98
98
  end
99
99
 
100
+ def self.lockfile_preference_order(file_infos)
101
+ files = file_infos.each_with_object({}) do |file_info, obj|
102
+ obj[File.basename(file_info.full_path)] = file_info
103
+ end
104
+
105
+ if files["npm-shrinkwrap.json"]
106
+ [files["npm-shrinkwrap.json"]] + files.values.reject { |fi| File.basename(fi.full_path) == "npm-shrinkwrap.json" }
107
+ else
108
+ files.values
109
+ end
110
+ end
111
+
100
112
  private_class_method def self.transform_tree_to_array(deps_by_name)
101
113
  deps_by_name.map do |name, metadata|
102
114
  [
@@ -19,6 +19,9 @@ module Bibliothecary
19
19
 
20
20
  def initialize(file_infos)
21
21
  package_manager = file_infos.first.package_manager
22
+ if package_manager.respond_to?(:lockfile_preference_order)
23
+ file_infos = package_manager.lockfile_preference_order(file_infos)
24
+ end
22
25
  @platform = package_manager.platform_name
23
26
  @path = Pathname.new(File.dirname(file_infos.first.relative_path)).cleanpath.to_path
24
27
  # `package_manager.determine_kind_from_info(info)` can be an Array, so use include? which also works for string
@@ -1,3 +1,3 @@
1
1
  module Bibliothecary
2
- VERSION = "7.3.0"
2
+ VERSION = "7.3.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bibliothecary
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.0
4
+ version: 7.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-25 00:00:00.000000000 Z
11
+ date: 2021-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tomlrb
@@ -206,7 +206,7 @@ dependencies:
206
206
  - - ">="
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
- description:
209
+ description:
210
210
  email:
211
211
  - andrewnez@gmail.com
212
212
  executables:
@@ -251,6 +251,7 @@ files:
251
251
  - lib/bibliothecary/parsers/cran.rb
252
252
  - lib/bibliothecary/parsers/dub.rb
253
253
  - lib/bibliothecary/parsers/elm.rb
254
+ - lib/bibliothecary/parsers/generic.rb
254
255
  - lib/bibliothecary/parsers/go.rb
255
256
  - lib/bibliothecary/parsers/hackage.rb
256
257
  - lib/bibliothecary/parsers/haxelib.rb
@@ -274,7 +275,7 @@ homepage: https://github.com/librariesio/bibliothecary
274
275
  licenses:
275
276
  - AGPL-3.0
276
277
  metadata: {}
277
- post_install_message:
278
+ post_install_message:
278
279
  rdoc_options: []
279
280
  require_paths:
280
281
  - lib
@@ -290,7 +291,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
291
  version: '0'
291
292
  requirements: []
292
293
  rubygems_version: 3.1.2
293
- signing_key:
294
+ signing_key:
294
295
  specification_version: 4
295
296
  summary: Find and parse manifests
296
297
  test_files: []