bibliothecary 8.6.4 → 8.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89c5d8cb9fca421230fa967e5fbc3ce68d9178b0c065cb0c20737464739fab4e
4
- data.tar.gz: 7ae9d50b5a82ae46f2c473eee0b483f2376674c97dd94ff8b1c70690973dd3d5
3
+ metadata.gz: 58c0282aec64e81ed313f123670287697f3718e64276e1260030833d70baf892
4
+ data.tar.gz: be3e9107d5fb2a0968acca81878d4c0bab062bf5b9d994121af2d682a4e8d278
5
5
  SHA512:
6
- metadata.gz: 29b2d8750cb9611c3a7cef9946fbaf12e8eb6d73d95ecbd604b4ac41c4428a07361f8d67db8ccece341d1f5c59c2b70510695f947bc060ae7a44f3e395126589
7
- data.tar.gz: 418b9879a3028dc396e996972c49be58fb1a63a3ec707e035d7b9c9cccdbdcefe919ff741a37d71a719cffc15145b4f362534ed83e72e8debbff2e73c4ffdee8
6
+ metadata.gz: 211d953af085e4495325cdd450816f6747ce42b1d8e9c55852e2a50786190466a885cd70b8c454ec1c5d6872ce55f6d8a8ecddd03be7ca2faa02450216f84242
7
+ data.tar.gz: 74ba743b92e5858c8cc6d7341bf2dda8ff9ce7fdabdff58f44e544554fbc538ae9909726cfcb588d222fa9e1b490d0db9e4ff45896f6f13c375fd1e4ea978f95
@@ -17,26 +17,6 @@ module Bibliothecary
17
17
  NoComponents = Class.new(StandardError)
18
18
 
19
19
  class ManifestEntries
20
- # If a purl type (key) exists, it will be used in a manifest for
21
- # the key's value. If not, it's ignored.
22
- #
23
- # https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst
24
- PURL_TYPE_MAPPING = {
25
- "golang" => :go,
26
- "maven" => :maven,
27
- "npm" => :npm,
28
- "cargo" => :cargo,
29
- "composer" => :packagist,
30
- "conda" => :conda,
31
- "cran" => :cran,
32
- "gem" => :rubygems,
33
- "hackage" => :hackage,
34
- "hex" => :hex,
35
- "nuget" => :nuget,
36
- "pypi" => :pypi,
37
- "swift" => :swift_pm
38
- }
39
-
40
20
  attr_reader :manifests
41
21
 
42
22
  def initialize(parse_queue:)
@@ -49,7 +29,7 @@ module Bibliothecary
49
29
  end
50
30
 
51
31
  def <<(purl)
52
- mapping = PURL_TYPE_MAPPING[purl.type]
32
+ mapping = Bibliothecary::PURL_TYPE_MAPPING[purl.type]
53
33
  return unless mapping
54
34
 
55
35
  @manifests[mapping] ||= Set.new
