bibliothecary 13.0.2 → 14.0.1
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 +22 -0
- data/lib/bibliothecary/analyser/analysis.rb +3 -24
- data/lib/bibliothecary/analyser.rb +5 -7
- data/lib/bibliothecary/dependency.rb +1 -1
- data/lib/bibliothecary/multi_parsers/bundler_like_manifest.rb +2 -1
- data/lib/bibliothecary/multi_parsers/cyclonedx.rb +3 -2
- data/lib/bibliothecary/multi_parsers/dependencies_csv.rb +3 -1
- data/lib/bibliothecary/multi_parsers/json_runtime.rb +4 -1
- data/lib/bibliothecary/multi_parsers/spdx.rb +3 -2
- data/lib/bibliothecary/parser_result.rb +37 -0
- data/lib/bibliothecary/parsers/bower.rb +3 -2
- data/lib/bibliothecary/parsers/cargo.rb +8 -4
- data/lib/bibliothecary/parsers/cocoapods.rb +10 -4
- data/lib/bibliothecary/parsers/conda.rb +8 -2
- data/lib/bibliothecary/parsers/cpan.rb +4 -2
- data/lib/bibliothecary/parsers/cran.rb +7 -5
- data/lib/bibliothecary/parsers/dub.rb +3 -1
- data/lib/bibliothecary/parsers/elm.rb +4 -2
- data/lib/bibliothecary/parsers/go.rb +32 -16
- data/lib/bibliothecary/parsers/julia.rb +3 -2
- data/lib/bibliothecary/parsers/maven.rb +61 -27
- data/lib/bibliothecary/parsers/npm.rb +46 -31
- data/lib/bibliothecary/parsers/nuget.rb +33 -20
- data/lib/bibliothecary/parsers/packagist.rb +9 -5
- data/lib/bibliothecary/parsers/pub.rb +7 -4
- data/lib/bibliothecary/parsers/pypi.rb +30 -16
- data/lib/bibliothecary/parsers/rubygems.rb +10 -5
- data/lib/bibliothecary/parsers/shard.rb +7 -4
- data/lib/bibliothecary/version.rb +1 -1
- data/lib/bibliothecary.rb +1 -0
- data/lib/sdl_parser.rb +3 -1
- metadata +3 -2
@@ -139,15 +139,17 @@ module Bibliothecary
|
|
139
139
|
|
140
140
|
def self.parse_ivy_manifest(file_contents, options: {})
|
141
141
|
manifest = Ox.parse file_contents
|
142
|
-
manifest.dependencies.locate("dependency").map do |dependency|
|
142
|
+
dependencies = manifest.dependencies.locate("dependency").map do |dependency|
|
143
143
|
attrs = dependency.attributes
|
144
144
|
Dependency.new(
|
145
145
|
name: "#{attrs[:org]}:#{attrs[:name]}",
|
146
146
|
requirement: attrs[:rev],
|
147
147
|
type: "runtime",
|
148
|
-
source: options.fetch(:filename, nil)
|
148
|
+
source: options.fetch(:filename, nil),
|
149
|
+
platform: platform_name
|
149
150
|
)
|
150
151
|
end
|
152
|
+
ParserResult.new(dependencies: dependencies)
|
151
153
|
end
|
152
154
|
|
153
155
|
def self.ivy_report?(file_contents)
|
@@ -172,7 +174,7 @@ module Bibliothecary
|
|
172
174
|
type = info.attributes[:conf]
|
173
175
|
type = "unknown" if type.nil?
|
174
176
|
modules = doc.locate("ivy-report/dependencies/module")
|
175
|
-
modules.map do |mod|
|
177
|
+
dependencies = modules.map do |mod|
|
176
178
|
attrs = mod.attributes
|
177
179
|
org = attrs[:organisation]
|
178
180
|
name = attrs[:name]
|
@@ -184,15 +186,17 @@ module Bibliothecary
|
|
184
186
|
name: "#{org}:#{name}",
|
185
187
|
requirement: version,
|
186
188
|
type: type,
|
187
|
-
source: options.fetch(:filename, nil)
|
189
|
+
source: options.fetch(:filename, nil),
|
190
|
+
platform: platform_name
|
188
191
|
)
|
189
192
|
end.compact
|
193
|
+
ParserResult.new(dependencies: dependencies)
|
190
194
|
end
|
191
195
|
|
192
196
|
def self.parse_gradle_resolved(file_contents, options: {})
|
193
197
|
current_type = nil
|
194
198
|
|
195
|
-
file_contents.split("\n").map do |line|
|
199
|
+
dependencies = file_contents.split("\n").map do |line|
|
196
200
|
current_type_match = GRADLE_TYPE_REGEXP.match(line)
|
197
201
|
current_type = current_type_match.captures[0] if current_type_match
|
198
202
|
|
@@ -232,7 +236,8 @@ module Bibliothecary
|
|
232
236
|
name: dep[-3..-2].join(":"),
|
233
237
|
requirement: dep[-1],
|
234
238
|
type: current_type,
|
235
|
-
source: options.fetch(:filename, nil)
|
239
|
+
source: options.fetch(:filename, nil),
|
240
|
+
platform: platform_name
|
236
241
|
)
|
237
242
|
elsif dep.count == 5
|
238
243
|
# get name from renamed package resolution "org:name -> renamed_org:name:version"
|
@@ -242,7 +247,8 @@ module Bibliothecary
|
|
242
247
|
name: dep[-3..-2].join(":"),
|
243
248
|
requirement: dep[-1],
|
244
249
|
type: current_type,
|
245
|
-
source: options.fetch(:filename, nil)
|
250
|
+
source: options.fetch(:filename, nil),
|
251
|
+
platform: platform_name
|
246
252
|
)
|
247
253
|
else
|
248
254
|
# get name from version conflict resolution ("org:name:version -> version") and no-resolution ("org:name:version")
|
@@ -250,21 +256,24 @@ module Bibliothecary
|
|
250
256
|
name: dep[0..1].join(":"),
|
251
257
|
requirement: dep[-1],
|
252
258
|
type: current_type,
|
253
|
-
source: options.fetch(:filename, nil)
|
259
|
+
source: options.fetch(:filename, nil),
|
260
|
+
platform: platform_name
|
254
261
|
)
|
255
262
|
end
|
256
263
|
end
|
257
264
|
.compact
|
258
265
|
.uniq { |item| [item.name, item.requirement, item.type, item.original_name, item.original_requirement] }
|
266
|
+
ParserResult.new(dependencies: dependencies)
|
259
267
|
end
|
260
268
|
|
261
269
|
def self.parse_maven_resolved(file_contents, options: {})
|
262
|
-
file_contents
|
270
|
+
dependencies = file_contents
|
263
271
|
.gsub(ANSI_MATCHER, "")
|
264
272
|
.split("\n")
|
265
273
|
.map { |line| parse_resolved_dep_line(line, options: options) }
|
266
274
|
.compact
|
267
275
|
.uniq
|
276
|
+
ParserResult.new(dependencies: dependencies)
|
268
277
|
end
|
269
278
|
|
270
279
|
# Return each item in the ascii art tree with a depth of that item,
|
@@ -318,19 +327,20 @@ module Bibliothecary
|
|
318
327
|
|
319
328
|
projects_to_exclude = {}
|
320
329
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
330
|
+
(root_name, root_version, _root_type) = parse_maven_tree_dependency(items[0][1])
|
331
|
+
|
332
|
+
# traditional behavior: we only exclude the root project, and only if we parsed multiple lines
|
333
|
+
if keep_subprojects && !items.empty?
|
334
|
+
items.shift
|
335
|
+
projects_to_exclude[root_name] = Set.new
|
336
|
+
projects_to_exclude[root_name].add(root_version)
|
328
337
|
end
|
329
338
|
|
330
339
|
unique_items = items.map do |(depth, item)|
|
331
340
|
# new behavior: we exclude root and subprojects (depth 0 items)
|
332
341
|
(name, version, type) = parse_maven_tree_dependency(item)
|
333
342
|
if depth == 0 && !keep_subprojects
|
343
|
+
|
334
344
|
# record and then remove the depth 0
|
335
345
|
projects_to_exclude[name] ||= Set.new
|
336
346
|
projects_to_exclude[name].add(version)
|
@@ -340,7 +350,7 @@ module Bibliothecary
|
|
340
350
|
end
|
341
351
|
end.compact.uniq
|
342
352
|
|
343
|
-
unique_items
|
353
|
+
dependencies = unique_items
|
344
354
|
# drop the projects and subprojects
|
345
355
|
.reject { |(name, version, _type)| projects_to_exclude[name]&.include?(version) }
|
346
356
|
.map do |(name, version, type)|
|
@@ -348,14 +358,20 @@ module Bibliothecary
|
|
348
358
|
name: name,
|
349
359
|
requirement: version,
|
350
360
|
type: type,
|
351
|
-
source: options.fetch(:filename, nil)
|
361
|
+
source: options.fetch(:filename, nil),
|
362
|
+
platform: platform_name
|
352
363
|
)
|
353
364
|
end
|
365
|
+
ParserResult.new(
|
366
|
+
project_name: root_name,
|
367
|
+
dependencies: dependencies
|
368
|
+
)
|
354
369
|
end
|
355
370
|
|
356
371
|
def self.parse_maven_tree_dot(file_contents, options: {})
|
357
372
|
# Project could be either the root project or a sub-module.
|
358
373
|
project = file_contents.match(MAVEN_DOT_PROJECT_REGEXP)[1]
|
374
|
+
project_name, _project_version, _project_type = parse_maven_tree_dependency(project)
|
359
375
|
relationships = file_contents.scan(MAVEN_DOT_RELATIONSHIP_REGEXP)
|
360
376
|
|
361
377
|
direct_names_to_versions = relationships.each.with_object({}) do |(parent, child), obj|
|
@@ -366,17 +382,25 @@ module Bibliothecary
|
|
366
382
|
obj[name].add(version)
|
367
383
|
end
|
368
384
|
|
369
|
-
relationships.map do |(_parent, child)|
|
385
|
+
deps = relationships.map do |(_parent, child)|
|
370
386
|
child_name, child_version, child_type = parse_maven_tree_dependency(child)
|
371
387
|
|
372
388
|
Dependency.new(
|
373
389
|
name: child_name,
|
374
390
|
requirement: child_version,
|
391
|
+
platform: platform_name,
|
375
392
|
type: child_type,
|
376
393
|
direct: direct_names_to_versions[child_name]&.include?(child_version) || false,
|
377
394
|
source: options.fetch(:filename, nil)
|
378
395
|
)
|
379
396
|
end.uniq
|
397
|
+
|
398
|
+
# TODO: should we change every method to return this, or just allow both to be
|
399
|
+
# returned to an analysis? (I'm leaning towards former)
|
400
|
+
ParserResult.new(
|
401
|
+
dependencies: deps,
|
402
|
+
project_name: project_name
|
403
|
+
)
|
380
404
|
end
|
381
405
|
|
382
406
|
def self.parse_resolved_dep_line(line, options: {})
|
@@ -392,12 +416,14 @@ module Bibliothecary
|
|
392
416
|
name: dep_parts[0, 2].join(":"),
|
393
417
|
requirement: dep_parts[3],
|
394
418
|
type: dep_parts[4].split("--").first.strip,
|
395
|
-
source: options.fetch(:filename, nil)
|
419
|
+
source: options.fetch(:filename, nil),
|
420
|
+
platform: platform_name
|
396
421
|
)
|
397
422
|
end
|
398
423
|
|
399
424
|
def self.parse_standalone_pom_manifest(file_contents, options: {})
|
400
|
-
parse_pom_manifest(file_contents, {}, options:)
|
425
|
+
dependencies = parse_pom_manifest(file_contents, {}, options:)
|
426
|
+
ParserResult.new(dependencies: dependencies)
|
401
427
|
end
|
402
428
|
|
403
429
|
def self.parse_pom_manifest(file_contents, parent_properties = {}, options: {})
|
@@ -438,6 +464,7 @@ module Bibliothecary
|
|
438
464
|
unless dep_hashes.key?(key)
|
439
465
|
dep_hashes[key] = {
|
440
466
|
name: key,
|
467
|
+
platform: platform_name,
|
441
468
|
requirement: nil,
|
442
469
|
type: nil,
|
443
470
|
optional: nil,
|
@@ -472,7 +499,7 @@ module Bibliothecary
|
|
472
499
|
end
|
473
500
|
|
474
501
|
def self.parse_gradle(file_contents, options: {})
|
475
|
-
file_contents
|
502
|
+
dependencies = file_contents
|
476
503
|
.scan(GRADLE_GROOVY_SIMPLE_REGEXP) # match 'implementation "group:artifactId:version"'
|
477
504
|
.reject { |(_type, group, artifact_id, _version)| group.nil? || artifact_id.nil? } # remove any matches with missing group/artifactId
|
478
505
|
.map do |(type, group, artifact_id, version)|
|
@@ -480,13 +507,15 @@ module Bibliothecary
|
|
480
507
|
name: [group, artifact_id].join(":"),
|
481
508
|
requirement: version,
|
482
509
|
type: type,
|
483
|
-
source: options.fetch(:filename, nil)
|
510
|
+
source: options.fetch(:filename, nil),
|
511
|
+
platform: platform_name
|
484
512
|
)
|
485
513
|
end
|
514
|
+
ParserResult.new(dependencies: dependencies)
|
486
515
|
end
|
487
516
|
|
488
517
|
def self.parse_gradle_kts(file_contents, options: {})
|
489
|
-
file_contents
|
518
|
+
dependencies = file_contents
|
490
519
|
.scan(GRADLE_KOTLIN_SIMPLE_REGEXP) # match 'implementation("group:artifactId:version")'
|
491
520
|
.reject { |(_type, group, artifact_id, _version)| group.nil? || artifact_id.nil? } # remove any matches with missing group/artifactId
|
492
521
|
.map do |(type, group, artifact_id, version)|
|
@@ -494,9 +523,11 @@ module Bibliothecary
|
|
494
523
|
name: [group, artifact_id].join(":"),
|
495
524
|
requirement: version,
|
496
525
|
type: type,
|
497
|
-
source: options.fetch(:filename, nil)
|
526
|
+
source: options.fetch(:filename, nil),
|
527
|
+
platform: platform_name
|
498
528
|
)
|
499
529
|
end
|
530
|
+
ParserResult.new(dependencies: dependencies)
|
500
531
|
end
|
501
532
|
|
502
533
|
def self.gradle_dependency_name(group, name)
|
@@ -612,11 +643,14 @@ module Bibliothecary
|
|
612
643
|
dep.delete(:fields)
|
613
644
|
end
|
614
645
|
|
615
|
-
squished.map do |dep_kvs|
|
646
|
+
dependencies = squished.map do |dep_kvs|
|
616
647
|
Dependency.new(
|
617
|
-
**dep_kvs,
|
648
|
+
**dep_kvs,
|
649
|
+
source: options.fetch(:filename, nil),
|
650
|
+
platform: platform_name
|
618
651
|
)
|
619
652
|
end
|
653
|
+
ParserResult.new(dependencies: dependencies)
|
620
654
|
end
|
621
655
|
|
622
656
|
def self.parse_sbt_deps(type, lines)
|
@@ -50,14 +50,15 @@ module Bibliothecary
|
|
50
50
|
def self.parse_package_lock(file_contents, options: {})
|
51
51
|
manifest = JSON.parse(file_contents)
|
52
52
|
# https://docs.npmjs.com/cli/v9/configuring-npm/package-lock-json#lockfileversion
|
53
|
-
if manifest["lockfileVersion"].to_i <= 1
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
53
|
+
dependencies = if manifest["lockfileVersion"].to_i <= 1
|
54
|
+
# lockfileVersion 1 uses the "dependencies" object
|
55
|
+
parse_package_lock_v1(manifest, options.fetch(:filename, nil))
|
56
|
+
else
|
57
|
+
# lockfileVersion 2 has backwards-compatability by including both "packages" and the legacy "dependencies" object
|
58
|
+
# lockfileVersion 3 has no backwards-compatibility and only includes the "packages" object
|
59
|
+
parse_package_lock_v2(manifest, options.fetch(:filename, nil))
|
60
|
+
end
|
61
|
+
ParserResult.new(dependencies: dependencies)
|
61
62
|
end
|
62
63
|
|
63
64
|
class << self
|
@@ -98,7 +99,8 @@ module Bibliothecary
|
|
98
99
|
original_requirement: original_name.nil? ? nil : dep["version"],
|
99
100
|
type: dep.fetch("dev", false) || dep.fetch("devOptional", false) ? "development" : "runtime",
|
100
101
|
local: dep.fetch("link", false),
|
101
|
-
source: source
|
102
|
+
source: source,
|
103
|
+
platform: platform_name
|
102
104
|
)
|
103
105
|
end
|
104
106
|
end
|
@@ -118,14 +120,15 @@ module Bibliothecary
|
|
118
120
|
name: name,
|
119
121
|
requirement: version,
|
120
122
|
type: type,
|
121
|
-
source: source
|
123
|
+
source: source,
|
124
|
+
platform: platform_name
|
122
125
|
)] + child_dependencies
|
123
126
|
end
|
124
127
|
end
|
125
128
|
|
126
129
|
def self.parse_manifest(file_contents, options: {})
|
127
130
|
# on ruby 3.2 we suddenly get this JSON error, so detect and return early: "package.json: unexpected token at ''"
|
128
|
-
return [] if file_contents.empty?
|
131
|
+
return ParserResult.new(dependencies: []) if file_contents.empty?
|
129
132
|
|
130
133
|
manifest = JSON.parse(file_contents)
|
131
134
|
|
@@ -150,7 +153,8 @@ module Bibliothecary
|
|
150
153
|
original_requirement: original_name.nil? ? nil : requirement,
|
151
154
|
type: "runtime",
|
152
155
|
local: requirement.start_with?("file:"),
|
153
|
-
source: options.fetch(:filename, nil)
|
156
|
+
source: options.fetch(:filename, nil),
|
157
|
+
platform: platform_name
|
154
158
|
)
|
155
159
|
end
|
156
160
|
|
@@ -162,11 +166,12 @@ module Bibliothecary
|
|
162
166
|
requirement: requirement,
|
163
167
|
type: "development",
|
164
168
|
local: requirement.start_with?("file:"),
|
165
|
-
source: options.fetch(:filename, nil)
|
169
|
+
source: options.fetch(:filename, nil),
|
170
|
+
platform: platform_name
|
166
171
|
)
|
167
172
|
end
|
168
173
|
|
169
|
-
dependencies
|
174
|
+
ParserResult.new(dependencies: dependencies)
|
170
175
|
end
|
171
176
|
|
172
177
|
def self.parse_yarn_lock(file_contents, options: {})
|
@@ -176,7 +181,7 @@ module Bibliothecary
|
|
176
181
|
parse_v1_yarn_lock(file_contents, options.fetch(:filename, nil))
|
177
182
|
end
|
178
183
|
|
179
|
-
dep_hash.map do |dep|
|
184
|
+
dependencies = dep_hash.map do |dep|
|
180
185
|
Dependency.new(
|
181
186
|
name: dep[:name],
|
182
187
|
original_name: dep[:original_name],
|
@@ -184,9 +189,11 @@ module Bibliothecary
|
|
184
189
|
original_requirement: dep[:original_requirement],
|
185
190
|
type: "runtime", # lockfile doesn't tell us more about the type of dep
|
186
191
|
local: dep[:requirements]&.first&.start_with?("file:"),
|
187
|
-
source: options.fetch(:filename, nil)
|
192
|
+
source: options.fetch(:filename, nil),
|
193
|
+
platform: platform_name
|
188
194
|
)
|
189
195
|
end
|
196
|
+
ParserResult.new(dependencies: dependencies)
|
190
197
|
end
|
191
198
|
|
192
199
|
# Returns a hash representation of the deps in yarn.lock, eg:
|
@@ -285,7 +292,8 @@ module Bibliothecary
|
|
285
292
|
original_name: original_name,
|
286
293
|
original_requirement: original_requirement,
|
287
294
|
type: is_dev ? "development" : "runtime",
|
288
|
-
source: source
|
295
|
+
source: source,
|
296
|
+
platform: platform_name
|
289
297
|
)
|
290
298
|
end
|
291
299
|
end
|
@@ -321,7 +329,8 @@ module Bibliothecary
|
|
321
329
|
original_name: original_name,
|
322
330
|
original_requirement: original_requirement,
|
323
331
|
type: is_dev ? "development" : "runtime",
|
324
|
-
source: source
|
332
|
+
source: source,
|
333
|
+
platform: platform_name
|
325
334
|
)
|
326
335
|
end
|
327
336
|
end
|
@@ -369,7 +378,8 @@ module Bibliothecary
|
|
369
378
|
original_name: original_name,
|
370
379
|
original_requirement: original_requirement,
|
371
380
|
type: is_dev ? "development" : "runtime",
|
372
|
-
source: source
|
381
|
+
source: source,
|
382
|
+
platform: platform_name
|
373
383
|
)
|
374
384
|
end
|
375
385
|
end
|
@@ -382,20 +392,22 @@ module Bibliothecary
|
|
382
392
|
parsed = YAML.load(contents)
|
383
393
|
lockfile_version = parsed["lockfileVersion"].to_i
|
384
394
|
|
385
|
-
case lockfile_version
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
395
|
+
dependencies = case lockfile_version
|
396
|
+
when 5
|
397
|
+
parse_v5_pnpm_lock(parsed, options.fetch(:filename, nil))
|
398
|
+
when 6
|
399
|
+
parse_v6_pnpm_lock(parsed, options.fetch(:filename, nil))
|
400
|
+
else # v9+
|
401
|
+
parse_v9_pnpm_lock(parsed, options.fetch(:filename, nil))
|
402
|
+
end
|
403
|
+
ParserResult.new(dependencies: dependencies)
|
393
404
|
end
|
394
405
|
|
395
406
|
def self.parse_ls(file_contents, options: {})
|
396
407
|
manifest = JSON.parse(file_contents)
|
397
408
|
|
398
|
-
transform_tree_to_array(manifest.fetch("dependencies", {}), options.fetch(:filename, nil))
|
409
|
+
dependencies = transform_tree_to_array(manifest.fetch("dependencies", {}), options.fetch(:filename, nil))
|
410
|
+
ParserResult.new(dependencies: dependencies)
|
399
411
|
end
|
400
412
|
|
401
413
|
def self.parse_bun_lock(file_contents, options: {})
|
@@ -408,7 +420,7 @@ module Bibliothecary
|
|
408
420
|
|
409
421
|
dev_deps = manifest.dig("workspaces", "", "devDependencies")&.keys&.to_set
|
410
422
|
|
411
|
-
manifest.fetch("packages", []).map do |name, info|
|
423
|
+
dependencies = manifest.fetch("packages", []).map do |name, info|
|
412
424
|
info_name, _, version = info.first.rpartition("@")
|
413
425
|
is_local = version&.start_with?("file:")
|
414
426
|
is_alias = info_name != name
|
@@ -420,9 +432,11 @@ module Bibliothecary
|
|
420
432
|
original_requirement: is_alias ? version : nil,
|
421
433
|
type: dev_deps&.include?(name) ? "development" : "runtime",
|
422
434
|
local: is_local,
|
423
|
-
source: source
|
435
|
+
source: source,
|
436
|
+
platform: platform_name
|
424
437
|
)
|
425
438
|
end
|
439
|
+
ParserResult.new(dependencies: dependencies)
|
426
440
|
end
|
427
441
|
|
428
442
|
def self.lockfile_preference_order(file_infos)
|
@@ -444,7 +458,8 @@ module Bibliothecary
|
|
444
458
|
name: name,
|
445
459
|
requirement: metadata["version"],
|
446
460
|
type: "runtime",
|
447
|
-
source: source
|
461
|
+
source: source,
|
462
|
+
platform: platform_name
|
448
463
|
),
|
449
464
|
] + transform_tree_to_array(metadata.fetch("dependencies", {}), source)
|
450
465
|
end.flatten(1)
|
@@ -52,15 +52,17 @@ module Bibliothecary
|
|
52
52
|
|
53
53
|
def self.parse_project_lock_json(file_contents, options: {})
|
54
54
|
manifest = JSON.parse file_contents
|
55
|
-
manifest.fetch("libraries", []).map do |name, _requirement|
|
55
|
+
dependencies = manifest.fetch("libraries", []).map do |name, _requirement|
|
56
56
|
dep = name.split("/")
|
57
57
|
Dependency.new(
|
58
58
|
name: dep[0],
|
59
59
|
requirement: dep[1],
|
60
60
|
type: "runtime",
|
61
|
-
source: options.fetch(:filename, nil)
|
61
|
+
source: options.fetch(:filename, nil),
|
62
|
+
platform: platform_name
|
62
63
|
)
|
63
64
|
end
|
65
|
+
ParserResult.new(dependencies: dependencies)
|
64
66
|
end
|
65
67
|
|
66
68
|
def self.parse_packages_lock_json(file_contents, options: {})
|
@@ -77,7 +79,8 @@ module Bibliothecary
|
|
77
79
|
# so fallback to requested is pure paranoia
|
78
80
|
requirement: details.fetch("resolved", details.fetch("requested", "*")),
|
79
81
|
type: "runtime",
|
80
|
-
source: options.fetch(:filename, nil)
|
82
|
+
source: options.fetch(:filename, nil),
|
83
|
+
platform: platform_name
|
81
84
|
)
|
82
85
|
end
|
83
86
|
end
|
@@ -88,23 +91,25 @@ module Bibliothecary
|
|
88
91
|
|
89
92
|
# Note, frameworks can be empty, so remove empty ones and then return the last sorted item if any
|
90
93
|
frameworks.delete_if { |_k, v| v.empty? }
|
91
|
-
return frameworks[frameworks.keys.max] unless frameworks.empty?
|
94
|
+
return ParserResult.new(dependencies: frameworks[frameworks.keys.max]) unless frameworks.empty?
|
92
95
|
end
|
93
|
-
[]
|
96
|
+
ParserResult.new(dependencies: [])
|
94
97
|
end
|
95
98
|
|
96
99
|
def self.parse_packages_config(file_contents, options: {})
|
97
100
|
manifest = Ox.parse file_contents
|
98
|
-
manifest.packages.locate("package").map do |dependency|
|
101
|
+
dependencies = manifest.packages.locate("package").map do |dependency|
|
99
102
|
Dependency.new(
|
100
103
|
name: dependency.id,
|
101
104
|
requirement: (dependency.version if dependency.respond_to? "version"),
|
102
105
|
type: dependency.respond_to?("developmentDependency") && dependency.developmentDependency == "true" ? "development" : "runtime",
|
103
|
-
source: options.fetch(:filename, nil)
|
106
|
+
source: options.fetch(:filename, nil),
|
107
|
+
platform: platform_name
|
104
108
|
)
|
105
109
|
end
|
110
|
+
ParserResult.new(dependencies: dependencies)
|
106
111
|
rescue StandardError
|
107
|
-
[]
|
112
|
+
ParserResult.new(dependencies: [])
|
108
113
|
end
|
109
114
|
|
110
115
|
def self.parse_csproj(file_contents, options: {})
|
@@ -138,7 +143,8 @@ module Bibliothecary
|
|
138
143
|
name: dependency.Include,
|
139
144
|
requirement: requirement,
|
140
145
|
type: type,
|
141
|
-
source: options.fetch(:filename, nil)
|
146
|
+
source: options.fetch(:filename, nil),
|
147
|
+
platform: platform_name
|
142
148
|
)
|
143
149
|
end
|
144
150
|
|
@@ -154,27 +160,31 @@ module Bibliothecary
|
|
154
160
|
name: name,
|
155
161
|
requirement: vals["Version"] || "*",
|
156
162
|
type: "runtime",
|
157
|
-
source: options.fetch(:filename, nil)
|
163
|
+
source: options.fetch(:filename, nil),
|
164
|
+
platform: platform_name
|
158
165
|
)
|
159
166
|
end
|
160
167
|
|
161
|
-
packages.uniq(&:name)
|
168
|
+
dependencies = packages.uniq(&:name)
|
169
|
+
ParserResult.new(dependencies: dependencies)
|
162
170
|
rescue StandardError
|
163
|
-
[]
|
171
|
+
ParserResult.new(dependencies: [])
|
164
172
|
end
|
165
173
|
|
166
174
|
def self.parse_nuspec(file_contents, options: {})
|
167
175
|
manifest = Ox.parse file_contents
|
168
|
-
manifest.package.metadata.dependencies.locate("dependency").map do |dependency|
|
176
|
+
dependencies = manifest.package.metadata.dependencies.locate("dependency").map do |dependency|
|
169
177
|
Dependency.new(
|
170
178
|
name: dependency.id,
|
171
179
|
requirement: dependency.attributes[:version],
|
172
180
|
type: dependency.respond_to?("developmentDependency") && dependency.developmentDependency == "true" ? "development" : "runtime",
|
173
|
-
source: options.fetch(:filename, nil)
|
181
|
+
source: options.fetch(:filename, nil),
|
182
|
+
platform: platform_name
|
174
183
|
)
|
175
184
|
end
|
185
|
+
ParserResult.new(dependencies: dependencies)
|
176
186
|
rescue StandardError
|
177
|
-
[]
|
187
|
+
ParserResult.new(dependencies: [])
|
178
188
|
end
|
179
189
|
|
180
190
|
def self.parse_paket_lock(file_contents, options: {})
|
@@ -185,11 +195,13 @@ module Bibliothecary
|
|
185
195
|
name: match[:name].strip,
|
186
196
|
requirement: match[:version],
|
187
197
|
type: "runtime",
|
188
|
-
source: options.fetch(:filename, nil)
|
198
|
+
source: options.fetch(:filename, nil),
|
199
|
+
platform: platform_name
|
189
200
|
)
|
190
201
|
end
|
191
202
|
# we only have to enforce uniqueness by name because paket ensures that there is only the single version globally in the project
|
192
|
-
packages.uniq(&:name)
|
203
|
+
dependencies = packages.uniq(&:name)
|
204
|
+
ParserResult.new(dependencies: dependencies)
|
193
205
|
end
|
194
206
|
|
195
207
|
def self.parse_project_assets_json(file_contents, options: {})
|
@@ -205,7 +217,8 @@ module Bibliothecary
|
|
205
217
|
name: name_split[0],
|
206
218
|
requirement: name_split[1],
|
207
219
|
type: "runtime",
|
208
|
-
source: options.fetch(:filename, nil)
|
220
|
+
source: options.fetch(:filename, nil),
|
221
|
+
platform: platform_name
|
209
222
|
)
|
210
223
|
end
|
211
224
|
end
|
@@ -216,9 +229,9 @@ module Bibliothecary
|
|
216
229
|
|
217
230
|
# Note, frameworks can be empty, so remove empty ones and then return the last sorted item if any
|
218
231
|
frameworks.delete_if { |_k, v| v.empty? }
|
219
|
-
return frameworks[frameworks.keys.max] unless frameworks.empty?
|
232
|
+
return ParserResult.new(dependencies: frameworks[frameworks.keys.max]) unless frameworks.empty?
|
220
233
|
end
|
221
|
-
[]
|
234
|
+
ParserResult.new(dependencies: [])
|
222
235
|
end
|
223
236
|
end
|
224
237
|
end
|
@@ -26,7 +26,7 @@ module Bibliothecary
|
|
26
26
|
|
27
27
|
def self.parse_lockfile(file_contents, options: {})
|
28
28
|
manifest = JSON.parse file_contents
|
29
|
-
manifest.fetch("packages", []).map do |dependency|
|
29
|
+
dependencies = manifest.fetch("packages", []).map do |dependency|
|
30
30
|
requirement = dependency["version"]
|
31
31
|
|
32
32
|
# Store Drupal version if Drupal, but include the original manifest version for reference
|
@@ -40,7 +40,8 @@ module Bibliothecary
|
|
40
40
|
requirement: requirement,
|
41
41
|
type: "runtime",
|
42
42
|
original_requirement: original_requirement,
|
43
|
-
source: options.fetch(:filename, nil)
|
43
|
+
source: options.fetch(:filename, nil),
|
44
|
+
platform: platform_name
|
44
45
|
)
|
45
46
|
end + manifest.fetch("packages-dev", []).map do |dependency|
|
46
47
|
requirement = dependency["version"]
|
@@ -56,15 +57,18 @@ module Bibliothecary
|
|
56
57
|
requirement: requirement,
|
57
58
|
type: "development",
|
58
59
|
original_requirement: original_requirement,
|
59
|
-
source: options.fetch(:filename, nil)
|
60
|
+
source: options.fetch(:filename, nil),
|
61
|
+
platform: platform_name
|
60
62
|
)
|
61
63
|
end
|
64
|
+
ParserResult.new(dependencies: dependencies)
|
62
65
|
end
|
63
66
|
|
64
67
|
def self.parse_manifest(file_contents, options: {})
|
65
68
|
manifest = JSON.parse file_contents
|
66
|
-
map_dependencies(manifest, "require", "runtime", options.fetch(:filename, nil)) +
|
67
|
-
|
69
|
+
dependencies = map_dependencies(manifest, "require", "runtime", options.fetch(:filename, nil)) +
|
70
|
+
map_dependencies(manifest, "require-dev", "development", options.fetch(:filename, nil))
|
71
|
+
ParserResult.new(dependencies: dependencies)
|
68
72
|
end
|
69
73
|
|
70
74
|
# Drupal hosts its own Composer repository, where its "modules" are indexed and searchable. The best way to
|
@@ -24,20 +24,23 @@ module Bibliothecary
|
|
24
24
|
|
25
25
|
def self.parse_yaml_manifest(file_contents, options: {})
|
26
26
|
manifest = YAML.load file_contents
|
27
|
-
map_dependencies(manifest, "dependencies", "runtime", options.fetch(:filename, nil)) +
|
28
|
-
|
27
|
+
dependencies = map_dependencies(manifest, "dependencies", "runtime", options.fetch(:filename, nil)) +
|
28
|
+
map_dependencies(manifest, "dev_dependencies", "development", options.fetch(:filename, nil))
|
29
|
+
ParserResult.new(dependencies: dependencies)
|
29
30
|
end
|
30
31
|
|
31
32
|
def self.parse_yaml_lockfile(file_contents, options: {})
|
32
33
|
manifest = YAML.load file_contents
|
33
|
-
manifest.fetch("packages", []).map do |name, dep|
|
34
|
+
dependencies = manifest.fetch("packages", []).map do |name, dep|
|
34
35
|
Dependency.new(
|
35
36
|
name: name,
|
36
37
|
requirement: dep["version"],
|
37
38
|
type: "runtime",
|
38
|
-
source: options.fetch(:filename, nil)
|
39
|
+
source: options.fetch(:filename, nil),
|
40
|
+
platform: platform_name
|
39
41
|
)
|
40
42
|
end
|
43
|
+
ParserResult.new(dependencies: dependencies)
|
41
44
|
end
|
42
45
|
end
|
43
46
|
end
|