bibliothecary 12.1.4 → 12.1.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: bbe2270af80c93aaa2613434faa3c801337ec316a68bdd25d4b6d92d9979398a
4
- data.tar.gz: ee84bbf8cb2bd2beae91c080e480fe5fc3f0c2773a305743388cf3f225355eb2
3
+ metadata.gz: e8b70e5a827feb678f61dc5d2f3760be0b627ad948556ccb22dc74521df046c9
4
+ data.tar.gz: de4f2d64c252570088d1c223002d6942247c45a18f3382e88448338e097273e9
5
5
  SHA512:
6
- metadata.gz: 0ac214d1af05ecf0f156a81dc751421cbbe1d94c6306420d0aeb87c7dabf96eca819a0b199705d40d408b3a22b73227a523bb06e121c1e60c7dfbbb2f74dff10
7
- data.tar.gz: 52d620bcd946c7197f129ebd59f2ba68676e67152dbeac297a4cdd5d72f74e9f3dc32c6c11b11f513443040721ccaa18b2c322e7b77162fb775fa7827fe3edd6
6
+ metadata.gz: cda3bfcd8d209364d5d8c6fe5b062f308437863f6e09ec05e05f473c486a425c6e0d68eaed3a8a8716119db7cb1ce65ee0921c781f9bacb1e927dd5a17bc7d58
7
+ data.tar.gz: efacaa12ee9cb7e88b876b4ea8fabf48bfa72ff2da49c4ee637d98bf4ad0f80219d3ad106c5cdc49560557dca078304729592fc89b79a9082ae501446a1d4236
data/CHANGELOG.md CHANGED
@@ -13,6 +13,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
 
14
14
  ### Removed
15
15
 
16
+ ## [12.1.5] - 2025-03-17
17
+
18
+ ### Added
19
+
20
+ - Adds alias support for PNPM lockfiles.
21
+ - Add support for bun.lock files
22
+
23
+ ### Changed
24
+
25
+ ### Removed
26
+
16
27
  ## [12.1.4] - 2025-03-14
17
28
 
18
29
  ### Added
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_dependency "commander"
25
25
  spec.add_dependency "deb_control"
26
+ spec.add_dependency "json", "~> 2.8"
26
27
  spec.add_dependency "librariesio-gem-parser"
27
28
  spec.add_dependency "ox", ">= 2.8.1"
28
29
  spec.add_dependency "packageurl-ruby"
@@ -36,6 +36,10 @@ module Bibliothecary
36
36
  kind: "lockfile",
37
37
  parser: :parse_shrinkwrap,
38
38
  },
39
+ match_filename("bun.lock") => {
40
+ kind: "lockfile",
41
+ parser: :parse_bun_lock,
42
+ },
39
43
  }
40
44
  end
41
45
 
@@ -252,53 +256,106 @@ module Bibliothecary
252
256
  end
253
257
  end
254
258
 