@@ -0,0 +1,98 @@
1
+ # packageurl-ruby uses pattern-matching (https://docs.ruby-lang.org/en/2.7.0/NEWS.html#label-Pattern+matching)
2
+ # which warns a whole bunch in Ruby 2.7 as being an experimental feature, but has
3
+ # been accepted in Ruby 3.0 (https://rubyreferences.github.io/rubychanges/3.0.html#pattern-matching).
4
+ Warning[:experimental] = false
5
+ require 'package_url'
6
+ Warning[:experimental] = true
7
+
8
+ module Bibliothecary
9
+ module MultiParsers
10
+ module Spdx
11
+ include Bibliothecary::Analyser
12
+ include Bibliothecary::Analyser::TryCache
13
+
14
+ # e.g. 'SomeText:' (allowing for leading whitespace)
15
+ WELLFORMED_LINE_REGEX = /^\s*[a-zA-Z]+:/
16
+
17
+ # e.g. 'PackageName: (allowing for excessive whitespace)
18
+ PACKAGE_NAME_REGEX = /^\s*PackageName:\s*(.*)/
19
+
20
+ # e.g. 'PackageVersion:' (allowing for excessive whitespace)
21
+ PACKAGE_VERSION_REGEX =/^\s*PackageVersion:\s*(.*)/
22
+
23
+ # e.g. "ExternalRef: PACKAGE-MANAGER purl (allowing for excessive whitespace)
24
+ PURL_REGEX = /^\s*ExternalRef:\s*PACKAGE[-|_]MANAGER\s*purl\s*(.*)/
25
+
26
+ NoEntries = Class.new(StandardError)
27
+ MalformedFile = Class.new(StandardError)
28
+
29
+ def self.mapping
30
+ {
31
+ match_extension('.spdx') => {
32
+ kind: 'lockfile',
33
+ parser: :parse_spdx_tag_value,
34
+ ungroupable: true
35
+ }
36
+ }
37
+ end
38
+
39
+ def parse_spdx_tag_value(file_contents, options: {})
40
+ entries = try_cache(options, options[:filename]) do
41
+ parse_spdx_tag_value_file_contents(file_contents)
42
+ end
43
+
44
+ raise NoEntries if entries.empty?
45
+
46
+ entries[platform_name.to_sym]
47
+ end
48
+
49
+ def get_platform(purl_string)
50
+ platform = PackageURL.parse(purl_string).type
51
+
52
+ Bibliothecary::PURL_TYPE_MAPPING[platform]
53
+ end
54
+
55
+ def parse_spdx_tag_value_file_contents(file_contents)
56
+ entries = {}
57
+
58
+ package_name = nil
59
+ package_version = nil
60
+ platform = nil
61
+
62
+ file_contents.split("\n").each do |line|
63
+ stripped_line = line.strip
64
+
65
+ next if skip_line?(stripped_line)
66
+
67
+ raise MalformedFile unless stripped_line.match(WELLFORMED_LINE_REGEX)
68
+
69
+ if (match = stripped_line.match(PACKAGE_NAME_REGEX))
70
+ package_name = match[1]
71
+ elsif (match = stripped_line.match(PACKAGE_VERSION_REGEX))
72
+ package_version = match[1]
73
+ elsif (match = stripped_line.match(PURL_REGEX))
74
+ platform ||= get_platform(match[1])
75
+ end
76
+
77
+ unless package_name.nil? || package_version.nil? || platform.nil?
78
+ entries[platform.to_sym] ||= []
79
+ entries[platform.to_sym] << {
80
+ name: package_name,
81
+ requirement: package_version,
82
+ type: 'lockfile'
83
+ }
84
+
85
+ package_name = package_version = platform = nil
86
+ end
87
+ end
88
+
89
+ entries
90
+ end
91
+
92
+ def skip_line?(stripped_line)
93
+ # Ignore blank lines and comments
94
+ stripped_line == "" || stripped_line[0] == "#"
95
+ end
96
+ end
97
+ end
98
+ end
@@ -17,6 +17,7 @@ module Bibliothecary
17
17
  end
18
18
 
19
19
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
20
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
20
21
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
21
22
 
22
23
  def self.parse_manifest(file_contents, options: {})
@@ -28,6 +28,7 @@ module Bibliothecary
28
28
 
29
29
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
30
30
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
31
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
31
32
 
32
33
  def self.parse_conda(file_contents, options: {})
33
34
  parse_conda_with_kind(file_contents, "manifest")
@@ -18,6 +18,7 @@ module Bibliothecary
18
18
 
19
19
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
20
20
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
21
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
21
22
 
22
23
  def self.parse_description(file_contents, options: {})
23
24
  manifest = DebControl::ControlFileBase.parse(file_contents)
@@ -66,6 +66,7 @@ module Bibliothecary
66
66
  end
67
67
 
68
68
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
69
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
69
70
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
70
71
 
