bibliothecary 14.4.0 → 15.0.0
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 +4 -4
- data/CHANGELOG.md +14 -0
- data/UPGRADING_TO_15_0_0.md +264 -0
- data/lib/bibliothecary/analyser/analysis.rb +2 -2
- data/lib/bibliothecary/analyser.rb +24 -20
- data/lib/bibliothecary/dependency.rb +1 -4
- data/lib/bibliothecary/file_info.rb +7 -3
- data/lib/bibliothecary/multi_parsers/cyclonedx.rb +24 -21
- data/lib/bibliothecary/multi_parsers/dependencies_csv.rb +7 -4
- data/lib/bibliothecary/multi_parsers/spdx.rb +40 -26
- data/lib/bibliothecary/{multi_parsers → parser_mixins}/bundler_like_manifest.rb +1 -1
- data/lib/bibliothecary/{multi_parsers → parser_mixins}/json_runtime.rb +1 -1
- data/lib/bibliothecary/parsers/bower.rb +0 -2
- data/lib/bibliothecary/parsers/cargo.rb +0 -4
- data/lib/bibliothecary/parsers/cocoapods.rb +1 -3
- data/lib/bibliothecary/parsers/conan.rb +0 -4
- data/lib/bibliothecary/parsers/conda.rb +0 -4
- data/lib/bibliothecary/parsers/cpan.rb +0 -2
- data/lib/bibliothecary/parsers/cran.rb +0 -4
- data/lib/bibliothecary/parsers/dub.rb +1 -3
- data/lib/bibliothecary/parsers/elm.rb +1 -3
- data/lib/bibliothecary/parsers/go.rb +0 -4
- data/lib/bibliothecary/parsers/haxelib.rb +1 -3
- data/lib/bibliothecary/parsers/julia.rb +0 -2
- data/lib/bibliothecary/parsers/maven.rb +0 -4
- data/lib/bibliothecary/parsers/meteor.rb +1 -3
- data/lib/bibliothecary/parsers/npm.rb +0 -4
- data/lib/bibliothecary/parsers/nuget.rb +1 -5
- data/lib/bibliothecary/parsers/packagist.rb +0 -4
- data/lib/bibliothecary/parsers/pub.rb +0 -2
- data/lib/bibliothecary/parsers/pypi.rb +0 -4
- data/lib/bibliothecary/parsers/rubygems.rb +1 -5
- data/lib/bibliothecary/parsers/shard.rb +0 -2
- data/lib/bibliothecary/parsers/vcpkg.rb +0 -4
- data/lib/bibliothecary/related_files_info.rb +19 -15
- data/lib/bibliothecary/runner/multi_manifest_filter.rb +2 -83
- data/lib/bibliothecary/runner.rb +40 -23
- data/lib/bibliothecary/version.rb +1 -1
- data/lib/bibliothecary.rb +16 -3
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f0d3fafafd92ac4eac18f89f709733c655b0f05a803f9fcb2c1ef8b26690c584
|
|
4
|
+
data.tar.gz: b89c725a5bbbcc8139a8ebac579f610a84839e3eaaf356dd04fe4d371294ad03
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9b8caae9ff6a85ee12a1860f048e69c2910e7f48128a6621fc1c2d14ca587a79ca9478a14b5f092005edb02cc6ff00ee2819d6788a6a7f8fa95d5f10f1addf67
|
|
7
|
+
data.tar.gz: 408d3891213550d27395f65587010ee0c4a49da47fb290e3805971dbe7f41b7fe2add33c3d3c4dbe646e084b6536e4a33c15928e8560d32ffaa8fde45332b14b
|
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
13
|
|
|
14
14
|
### Removed
|
|
15
15
|
|
|
16
|
+
## [15.0.0]
|
|
17
|
+
|
|
18
|
+
15.0.0 includes some breaking changes, so please see UPGRADING_TO_15_0_0.md to migrate your code.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Make the MultiParsers (CycloneDX, Spdx, DependenciesCSV) classes instead of modules.
|
|
23
|
+
- Moved the two parser mixins, JSONRuntime and BundlerLikeManifest, into their own Bibliothecary::ParserMixins namespace.
|
|
24
|
+
- Return all dependencies from SPDX and CycloneDX files regardless of platform
|
|
25
|
+
|
|
26
|
+
### Removed
|
|
27
|
+
|
|
28
|
+
- Removed MultiManifestFilter, since it's no longer necessary
|
|
29
|
+
|
|
16
30
|
## [14.4.0]
|
|
17
31
|
|
|
18
32
|
### Added
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Upgrading to Bibliothecary 15.0.0
|
|
2
|
+
|
|
3
|
+
Bibliothecary 15.0.0 includes several breaking changes related to how parsers are structured and how analysis results are returned. This guide will help you upgrade your code.
|
|
4
|
+
|
|
5
|
+
## Breaking Changes
|
|
6
|
+
|
|
7
|
+
### 1. Analysis Results Now Use `parser` Instead of `platform`
|
|
8
|
+
|
|
9
|
+
**What Changed:**
|
|
10
|
+
- Analysis result hashes now use the key `parser:` instead of `platform:`
|
|
11
|
+
- `Bibliothecary::Analyser.create_analysis()` returns `parser:` instead of `platform:`
|
|
12
|
+
- `Bibliothecary::Analyser.create_error_analysis()` returns `parser:` instead of `platform:`
|
|
13
|
+
|
|
14
|
+
**Before (14.x):**
|
|
15
|
+
```ruby
|
|
16
|
+
analysis = Bibliothecary.analyse('path/to/project')
|
|
17
|
+
# => [{
|
|
18
|
+
# platform: "npm",
|
|
19
|
+
# path: "package.json",
|
|
20
|
+
# dependencies: [...],
|
|
21
|
+
# kind: "manifest",
|
|
22
|
+
# success: true
|
|
23
|
+
# }]
|
|
24
|
+
|
|
25
|
+
analysis.first[:platform] # => "npm"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**After (15.0):**
|
|
29
|
+
```ruby
|
|
30
|
+
analysis = Bibliothecary.analyse('path/to/project')
|
|
31
|
+
# => [{
|
|
32
|
+
# parser: "npm",
|
|
33
|
+
# path: "package.json",
|
|
34
|
+
# dependencies: [...],
|
|
35
|
+
# kind: "manifest",
|
|
36
|
+
# success: true
|
|
37
|
+
# }]
|
|
38
|
+
|
|
39
|
+
analysis.first[:parser] # => "npm"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Migration:**
|
|
43
|
+
- Replace all references to `analysis[:platform]` with `analysis[:parser]`
|
|
44
|
+
- Update any code that expects the `platform` key in analysis results
|
|
45
|
+
- Note: `Dependency` objects still use `platform:` as this refers to the ecosystem, not the parser
|
|
46
|
+
|
|
47
|
+
### 2. SBOM Files Now Return Single Parser Results
|
|
48
|
+
|
|
49
|
+
**What Changed:**
|
|
50
|
+
- SBOM files (CycloneDX, SPDX, dependencies.csv) are now parsed as standalone parser results
|
|
51
|
+
- Previously, multi-parsers would distribute dependencies across multiple platform-specific results
|
|
52
|
+
- Now, all dependencies from an SBOM file are returned in a single result with the SBOM parser name
|
|
53
|
+
|
|
54
|
+
**Before (14.x):**
|
|
55
|
+
```ruby
|
|
56
|
+
# A cyclonedx.json file containing npm and maven dependencies would return:
|
|
57
|
+
[
|
|
58
|
+
{
|
|
59
|
+
platform: "npm",
|
|
60
|
+
path: "cyclonedx.json",
|
|
61
|
+
dependencies: [<npm deps>],
|
|
62
|
+
...
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
platform: "maven",
|
|
66
|
+
path: "cyclonedx.json",
|
|
67
|
+
dependencies: [<maven deps>],
|
|
68
|
+
...
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**After (15.0):**
|
|
74
|
+
```ruby
|
|
75
|
+
# The same cyclonedx.json file now returns a single result:
|
|
76
|
+
[
|
|
77
|
+
{
|
|
78
|
+
parser: "cyclonedx",
|
|
79
|
+
path: "cyclonedx.json",
|
|
80
|
+
dependencies: [<all deps with their platform: field set>],
|
|
81
|
+
kind: "lockfile",
|
|
82
|
+
success: true
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
# Each dependency still knows its platform:
|
|
87
|
+
dependencies.first.platform # => "npm"
|
|
88
|
+
dependencies.last.platform # => "maven"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Migration:**
|
|
92
|
+
- Update code that expects SBOM files to return multiple platform-specific results
|
|
93
|
+
- Instead of filtering results by `platform`, check `result[:parser]` for "cyclonedx", "spdx", or "dependenciescsv"
|
|
94
|
+
- Group dependencies by their `Dependency#platform` field if you need platform-specific grouping
|
|
95
|
+
|
|
96
|
+
**Affected Parsers:**
|
|
97
|
+
- `cyclonedx` (cyclonedx.json, cyclonedx.xml, *.cdx.json, *.cdx.xml)
|
|
98
|
+
- `spdx` (*.spdx, *.spdx.json)
|
|
99
|
+
- `dependenciescsv` (dependencies.csv)
|
|
100
|
+
|
|
101
|
+
### 3. SBOM Files Now Return ALL Dependencies Regardless of Platform
|
|
102
|
+
|
|
103
|
+
**What Changed:**
|
|
104
|
+
- CycloneDX and SPDX parsers now return ALL dependencies from SBOM files
|
|
105
|
+
- Previously, only dependencies with PURL types mapped in `PURL_TYPE_MAPPING` were returned
|
|
106
|
+
- Now, unmapped PURL types (e.g., `alpine`, `apk`, `deb`, `rpm`) are included with the PURL type used as the platform name
|
|
107
|
+
|
|
108
|
+
**Before (14.x):**
|
|
109
|
+
```ruby
|
|
110
|
+
# An SBOM with npm, maven, and alpine packages would only return npm and maven
|
|
111
|
+
result = Bibliothecary.analyse('cyclonedx.json')
|
|
112
|
+
# => [{
|
|
113
|
+
# parser: "cyclonedx",
|
|
114
|
+
# dependencies: [
|
|
115
|
+
# { name: "express", platform: "npm", ... }, # included
|
|
116
|
+
# { name: "junit", platform: "maven", ... }, # included
|
|
117
|
+
# # alpine packages were silently filtered out
|
|
118
|
+
# ]
|
|
119
|
+
# }]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**After (15.0):**
|
|
123
|
+
```ruby
|
|
124
|
+
# The same SBOM now returns ALL packages
|
|
125
|
+
result = Bibliothecary.analyse('cyclonedx.json')
|
|
126
|
+
# => [{
|
|
127
|
+
# parser: "cyclonedx",
|
|
128
|
+
# dependencies: [
|
|
129
|
+
# { name: "express", platform: "npm", ... }, # included (mapped)
|
|
130
|
+
# { name: "junit", platform: "maven", ... }, # included (mapped)
|
|
131
|
+
# { name: "alpine-base", platform: "alpine", ... }, # included (unmapped, uses PURL type)
|
|
132
|
+
# { name: "curl", platform: "apk", ... } # included (unmapped, uses PURL type)
|
|
133
|
+
# ]
|
|
134
|
+
# }]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Mapped PURL Types (in PURL_TYPE_MAPPING):**
|
|
138
|
+
- `golang` → `go`
|
|
139
|
+
- `maven` → `maven`
|
|
140
|
+
- `npm` → `npm`
|
|
141
|
+
- `cargo` → `cargo`
|
|
142
|
+
- `composer` → `packagist`
|
|
143
|
+
- `conan` → `conan`
|
|
144
|
+
- `conda` → `conda`
|
|
145
|
+
- `cran` → `cran`
|
|
146
|
+
- `gem` → `rubygems`
|
|
147
|
+
- `nuget` → `nuget`
|
|
148
|
+
- `pypi` → `pypi`
|
|
149
|
+
- `vcpkg` → `vcpkg`
|
|
150
|
+
|
|
151
|
+
**Unmapped PURL Types (now included as-is):**
|
|
152
|
+
- `alpine`, `apk`, `deb`, `rpm`, `bitbucket`, `github`, `docker`, and any other PURL types
|
|
153
|
+
|
|
154
|
+
**Migration:**
|
|
155
|
+
- If your code filters or groups by platform, be aware that new platform values may appear
|
|
156
|
+
- System package types (`alpine`, `apk`, `deb`, `rpm`) will now be included in results
|
|
157
|
+
- Consider whether your application needs to handle these additional platform types
|
|
158
|
+
- The behavior is now more comprehensive and accurate to what's actually in SBOM files
|
|
159
|
+
|
|
160
|
+
### 4. API Method Renames
|
|
161
|
+
|
|
162
|
+
**What Changed:**
|
|
163
|
+
- Methods containing "package_manager" have been renamed to "parser"
|
|
164
|
+
- Old methods now raise errors with upgrade instructions
|
|
165
|
+
|
|
166
|
+
**Removed Methods:**
|
|
167
|
+
|
|
168
|
+
| Old Method (14.x) | New Method (15.0) |
|
|
169
|
+
|-------------------|-------------------|
|
|
170
|
+
| `Bibliothecary.package_managers` | `Bibliothecary.parsers` |
|
|
171
|
+
| `Bibliothecary.applicable_package_managers(info)` | `Bibliothecary.applicable_parsers(info)` |
|
|
172
|
+
| `Runner#package_managers` | `Runner#parsers` |
|
|
173
|
+
| `Runner#applicable_package_managers(info)` | `Runner#applicable_parsers(info)` |
|
|
174
|
+
| `FileInfo#package_manager` | `FileInfo#parser` |
|
|
175
|
+
| `RelatedFilesInfo#package_manager` | `RelatedFilesInfo#parser` |
|
|
176
|
+
|
|
177
|
+
**Before (14.x):**
|
|
178
|
+
```ruby
|
|
179
|
+
Bibliothecary.package_managers
|
|
180
|
+
# => [Bibliothecary::Parsers::NPM, Bibliothecary::Parsers::Rubygems, ...]
|
|
181
|
+
|
|
182
|
+
info = Bibliothecary::FileInfo.new(...)
|
|
183
|
+
parsers = Bibliothecary.applicable_package_managers(info)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**After (15.0):**
|
|
187
|
+
```ruby
|
|
188
|
+
Bibliothecary.parsers
|
|
189
|
+
# => [Bibliothecary::Parsers::NPM, Bibliothecary::MultiParsers::CycloneDX, ...]
|
|
190
|
+
|
|
191
|
+
info = Bibliothecary::FileInfo.new(...)
|
|
192
|
+
parsers = Bibliothecary.applicable_parsers(info)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Migration:**
|
|
196
|
+
- Search and replace `package_managers` with `parsers` in your codebase
|
|
197
|
+
- Search and replace `applicable_package_managers` with `applicable_parsers`
|
|
198
|
+
- Update any references to `FileInfo#package_manager` to use `FileInfo#parser`
|
|
199
|
+
|
|
200
|
+
### 4. MultiManifestFilter Removed
|
|
201
|
+
|
|
202
|
+
**What Changed:**
|
|
203
|
+
- The `Bibliothecary::Runner::MultiManifestFilter` class has been removed
|
|
204
|
+
- Multi-parsers are now standalone parser classes and don't require special filtering
|
|
205
|
+
|
|
206
|
+
**Before (14.x):**
|
|
207
|
+
```ruby
|
|
208
|
+
# MultiManifestFilter was used internally to handle SBOM files
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**After (15.0):**
|
|
212
|
+
```ruby
|
|
213
|
+
# Multi-parsers (CycloneDX, SPDX, DependenciesCSV) are regular parser classes
|
|
214
|
+
# They are included automatically in Bibliothecary.parsers
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Migration:**
|
|
218
|
+
- Remove any direct references to `Bibliothecary::Runner::MultiManifestFilter`
|
|
219
|
+
- The new behavior handles SBOM files transparently through the regular parser system
|
|
220
|
+
|
|
221
|
+
### 5. Parser Mixins Moved
|
|
222
|
+
|
|
223
|
+
**What Changed:**
|
|
224
|
+
- `Bibliothecary::MultiParsers::JSONRuntime` moved to `Bibliothecary::ParserMixins::JSONRuntime`
|
|
225
|
+
- `Bibliothecary::MultiParsers::BundlerLikeManifest` moved to `Bibliothecary::ParserMixins::BundlerLikeManifest`
|
|
226
|
+
|
|
227
|
+
**Migration:**
|
|
228
|
+
- Update any explicit references to these modules in your code
|
|
229
|
+
- Most users won't be affected as these are internal implementation details
|
|
230
|
+
|
|
231
|
+
### 6. MultiParsers Are Now Classes
|
|
232
|
+
|
|
233
|
+
**What Changed:**
|
|
234
|
+
- Multi-parsers (CycloneDX, SPDX, DependenciesCSV) are now classes instead of modules
|
|
235
|
+
- They are no longer mixed into platform-specific parsers
|
|
236
|
+
- They are standalone parsers included in `Bibliothecary.parsers`
|
|
237
|
+
|
|
238
|
+
**Before (14.x):**
|
|
239
|
+
```ruby
|
|
240
|
+
# Multi-parsers were modules that extended individual parsers
|
|
241
|
+
Bibliothecary::Parsers::NPM.ancestors
|
|
242
|
+
# => includes Bibliothecary::MultiParsers::CycloneDX
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**After (15.0):**
|
|
246
|
+
```ruby
|
|
247
|
+
# Multi-parsers are independent parser classes
|
|
248
|
+
Bibliothecary.parsers
|
|
249
|
+
# => [
|
|
250
|
+
# Bibliothecary::Parsers::NPM,
|
|
251
|
+
# Bibliothecary::Parsers::Maven,
|
|
252
|
+
# ...,
|
|
253
|
+
# Bibliothecary::MultiParsers::CycloneDX,
|
|
254
|
+
# Bibliothecary::MultiParsers::Spdx,
|
|
255
|
+
# Bibliothecary::MultiParsers::DependenciesCSV
|
|
256
|
+
# ]
|
|
257
|
+
|
|
258
|
+
# They have their own platform_name
|
|
259
|
+
Bibliothecary::MultiParsers::CycloneDX.platform_name # => "cyclonedx"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Migration:**
|
|
263
|
+
- Don't rely on multi-parser methods being available on platform-specific parsers
|
|
264
|
+
- Treat SBOM parsers as independent parsers in your code
|
|
@@ -43,9 +43,9 @@ module Bibliothecary
|
|
|
43
43
|
parser_result = parse_file(info.relative_path, info.contents, options: options)
|
|
44
44
|
parser_result = ParserResult.new(dependencies: []) if parser_result.nil? # work around any legacy parsers that return nil
|
|
45
45
|
|
|
46
|
-
Bibliothecary::Analyser.create_analysis(
|
|
46
|
+
Bibliothecary::Analyser.create_analysis(parser_name, info.relative_path, kind, parser_result)
|
|
47
47
|
rescue Bibliothecary::FileParsingError => e
|
|
48
|
-
Bibliothecary::Analyser.create_error_analysis(
|
|
48
|
+
Bibliothecary::Analyser.create_error_analysis(parser_name, info.relative_path, kind, e.message, e.location)
|
|
49
49
|
end
|
|
50
50
|
alias analyze_contents_from_info analyse_contents_from_info
|
|
51
51
|
|
|
@@ -6,9 +6,9 @@ require_relative "analyser/analysis"
|
|
|
6
6
|
|
|
7
7
|
module Bibliothecary
|
|
8
8
|
module Analyser
|
|
9
|
-
def self.create_error_analysis(
|
|
9
|
+
def self.create_error_analysis(parser_name, relative_path, kind, message, location = nil)
|
|
10
10
|
{
|
|
11
|
-
|
|
11
|
+
parser: parser_name,
|
|
12
12
|
path: relative_path,
|
|
13
13
|
dependencies: nil,
|
|
14
14
|
kind: kind,
|
|
@@ -18,9 +18,9 @@ module Bibliothecary
|
|
|
18
18
|
}
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def self.create_analysis(
|
|
21
|
+
def self.create_analysis(parser_name, relative_path, kind, parser_result)
|
|
22
22
|
{
|
|
23
|
-
|
|
23
|
+
parser: parser_name,
|
|
24
24
|
path: relative_path,
|
|
25
25
|
project_name: parser_result.project_name,
|
|
26
26
|
dependencies: parser_result.dependencies,
|
|
@@ -52,13 +52,17 @@ module Bibliothecary
|
|
|
52
52
|
|
|
53
53
|
module ClassMethods
|
|
54
54
|
def platform_name
|
|
55
|
-
|
|
55
|
+
parser_name
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def parser_name
|
|
59
|
+
@parser_name ||= name.to_s.split("::").last.downcase.freeze
|
|
56
60
|
end
|
|
57
61
|
|
|
58
62
|
def map_dependencies(hash, key, type, source = nil)
|
|
59
63
|
hash.fetch(key, []).map do |name, requirement|
|
|
60
64
|
Dependency.new(
|
|
61
|
-
platform:
|
|
65
|
+
platform: parser_name,
|
|
62
66
|
name: name,
|
|
63
67
|
requirement: requirement,
|
|
64
68
|
type: type,
|
|
@@ -67,23 +71,23 @@ module Bibliothecary
|
|
|
67
71
|
end
|
|
68
72
|
end
|
|
69
73
|
|
|
70
|
-
# Add a MultiParser module to a Parser class. This extends the
|
|
71
|
-
# self.mapping method on the parser to include the multi parser's
|
|
72
|
-
# files to watch for, and it extends the Parser class with
|
|
73
|
-
# the multi parser for you.
|
|
74
|
-
#
|
|
75
|
-
# @param klass [Class] A Bibliothecary::MultiParsers class
|
|
76
|
-
def add_multi_parser(klass)
|
|
77
|
-
|
|
74
|
+
# # Add a MultiParser module to a Parser class. This extends the
|
|
75
|
+
# # self.mapping method on the parser to include the multi parser's
|
|
76
|
+
# # files to watch for, and it extends the Parser class with
|
|
77
|
+
# # the multi parser for you.
|
|
78
|
+
# #
|
|
79
|
+
# # @param klass [Class] A Bibliothecary::MultiParsers class
|
|
80
|
+
# def add_multi_parser(klass)
|
|
81
|
+
# raise "No mapping found! You should place the add_multi_parser call below def self.mapping." unless respond_to?(:mapping)
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
# original_mapping = mapping
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
# define_singleton_method(:mapping) do
|
|
86
|
+
# original_mapping.merge(klass.mapping)
|
|
87
|
+
# end
|
|
84
88
|
|
|
85
|
-
|
|
86
|
-
end
|
|
89
|
+
# send(:extend, klass)
|
|
90
|
+
# end
|
|
87
91
|
end
|
|
88
92
|
end
|
|
89
93
|
end
|
|
@@ -5,10 +5,7 @@ module Bibliothecary
|
|
|
5
5
|
#
|
|
6
6
|
# @attr_reader [String] name The name of the package, e.g. "ansi-string-colors"
|
|
7
7
|
# @attr_reader [String] requirement The version requirement of the release, e.g. "1.0.0" or "^1.0.0"
|
|
8
|
-
# @attr_reader [String] platform The platform of the package, e.g. "maven".
|
|
9
|
-
# it's implicit in most parser results, and the analyzer returns the platform name itself. One
|
|
10
|
-
# exception are multi-parsers like DependenciesCSV, because they may return deps from multiple platforms.
|
|
11
|
-
# Bibliothecary could start returning this field for *all* deps in future, and make it required. (default: nil)
|
|
8
|
+
# @attr_reader [String] platform The platform of the package, e.g. "maven".
|
|
12
9
|
# @attr_reader [String] type The type or scope of dependency, e.g. "runtime" or "test". In some ecosystems a
|
|
13
10
|
# default may be set and in other ecosystems it may make sense to return nil when not found.
|
|
14
11
|
# @attr_reader [Boolean] direct Is this dependency a direct dependency (vs transitive dependency)? (default: nil)
|
|
@@ -7,7 +7,11 @@ module Bibliothecary
|
|
|
7
7
|
# and package manager information if needed.
|
|
8
8
|
class FileInfo
|
|
9
9
|
attr_reader :folder_path, :relative_path, :full_path
|
|
10
|
-
attr_accessor :
|
|
10
|
+
attr_accessor :parser
|
|
11
|
+
|
|
12
|
+
def package_manager
|
|
13
|
+
raise "FileInfo#package_manager() has been removed in bibliothecary 15.0.0. Use parser() instead, which now includes MultiParsers."
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def contents
|
|
13
17
|
@contents ||=
|
|
@@ -45,11 +49,11 @@ module Bibliothecary
|
|
|
45
49
|
|
|
46
50
|
@contents = contents
|
|
47
51
|
|
|
48
|
-
@
|
|
52
|
+
@parser = nil
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
def groupable?
|
|
52
|
-
@
|
|
56
|
+
@parser&.groupable?(self)
|
|
53
57
|
end
|
|
54
58
|
end
|
|
55
59
|
end
|
|
@@ -12,17 +12,17 @@ Warning[:experimental] = true
|
|
|
12
12
|
|
|
13
13
|
module Bibliothecary
|
|
14
14
|
module MultiParsers
|
|
15
|
-
|
|
15
|
+
class CycloneDX
|
|
16
16
|
include Bibliothecary::Analyser
|
|
17
|
-
|
|
17
|
+
extend Bibliothecary::Analyser::TryCache
|
|
18
18
|
|
|
19
19
|
NoComponents = Class.new(StandardError)
|
|
20
20
|
|
|
21
21
|
class ManifestEntries
|
|
22
|
-
attr_reader :
|
|
22
|
+
attr_reader :entries
|
|
23
23
|
|
|
24
24
|
def initialize(parse_queue:)
|
|
25
|
-
@
|
|
25
|
+
@entries = Set.new
|
|
26
26
|
|
|
27
27
|
# Instead of recursing, we'll work through a queue of components
|
|
28
28
|
# to process, letting the different parser add components to the
|
|
@@ -31,14 +31,13 @@ module Bibliothecary
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def add(purl, source = nil)
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
# Use the mapped purl->bibliothecary platform, or else fall back to original platform itself.
|
|
35
|
+
mapping = PurlUtil::PURL_TYPE_MAPPING.fetch(purl.type, purl.type)
|
|
36
36
|
|
|
37
|
-
@
|
|
38
|
-
@manifests[mapping] << Dependency.new(
|
|
37
|
+
@entries << Dependency.new(
|
|
39
38
|
name: PurlUtil.full_name(purl),
|
|
40
39
|
requirement: purl.version,
|
|
41
|
-
platform: mapping.to_s,
|
|
40
|
+
platform: mapping ? mapping.to_s : purl.type,
|
|
42
41
|
type: "lockfile",
|
|
43
42
|
source: source
|
|
44
43
|
)
|
|
@@ -60,10 +59,6 @@ module Bibliothecary
|
|
|
60
59
|
add(purl, source)
|
|
61
60
|
end
|
|
62
61
|
end
|
|
63
|
-
|
|
64
|
-
def [](key)
|
|
65
|
-
@manifests[key]&.to_a
|
|
66
|
-
end
|
|
67
62
|
end
|
|
68
63
|
|
|
69
64
|
def self.mapping
|
|
@@ -91,25 +86,31 @@ module Bibliothecary
|
|
|
91
86
|
}
|
|
92
87
|
end
|
|
93
88
|
|
|
94
|
-
def
|
|
89
|
+
def self.platform_name
|
|
90
|
+
raise "CycloneDX is a multi-parser and does not have a platform name."
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def self.parse_cyclonedx_json(file_contents, options: {})
|
|
95
94
|
manifest = try_cache(options, options[:filename]) do
|
|
96
95
|
JSON.parse(file_contents)
|
|
97
96
|
end
|
|
98
97
|
|
|
99
98
|
raise NoComponents unless manifest["components"]
|
|
100
99
|
|
|
101
|
-
|
|
100
|
+
manifest_entries = ManifestEntries.new(
|
|
101
|
+
parse_queue: manifest["components"]
|
|
102
|
+
)
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
manifest_entries.parse!(options.fetch(:filename, nil)) do |component, parse_queue|
|
|
104
105
|
parse_queue.concat(component["components"]) if component["components"]
|
|
105
106
|
|
|
106
107
|
component["purl"]
|
|
107
108
|
end
|
|
108
109
|
|
|
109
|
-
ParserResult.new(dependencies: entries
|
|
110
|
+
ParserResult.new(dependencies: manifest_entries.entries.to_a)
|
|
110
111
|
end
|
|
111
112
|
|
|
112
|
-
def parse_cyclonedx_xml(file_contents, options: {})
|
|
113
|
+
def self.parse_cyclonedx_xml(file_contents, options: {})
|
|
113
114
|
manifest = try_cache(options, options[:filename]) do
|
|
114
115
|
Ox.parse(file_contents)
|
|
115
116
|
end
|
|
@@ -121,9 +122,11 @@ module Bibliothecary
|
|
|
121
122
|
|
|
122
123
|
raise NoComponents unless root.locate("components").first
|
|
123
124
|
|
|
124
|
-
|
|
125
|
+
manifest_entries = ManifestEntries.new(
|
|
126
|
+
parse_queue: root.locate("components/*")
|
|
127
|
+
)
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
manifest_entries.parse!(options.fetch(:filename, nil)) do |component, parse_queue|
|
|
127
130
|
# #locate returns an empty array if nothing is found, so we can
|
|
128
131
|
# always safely concatenate it to the parse queue.
|
|
129
132
|
parse_queue.concat(component.locate("components/*"))
|
|
@@ -131,7 +134,7 @@ module Bibliothecary
|
|
|
131
134
|
component.locate("purl").first&.text
|
|
132
135
|
end
|
|
133
136
|
|
|
134
|
-
ParserResult.new(dependencies: entries
|
|
137
|
+
ParserResult.new(dependencies: manifest_entries.entries.to_a)
|
|
135
138
|
end
|
|
136
139
|
end
|
|
137
140
|
end
|
|
@@ -4,9 +4,9 @@ require "csv"
|
|
|
4
4
|
|
|
5
5
|
module Bibliothecary
|
|
6
6
|
module MultiParsers
|
|
7
|
-
|
|
7
|
+
class DependenciesCSV
|
|
8
8
|
include Bibliothecary::Analyser
|
|
9
|
-
|
|
9
|
+
extend Bibliothecary::Analyser::TryCache
|
|
10
10
|
|
|
11
11
|
def self.mapping
|
|
12
12
|
{
|
|
@@ -18,6 +18,10 @@ module Bibliothecary
|
|
|
18
18
|
}
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
def self.platform_name
|
|
22
|
+
raise "DependenciesCSV is a multi-parser and does not have a platform name."
|
|
23
|
+
end
|
|
24
|
+
|
|
21
25
|
# Processing a CSV file isn't as exact as using a real manifest file,
|
|
22
26
|
# but you can get pretty close as long as the data you're importing
|
|
23
27
|
# is simple.
|
|
@@ -132,7 +136,7 @@ module Bibliothecary
|
|
|
132
136
|
end
|
|
133
137
|
end
|
|
134
138
|
|
|
135
|
-
def parse_dependencies_csv(file_contents, options: {})
|
|
139
|
+
def self.parse_dependencies_csv(file_contents, options: {})
|
|
136
140
|
csv_file = try_cache(options, options[:filename]) do
|
|
137
141
|
raw_csv_file = CSVFile.new(file_contents)
|
|
138
142
|
raw_csv_file.parse!
|
|
@@ -141,7 +145,6 @@ module Bibliothecary
|
|
|
141
145
|
|
|
142
146
|
dependencies = csv_file
|
|
143
147
|
.result
|
|
144
|
-
.find_all { |dependency| dependency[:platform] == platform_name.to_s }
|
|
145
148
|
.map do |dep_kvs|
|
|
146
149
|
Dependency.new(
|
|
147
150
|
**dep_kvs, source: options.fetch(:filename, nil)
|