255
- # This method currently has been tested to support:
256
- # lockfileVersion: '9.0'
257
- # lockfileVersion: '6.0'
258
- # lockfileVersion: '5.4'
259
- def self.parse_pnpm_lock(contents, _source = nil)
260
- parsed = YAML.load(contents)
261
- lockfile_version = parsed["lockfileVersion"].to_i
259
+ def self.parse_v5_pnpm_lock(parsed_contents, _source = nil)
260
+ dependency_mapping = parsed_contents.fetch("dependencies", {})
261
+ .merge(parsed_contents.fetch("devDependencies", {}))
262
+
263
+ parsed_contents["packages"]
264
+ .map do |name_version, details|
265
+ # e.g. "/debug/2.6.9:"
266
+ name, version = name_version.sub(/^\//, "").split("/", 2)
267
+
268
+ # e.g. "/debug/2.2.0_supports-color@1.2.0:"
269
+ version = version.split("_", 2)[0]
270
+
271
+ # e.g. "alias-package: /zod/3.24.2"
272
+ original_name = nil
273
+ original_requirement = nil
274
+ if (alias_dep = dependency_mapping.find { |_n, v| v.start_with?("/#{name}/") })
275
+ original_name = alias_dep[0]
276
+ original_requirement = alias_dep[1].split("/", 3)[2] # e.g. "/zod/3.24.2"
277
+ end
278
+
279
+ is_dev = details["dev"] == true
280
+
281
+ Dependency.new(
282
+ name: name,
283
+ requirement: version,
284
+ original_name: original_name,
285
+ original_requirement: original_requirement,
286
+ type: is_dev ? "development" : "runtime"
287
+ )
288
+ end
289
+ end
290
+
291
+ def self.parse_v6_pnpm_lock(parsed_contents, _source = nil)
292
+ dependency_mapping = parsed_contents.fetch("dependencies", {})
293
+ .merge(parsed_contents.fetch("devDependencies", {}))
294
+
295
+ parsed_contents["packages"]
296
+ .map do |name_version, details|
297
+ # e.g. "/debug@2.6.9:"
298
+ name, version = name_version.sub(/^\//, "").split("@", 2)
299
+
300
+ # e.g. "debug@2.2.0(supports-color@1.2.0)"
301
+ version = version.split("(", 2).first
302
+
303
+ # e.g.
304
+ # alias-package:
305
+ # specifier: npm:zod
306
+ # version: /zod@3.24.2
307
+ original_name = nil
308
+ original_requirement = nil
309
+ if (alias_dep = dependency_mapping.find { |_n, info| info["specifier"] == "npm:#{name}" })
310
+ original_name = alias_dep[0]
311
+ original_requirement = alias_dep[1]["version"].sub(/^\//, "").split("@", 2)[1]
312
+ end
313
+
314
+ is_dev = details["dev"] == true
315
+
316
+ Dependency.new(
317
+ name: name,
318
+ requirement: version,
319
+ original_name: original_name,
320
+ original_requirement: original_requirement,
321
+ type: is_dev ? "development" : "runtime"
322
+ )
323
+ end
324
+ end
262
325
 
263
- dev_dependencies = parsed.dig("importers", ".", "devDependencies") # <= v9
264
- dev_dependencies ||= parsed["devDependencies"] # <v9
326
+ def self.parse_v9_pnpm_lock(parsed_contents, _source = nil)
327
+ dependencies = parsed_contents.fetch("importers", {}).fetch(".", {}).fetch("dependencies")
328
+ dev_dependencies = parsed_contents.fetch("importers", {}).fetch(".", {}).fetch("devDependencies")
329
+ dependency_mapping = dependencies.merge(dev_dependencies)
265
330
 
266
331
  # "dependencies" is in "packages" for < v9 and in "snapshots" for >= v9
267
332
  # as of https://github.com/pnpm/pnpm/pull/7700.
268
- (parsed["snapshots"] || parsed["packages"])
269
- .map do |name_version, details|
270
- name, version = case lockfile_version
271
- when 5
272
- # e.g. '/debug/2.6.9:'
273
- n, v = name_version.sub(/^\//, "").split("/", 2)
274
- # e.g. '/debug/2.2.0_supports-color@1.2.0:'
275
- v = v.split("_", 2)[0]
276
- [n, v] # rubocop:disable Style/IdenticalConditionalBranches
277
- when 6
278
- # e.g. '/debug@2.6.9:'
279
- n, v = name_version.sub(/^\//, "").split("@", 2)
280
- # e.g. "debug@2.2.0(supports-color@1.2.0)"
281
- v = v.split("(", 2).first
282
- [n, v] # rubocop:disable Style/IdenticalConditionalBranches
283
- else
284
- # e.g. 'debug@2.6.9:'
285
- n, v = name_version.split("@", 2)
286
- # e.g. "debug@2.2.0(supports-color@1.2.0)"
287
- v = v.split("(", 2).first
288
- [n, v] # rubocop:disable Style/IdenticalConditionalBranches
289
- end
333
+ parsed_contents["snapshots"]
334
+ .map do |name_version, _details|
335
+ # e.g. "debug@2.6.9:"
336
+ name, version = name_version.split("@", 2)
337
+
338
+ # e.g. "debug@2.2.0(supports-color@1.2.0)"
339
+ version = version.split("(", 2).first
340
+
341
+ # e.g.
342
+ # alias-package:
343
+ # specifier: npm:zod
344
+ # version: zod@3.24.2
345
+ original_name = nil
346
+ original_requirement = nil
347
+ if (alias_dep = dependency_mapping.find { |_n, info| info["specifier"] == "npm:#{name}" })
348
+ original_name = alias_dep[0]
349
+ original_requirement = alias_dep[1]["version"].split("@", 2)[1]
350
+ end
290
351
 
291
352
  # TODO: the "dev" field was removed in v9 lockfiles (https://github.com/pnpm/pnpm/pull/7808)
292
- # so this will only exist in v6 and below and might be unreliable.
293
353
  # The proper way to set this for v9+ is to build a lookup of deps to
294
354
  # their "dependencies", and then recurse through each package's
295
355
  # parents. If the direct dep(s) that required them are all
296
356
  # "devDependencies" then we can consider them "dev == true". This
297
357
  # should be done using a DAG data structure, though, to be efficient
298
358
  # and avoid cycles.
299
- is_dev = details["dev"] == true
300
-
301
- # Fallback for v9+: this only detects dev deps that are direct.
302
359
  is_dev ||= dev_dependencies.any? do |dev_name, dev_details|
303
360
  dev_name == name && dev_details["version"] == version
304
361
  end
@@ -306,17 +363,60 @@ module Bibliothecary
306
363
  Dependency.new(
307
364
  name: name,
308
365
  requirement: version,
366
+ original_name: original_name,
367
+ original_requirement: original_requirement,
309
368
  type: is_dev ? "development" : "runtime"
310
369
  )
311
370
  end
312
371
  end
313
372
 
373
+ # This method currently has been tested to support:
374
+ # lockfileVersion: '9.0'
375
+ # lockfileVersion: '6.0'
376
+ # lockfileVersion: '5.4'
377
+ def self.parse_pnpm_lock(contents, _source = nil)
378
+ parsed = YAML.load(contents)
379
+ lockfile_version = parsed["lockfileVersion"].to_i
380
+
381
+ case lockfile_version
382
+ when 5
383
+ parse_v5_pnpm_lock(parsed)
384
+ when 6
385
+ parse_v6_pnpm_lock(parsed)
386
+ else # v9+
387
+ parse_v9_pnpm_lock(parsed)
388
+ end
389
+ end
390
+
314
391
  def self.parse_ls(file_contents, options: {})
315
392
  manifest = JSON.parse(file_contents)
316
393
 
317
394
  transform_tree_to_array(manifest.fetch("dependencies", {}), options.fetch(:filename, nil))
318
395
  end
319
396
 
397
+ def self.parse_bun_lock(file_contents, options: {})
398
+ manifest = JSON.parse(file_contents, allow_trailing_comma: true)
399
+ source = options.fetch(:filename, nil)
400
+
401
+ dev_deps = manifest.dig("workspaces", "", "devDependencies")&.keys&.to_set
402
+
403
+ manifest.fetch("packages", []).map do |name, info|
404
+ info_name, _, version = info.first.rpartition("@")
405
+ is_local = version&.start_with?("file:")
406
+ is_alias = info_name != name
407
+
408
+ Dependency.new(
409
+ name: info_name,
410
+ original_name: is_alias ? name : nil,
411
+ requirement: version,
412
+ original_requirement: is_alias ? version : nil,
413
+ type: dev_deps&.include?(name) ? "development" : "runtime",
414
+ local: is_local,
415
+ source: source
416
+ )
417
+ end
418
+ end
419
+
320
420
  def self.lockfile_preference_order(file_infos)
321
421
  files = file_infos.each_with_object({}) do |file_info, obj|
322
422
  obj[File.basename(file_info.full_path)] = file_info
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bibliothecary
4
- VERSION = "12.1.4"
4
+ VERSION = "12.1.5"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bibliothecary
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.1.4
4
+ version: 12.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-14 00:00:00.000000000 Z
10
+ date: 2025-03-18 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: commander
@@ -37,6 +37,20 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: json
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.8'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.8'
40
54
  - !ruby/object:Gem::Dependency
41
55
  name: librariesio-gem-parser
42
56
  requirement: !ruby/object:Gem::Requirement