71
72
  def self.parse_godep_json(file_contents, options: {})
@@ -21,6 +21,7 @@ module Bibliothecary
21
21
 
22
22
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
23
23
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
24
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
24
25
 
25
26
  def self.parse_cabal(file_contents, options: {})
26
27
  headers = {
@@ -20,6 +20,7 @@ module Bibliothecary
20
20
 
21
21
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
22
22
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
23
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
23
24
 
24
25
  def self.parse_mix(file_contents, options: {})
25
26
  response = Typhoeus.post("#{Bibliothecary.configuration.mix_parser_host}/", body: file_contents)
@@ -25,15 +25,15 @@ module Bibliothecary
25
25
  # Deprecated methods: https://docs.gradle.org/current/userguide/upgrading_version_6.html#sec:configuration_removal
26
26
  GRADLE_DEPENDENCY_METHODS = %w(api compile compileClasspath compileOnly compileOnlyApi implementation runtime runtimeClasspath runtimeOnly testCompile testCompileOnly testImplementation testRuntime testRuntimeOnly)
27
27
 
28
- # Intentionally overly-simplified regexes to scrape deps from build.gradle (Groovy) and build.gradle.kts (Kotlin) files.
29
- # To be truly useful bibliothecary would need full Groovy / Kotlin parsers that speaks Gradle,
28
+ # Intentionally overly-simplified regexes to scrape deps from build.gradle (Groovy) and build.gradle.kts (Kotlin) files.
29
+ # To be truly useful bibliothecary would need full Groovy / Kotlin parsers that speaks Gradle,
30
30
  # because the Groovy and Kotlin DSLs have many dynamic ways of declaring dependencies.
31
31
  GRADLE_VERSION_REGEX = /[\w.-]+/ # e.g. '1.2.3'
32
32
  GRADLE_VAR_INTERPOLATION_REGEX = /\$\w+/ # e.g. '$myVersion'
33
33
  GRADLE_CODE_INTERPOLATION_REGEX = /\$\{.*\}/ # e.g. '${my-project-settings["version"]}'
34
34
  GRADLE_GAV_REGEX = /([\w.-]+)\:([\w.-]+)(?:\:(#{GRADLE_VERSION_REGEX}|#{GRADLE_VAR_INTERPOLATION_REGEX}|#{GRADLE_CODE_INTERPOLATION_REGEX}))?/ # e.g. "group:artifactId:1.2.3"
35
- GRADLE_GROOVY_SIMPLE_REGEX = /(#{GRADLE_DEPENDENCY_METHODS.join('|')})\s*\(?\s*['"]#{GRADLE_GAV_REGEX}['"]/m
36
- GRADLE_KOTLIN_SIMPLE_REGEX = /(#{GRADLE_DEPENDENCY_METHODS.join('|')})\s*\(\s*"#{GRADLE_GAV_REGEX}"/m
35
+ GRADLE_GROOVY_SIMPLE_REGEX = /(#{GRADLE_DEPENDENCY_METHODS.join('|')})\s*\(?\s*['"]#{GRADLE_GAV_REGEX}['"]/m
36
+ GRADLE_KOTLIN_SIMPLE_REGEX = /(#{GRADLE_DEPENDENCY_METHODS.join('|')})\s*\(\s*"#{GRADLE_GAV_REGEX}"/m
37
37
 
38
38
  MAVEN_PROPERTY_REGEX = /\$\{(.+?)\}/
39
39
  MAX_DEPTH = 5
@@ -96,6 +96,7 @@ module Bibliothecary
96
96
  end
97
97
 
98
98
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
99
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
99
100
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
100
101
 
101
102
  def self.parse_ivy_manifest(file_contents, options: {})
@@ -162,7 +163,7 @@ module Bibliothecary
162
163
  # so we treat these projects as "internal" deps with requirement of "1.0.0"
163
164
  if (project_match = line.match(GRADLE_PROJECT_REGEX))
164
165
  # an empty project name is self-referential (i.e. a cycle), and we don't need to track the manifest's project itself, e.g. "+--- project :"
165
- next if project_match[1].nil?
166
+ next if project_match[1].nil?
166
167
 
167
168
  # project names can have colons (e.g. for gradle projects in subfolders), which breaks maven artifact naming assumptions, so just replace them with hyphens.
168
169
  project_name = project_match[1].gsub(/:/, "-")
@@ -34,6 +34,7 @@ module Bibliothecary
34
34
  end
35
35
 
36
36
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
37
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
37
38
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
38
39
 
39
40
  def self.parse_package_lock(file_contents, options: {})
@@ -57,9 +58,9 @@ module Bibliothecary
57
58
  def self.parse_package_lock_v1(manifest)
58
59
  parse_package_lock_deps_recursively(manifest.fetch('dependencies', []))
59
60
  end
60
-
61
+
61
62
  def self.parse_package_lock_v2(manifest)
62
- # "packages" is a flat object where each key is the installed location of the dep, e.g. node_modules/foo/node_modules/bar.
63
+ # "packages" is a flat object where each key is the installed location of the dep, e.g. node_modules/foo/node_modules/bar.
63
64
  manifest
64
65
  .fetch("packages")
65
66
  .reject { |name, dep| name == "" } # this is the lockfile's package itself
@@ -68,7 +69,7 @@ module Bibliothecary
68
69
  name: name.split("node_modules/").last,
69
70
  requirement: dep["version"],
70
71
  type: dep.fetch("dev", false) || dep.fetch("devOptional", false) ? "development" : "runtime"
71
- }
72
+ }
72
73
  end
73
74
  end
74
75
 
@@ -94,7 +95,7 @@ module Bibliothecary
94
95
  def self.parse_manifest(file_contents, options: {})
95
96
  manifest = JSON.parse(file_contents)
96
97
  raise "appears to be a lockfile rather than manifest format" if manifest.key?('lockfileVersion')
97
-
98
+
98
99
  (
99
100
  map_dependencies(manifest, 'dependencies', 'runtime') +
100
101
  map_dependencies(manifest, 'devDependencies', 'development')
@@ -46,6 +46,7 @@ module Bibliothecary
46
46
 
47
47
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
48
48
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
49
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
49
50
 
50
51
  def self.parse_project_lock_json(file_contents, options: {})
51
52
  manifest = JSON.parse file_contents
@@ -20,6 +20,7 @@ module Bibliothecary
20
20
 
21
21
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
22
22
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
23
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
23
24
 
24
25
  def self.parse_lockfile(file_contents, options: {})
25
26
  manifest = JSON.parse file_contents
@@ -87,6 +87,7 @@ module Bibliothecary
87
87
 
88
88
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
89
89
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
90
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
90
91
 
91
92
  def self.parse_pipfile(file_contents, options: {})
92
93
  manifest = Tomlrb.parse(file_contents)
@@ -94,10 +95,10 @@ module Bibliothecary
94
95
  end
95
96
 
96
97
  def self.parse_pyproject(file_contents, options: {})
97
- deps = []
98
+ deps = []
98
99
 
99
100
  file_contents = Tomlrb.parse(file_contents)
100
-
101
+
101
102
  # Parse poetry [tool.poetry] deps
102
103
  poetry_manifest = file_contents.fetch('tool', {}).fetch('poetry', {})
103
104
  deps += map_dependencies(poetry_manifest['dependencies'], 'runtime')
@@ -32,6 +32,7 @@ module Bibliothecary
32
32
 
33
33
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
34
34
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
35
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
35
36
 
36
37
  def self.parse_gemfile_lock(file_contents, options: {})
37
38
  file_contents.lines(chomp: true).map do |line|
@@ -14,6 +14,7 @@ module Bibliothecary
14
14
 
15
15
  add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
16
16
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
17
+ add_multi_parser(Bibliothecary::MultiParsers::Spdx)
17
18
 
18
19
  def self.parse_package_swift(file_contents, options: {})
19
20
  response = Typhoeus.post("#{Bibliothecary.configuration.swift_parser_host}/to-json", body: file_contents)
@@ -0,0 +1,21 @@
1
+ module Bibliothecary
2
+ # If a purl type (key) exists, it will be used in a manifest for
3
+ # the key's value. If not, it's ignored.
4
+ #
5
+ # https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst
6
+ PURL_TYPE_MAPPING = {
7
+ "golang" => :go,
8
+ "maven" => :maven,
9
+ "npm" => :npm,
10
+ "cargo" => :cargo,
11
+ "composer" => :packagist,
12
+ "conda" => :conda,
13
+ "cran" => :cran,
14
+ "gem" => :rubygems,
15
+ "hackage" => :hackage,
16
+ "hex" => :hex,
17
+ "nuget" => :nuget,
18
+ "pypi" => :pypi,
19
+ "swift" => :swift_pm
20
+ }.freeze
21
+ end
@@ -1,3 +1,3 @@
1
1
  module Bibliothecary
2
- VERSION = "8.6.4"
2
+ VERSION = "8.6.5"
3
3
  end
data/lib/bibliothecary.rb CHANGED
@@ -5,6 +5,7 @@ require "bibliothecary/runner"
5
5
  require "bibliothecary/exceptions"
6
6
  require "bibliothecary/file_info"
7
7
  require "bibliothecary/related_files_info"
8
+ require "bibliothecary/purl_util"
8
9
  require "find"
9
10
  require "tomlrb"
10
11
 
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: 8.6.4
4
+ version: 8.6.5
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: 2023-07-02 00:00:00.000000000 Z
11
+ date: 2023-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tomlrb
@@ -248,7 +248,7 @@ dependencies:
248
248
  - - ">="
249
249
  - !ruby/object:Gem::Version
250
250
  version: '0'
251
- description:
251
+ description:
252
252
  email:
253
253
  - andrewnez@gmail.com
254
254
  executables:
@@ -290,6 +290,7 @@ files:
290
290
  - lib/bibliothecary/multi_parsers/cyclonedx.rb
291
291
  - lib/bibliothecary/multi_parsers/dependencies_csv.rb
292
292
  - lib/bibliothecary/multi_parsers/json_runtime.rb
293
+ - lib/bibliothecary/multi_parsers/spdx.rb
293
294
  - lib/bibliothecary/parsers/bower.rb
294
295
  - lib/bibliothecary/parsers/cargo.rb
295
296
  - lib/bibliothecary/parsers/carthage.rb
@@ -315,6 +316,7 @@ files:
315
316
  - lib/bibliothecary/parsers/rubygems.rb
316
317
  - lib/bibliothecary/parsers/shard.rb
317
318
  - lib/bibliothecary/parsers/swift_pm.rb
319
+ - lib/bibliothecary/purl_util.rb
318
320
  - lib/bibliothecary/related_files_info.rb
319
321
  - lib/bibliothecary/runner.rb
320
322
  - lib/bibliothecary/runner/multi_manifest_filter.rb
@@ -324,7 +326,7 @@ homepage: https://github.com/librariesio/bibliothecary
324
326
  licenses:
325
327
  - AGPL-3.0
326
328
  metadata: {}
327
- post_install_message:
329
+ post_install_message:
328
330
  rdoc_options: []
329
331
  require_paths:
330
332
  - lib
@@ -339,8 +341,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
339
341
  - !ruby/object:Gem::Version
340
342
  version: '0'
341
343
  requirements: []
342
- rubygems_version: 3.3.22
343
- signing_key:
344
+ rubygems_version: 3.1.6
345
+ signing_key:
344
346
  specification_version: 4
345
347
  summary: Find and parse manifests
346
348
  test_files: []