ecosystems-bibliothecary 15.1.1 → 15.3.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +189 -124
  4. data/lib/bibliothecary/analyser.rb +4 -0
  5. data/lib/bibliothecary/dependency.rb +6 -1
  6. data/lib/bibliothecary/parsers/actions.rb +4 -0
  7. data/lib/bibliothecary/parsers/alpm.rb +89 -0
  8. data/lib/bibliothecary/parsers/apk.rb +91 -0
  9. data/lib/bibliothecary/parsers/bentoml.rb +5 -1
  10. data/lib/bibliothecary/parsers/bower.rb +5 -0
  11. data/lib/bibliothecary/parsers/cargo.rb +7 -1
  12. data/lib/bibliothecary/parsers/carthage.rb +4 -0
  13. data/lib/bibliothecary/parsers/clojars.rb +5 -0
  14. data/lib/bibliothecary/parsers/cocoapods.rb +33 -1
  15. data/lib/bibliothecary/parsers/cog.rb +5 -1
  16. data/lib/bibliothecary/parsers/conan.rb +4 -0
  17. data/lib/bibliothecary/parsers/conda.rb +6 -0
  18. data/lib/bibliothecary/parsers/cpan.rb +4 -0
  19. data/lib/bibliothecary/parsers/cran.rb +4 -0
  20. data/lib/bibliothecary/parsers/deb.rb +132 -0
  21. data/lib/bibliothecary/parsers/deno.rb +112 -0
  22. data/lib/bibliothecary/parsers/docker.rb +4 -0
  23. data/lib/bibliothecary/parsers/dub.rb +6 -0
  24. data/lib/bibliothecary/parsers/dvc.rb +5 -1
  25. data/lib/bibliothecary/parsers/elm.rb +4 -0
  26. data/lib/bibliothecary/parsers/go.rb +8 -2
  27. data/lib/bibliothecary/parsers/hackage.rb +58 -2
  28. data/lib/bibliothecary/parsers/haxelib.rb +5 -0
  29. data/lib/bibliothecary/parsers/hex.rb +109 -5
  30. data/lib/bibliothecary/parsers/homebrew.rb +4 -0
  31. data/lib/bibliothecary/parsers/julia.rb +55 -0
  32. data/lib/bibliothecary/parsers/luarocks.rb +5 -0
  33. data/lib/bibliothecary/parsers/maven.rb +4 -0
  34. data/lib/bibliothecary/parsers/meteor.rb +5 -0
  35. data/lib/bibliothecary/parsers/mlflow.rb +5 -1
  36. data/lib/bibliothecary/parsers/nimble.rb +5 -0
  37. data/lib/bibliothecary/parsers/nix.rb +205 -0
  38. data/lib/bibliothecary/parsers/npm.rb +84 -11
  39. data/lib/bibliothecary/parsers/nuget.rb +4 -0
  40. data/lib/bibliothecary/parsers/ollama.rb +5 -1
  41. data/lib/bibliothecary/parsers/packagist.rb +32 -31
  42. data/lib/bibliothecary/parsers/pub.rb +4 -0
  43. data/lib/bibliothecary/parsers/pypi.rb +25 -2
  44. data/lib/bibliothecary/parsers/rpm.rb +80 -0
  45. data/lib/bibliothecary/parsers/rubygems.rb +38 -4
  46. data/lib/bibliothecary/parsers/shard.rb +4 -0
  47. data/lib/bibliothecary/parsers/swift_pm.rb +4 -0
  48. data/lib/bibliothecary/parsers/vcpkg.rb +4 -0
  49. data/lib/bibliothecary/version.rb +1 -1
  50. data/lib/bibliothecary.rb +7 -0
  51. metadata +7 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49988f4a70c1d5dcf6b7c05bffba8d885b3e63f04545f0c524d32b46de0804f2
4
- data.tar.gz: 121b4e75f934770b9967b0e3b2427ddc1dc6aaaa19f8ed0d72f1001e50d4d575
3
+ metadata.gz: c213dba45d6c84c67ecad66538e68fbd7ff843ec5fb6f6b1d80b757ae9ab5f15
4
+ data.tar.gz: a0b4a803b35d16820ed19b071ae8984efb9004ba712ca6457e6f9d9412d331e6
5
5
  SHA512:
6
- metadata.gz: 227adbf47ce52d6a9bb70be154f0cc204f5f327b68adeb8c91fd2e668036359eebd07d3fb940f0d4eef00128af04fb2073304147b9285589917efef1b1d5d5cf
7
- data.tar.gz: ca3b36ddfa71702dae9737500dcf09ad6a9e6c4daf5758738c793614bcdcbd730a50083d081ee45a899536b0f01c1bd7d4eef90117cc3c1aeee6063a780e0b3f
6
+ metadata.gz: ade8a88ba728b3d95e333000cdcde1ad8ed9ae885ab775678a1b45c3d3521705f553c293be26ce5d63002f5ec86666e29108b7b456b672c647a58d56af8dc568
7
+ data.tar.gz: e5fdf2c94bde72360926307a0df9cc6d796d476aa983a5236fa5d13691c4bcf74a5e20bd3c0090725ddd37bfad8a4d0733cc6a2d99b6cf25a64a92ac6a7d507b
data/CHANGELOG.md CHANGED
@@ -13,6 +13,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
 
14
14
  ### Removed
15
15
 
16
+ ## [15.3.0]
17
+
18
+ ### Added
19
+
20
+ - npm: pnpm-workspace.yaml support for catalog dependencies (pnpm 9+)
21
+ - alpm: Arch Linux PKGBUILD parser for depends, makedepends, and checkdepends
22
+ - apk: Alpine Linux APKBUILD parser for depends, makedepends, and checkdepends
23
+ - deb: Debian control file parser for Build-Depends, Depends, Pre-Depends, Recommends, Suggests
24
+ - rpm: RPM spec file parser for BuildRequires and Requires
25
+ - integrity: Added `integrity` field to Dependency class for lockfile hashes (npm package-lock.json, pnpm-lock.yaml, yarn.lock v4, bun.lock, go.sum, Gemfile.lock, deno.lock, composer.lock, stack.yaml.lock, Cargo.lock, Podfile.lock, mix.lock, rebar.lock, manifest.toml, poetry.lock, uv.lock)
26
+
27
+ ## [15.2.0]
28
+
29
+ ### Added
30
+
31
+ - Deno parser for deno.json, deno.jsonc, and deno.lock files (supports npm: and jsr: specifiers)
32
+ - Nix parser for flake.nix, flake.lock, nix/sources.json (niv), and npins/sources.json (npins)
33
+ - Gleam support in Hex parser for gleam.toml and manifest.toml
34
+ - Rebar3 support in Hex parser for rebar.lock
35
+ - Julia Project.toml and Manifest.toml support
36
+ - Hackage cabal.project.freeze support
37
+
16
38
  ## [15.1.1]
17
39
 
18
40
  ### Added
data/README.md CHANGED
@@ -42,166 +42,231 @@ Bibliothecary.analyse('./')
42
42
 
43
43
  All available config options are in: https://github.com/ecosyste-ms/bibliothecary/blob/master/lib/bibliothecary/configuration.rb
44
44
 
45
+ ## Dependency fields
46
+
47
+ Each parsed dependency is a `Bibliothecary::Dependency` with:
48
+
49
+ | Field | Type | Description |
50
+ |-------|------|-------------|
51
+ | `name` | String | Package name |
52
+ | `requirement` | String | Version requirement (defaults to `"*"`) |
53
+ | `platform` | String | Package manager platform (e.g. `"npm"`, `"maven"`) |
54
+ | `type` | String | Dependency scope: `"runtime"`, `"development"`, `"test"`, etc. |
55
+ | `direct` | Boolean | Direct dependency (vs transitive) |
56
+ | `deprecated` | Boolean | Deprecated dependency |
57
+ | `local` | Boolean | Local/file path dependency |
58
+ | `optional` | Boolean | Optional dependency |
59
+ | `original_name` | String | Original name before aliasing/normalization |
60
+ | `original_requirement` | String | Original requirement before resolution |
61
+ | `source` | String | Path to the manifest file |
62
+ | `integrity` | String | Lockfile integrity hash (see table below) |
63
+
64
+ ## Integrity hash support
65
+
66
+ The `integrity` field is populated for lockfiles that include per-dependency hashes:
67
+
68
+ | Lockfile | Platform | Hash format |
69
+ |----------|----------|-------------|
70
+ | package-lock.json | npm | `sha512-...` |
71
+ | pnpm-lock.yaml | npm | `sha512-...` |
72
+ | yarn.lock (v2+) | npm | `sha512-...` |
73
+ | bun.lock | npm | `sha512-...` |
74
+ | deno.lock | deno | `sha512-...` |
75
+ | go.sum | go | `h1:...` |
76
+ | Gemfile.lock | rubygems | `sha256=...` |
77
+ | poetry.lock | pypi | `sha256:...` |
78
+ | uv.lock | pypi | `sha256:...` |
79
+ | composer.lock | packagist | `sha1=...` |
80
+ | Cargo.lock | cargo | `sha256=...` |
81
+ | Podfile.lock | cocoapods | `sha1=...` |
82
+ | mix.lock | hex | `sha256=...` |
83
+ | rebar.lock | hex | `sha256=...` |
84
+ | manifest.toml (Gleam) | hex | `sha256=...` |
85
+ | stack.yaml.lock | hackage | `sha256=...` |
86
+
45
87
  ## Supported package manager file formats
46
88
 
47
- - npm
48
- - package.json
49
- - package-lock.json
50
- - npm-shrinkwrap.json
51
- - yarn.lock
52
- - pnpm-lock.yaml
53
- - bun.lock
54
- - npm-ls.json
55
- - Maven
56
- - pom.xml
57
- - ivy.xml
58
- - build.gradle
59
- - build.gradle.kts
60
- - gradle-dependencies-q.txt
61
- - maven-resolved-dependencies.txt
62
- - sbt-update-full.txt
63
- - maven-dependency-tree.txt
64
- - maven-dependency-tree.dot
65
- - gradle.lockfile
66
- - verification-metadata.xml
67
- - RubyGems
68
- - Gemfile
69
- - Gemfile.lock
70
- - gems.rb
71
- - gems.locked
72
- - *.gemspec
73
- - Packagist
74
- - composer.json
75
- - composer.lock
76
- - PyPi
77
- - setup.py
78
- - req*.txt
79
- - req*.pip
80
- - requirements/*.txt
81
- - requirements/*.pip
82
- - requirements.frozen
83
- - Pipfile
84
- - Pipfile.lock
85
- - pyproject.toml
86
- - poetry.lock
87
- - uv.lock
88
- - pylock.toml
89
- - pdm.lock
90
- - pip-resolved-dependencies.txt
91
- - pip-dependency-graph.json
92
- - Nuget
93
- - packages.config
94
- - packages.lock.json
95
- - Project.json
96
- - Project.lock.json
97
- - *.nuspec
98
- - paket.lock
99
- - *.csproj
100
- - project.assets.json
101
- - \*.deps.json
102
- - Bower
103
- - bower.json
104
- - BentoML
105
- - bentofile.yaml
106
- - CPAN
107
- - META.json
108
- - META.yml
109
- - cpanfile
110
- - cpanfile.snapshot
111
- - Makefile.PL
112
- - Build.PL
113
- - CocoaPods
114
- - Podfile
115
- - Podfile.lock
116
- - *.podspec
117
- - *.podspec.json
89
+ - Actions
90
+ - action.yml
91
+ - action.yaml
92
+ - .github/workflows/\*.yml
93
+ - .github/workflows/\*.yaml
94
+ - Alpm
95
+ - PKGBUILD
118
96
  - Anaconda
119
97
  - environment.yml
120
98
  - environment.yaml
99
+ - Apk
100
+ - APKBUILD
101
+ - BentoML
102
+ - bentofile.yaml
103
+ - Bower
104
+ - bower.json
105
+ - Cargo
106
+ - Cargo.toml
107
+ - Cargo.lock
108
+ - Carthage
109
+ - Cartfile
110
+ - Cartfile.private
111
+ - Cartfile.resolved
121
112
  - Clojars
122
113
  - project.clj
114
+ - CocoaPods
115
+ - Podfile
116
+ - \*.podspec
117
+ - Podfile.lock
118
+ - \*.podspec.json
123
119
  - Cog
124
120
  - cog.yaml
125
121
  - Conan
126
122
  - conanfile.py
127
123
  - conanfile.txt
128
124
  - conan.lock
129
- - Meteor
130
- - versions.json
131
- - MLflow
132
- - MLmodel
125
+ - CPAN
126
+ - META.json
127
+ - META.yml
128
+ - cpanfile
129
+ - cpanfile.snapshot
130
+ - Makefile.PL
131
+ - Build.PL
133
132
  - CRAN
134
133
  - DESCRIPTION
135
134
  - renv.lock
136
- - Cargo
137
- - Cargo.toml
138
- - Cargo.lock
139
- - Hex
140
- - mix.exs
141
- - mix.lock
142
- - Swift
143
- - Package.swift
144
- - Package.resolved
145
- - Pub
146
- - pubspec.yaml
147
- - pubspec.lock
148
- - Carthage
149
- - Cartfile
150
- - Cartfile.private
151
- - Cartfile.resolved
135
+ - Deb
136
+ - debian/control
137
+ - control
138
+ - Deno
139
+ - deno.json
140
+ - deno.jsonc
141
+ - deno.lock
142
+ - Docker
143
+ - docker-compose\*.yml
144
+ - Dockerfile
152
145
  - Dub
153
146
  - dub.json
154
147
  - dub.sdl
155
- - Julia
156
- - REQUIRE
157
- - Shards
158
- - shard.yml
159
- - shard.lock
148
+ - DVC
149
+ - dvc.yaml
150
+ - Elm
151
+ - elm-package.json
152
+ - elm_dependencies.json
153
+ - elm-stuff/exact-dependencies.json
160
154
  - Go
155
+ - go.mod
156
+ - go.sum
161
157
  - glide.yaml
162
158
  - glide.lock
163
- - Godeps
164
159
  - Godeps/Godeps.json
160
+ - Godeps
165
161
  - vendor/manifest
166
162
  - vendor/vendor.json
167
163
  - Gopkg.toml
168
164
  - Gopkg.lock
169
- - go.mod
170
- - go.sum
171
165
  - go-resolved-dependencies.json
172
- - Elm
173
- - elm-package.json
174
- - elm_dependencies.json
175
- - elm-stuff/exact-dependencies.json
176
- - Haxelib
177
- - haxelib.json
178
166
  - Hackage
179
167
  - \*.cabal
180
- - cabal.config
168
+ - \*cabal.config
181
169
  - stack.yaml.lock
182
- - Actions
183
- - action.yml
184
- - action.yaml
185
- - .github/workflows/*.yml
186
- - .github/workflows/*.yaml
187
- - Docker
188
- - Dockerfile
189
- - docker-compose*.yml
190
- - docker-compose*.yaml
191
- - DVC
192
- - dvc.yaml
193
- - Vcpkg
194
- - vcpkg.json
195
- - _generated-vcpkg-list.json
170
+ - cabal.project.freeze
171
+ - Haxelib
172
+ - haxelib.json
173
+ - Hex
174
+ - mix.exs
175
+ - mix.lock
176
+ - gleam.toml
177
+ - manifest.toml
178
+ - rebar.lock
196
179
  - Homebrew
197
180
  - Brewfile
198
181
  - Brewfile.lock.json
199
- - Ollama
200
- - Modelfile
201
- - Nimble
202
- - \*.nimble
182
+ - Julia
183
+ - REQUIRE
184
+ - Project.toml
185
+ - Manifest.toml
203
186
  - LuaRocks
204
187
  - \*.rockspec
188
+ - Maven
189
+ - ivy.xml
190
+ - pom.xml
191
+ - build.gradle
192
+ - build.gradle.kts
193
+ - gradle-dependencies-q.txt
194
+ - maven-resolved-dependencies.txt
195
+ - sbt-update-full.txt
196
+ - maven-dependency-tree.txt
197
+ - maven-dependency-tree.dot
198
+ - gradle.lockfile
199
+ - verification-metadata.xml
200
+ - Meteor
201
+ - versions.json
202
+ - MLflow
203
+ - MLmodel
204
+ - Nimble
205
+ - \*.nimble
206
+ - Nix
207
+ - flake.nix
208
+ - flake.lock
209
+ - nix/sources.json
210
+ - npins/sources.json
211
+ - npm
212
+ - package.json
213
+ - package-lock.json
214
+ - npm-shrinkwrap.json
215
+ - yarn.lock
216
+ - pnpm-lock.yaml
217
+ - pnpm-workspace.yaml
218
+ - bun.lock
219
+ - npm-ls.json
220
+ - Nuget
221
+ - Project.json
222
+ - Project.lock.json
223
+ - packages.lock.json
224
+ - packages.config
225
+ - \*.nuspec
226
+ - \*.csproj
227
+ - paket.lock
228
+ - project.assets.json
229
+ - \*.deps.json
230
+ - Ollama
231
+ - Modelfile
232
+ - Packagist
233
+ - composer.json
234
+ - composer.lock
235
+ - Pub
236
+ - pubspec.yaml
237
+ - pubspec.lock
238
+ - PyPi
239
+ - setup.py
240
+ - requirements\*.txt
241
+ - requirements\*.pip
242
+ - requirements\*.in
243
+ - requirements.frozen
244
+ - Pipfile
245
+ - Pipfile.lock
246
+ - pyproject.toml
247
+ - poetry.lock
248
+ - uv.lock
249
+ - pylock.toml
250
+ - pdm.lock
251
+ - pip-resolved-dependencies.txt
252
+ - pip-dependency-graph.json
253
+ - Rpm
254
+ - \*.spec
255
+ - RubyGems
256
+ - Gemfile
257
+ - Gemfile.lock
258
+ - gems.rb
259
+ - gems.locked
260
+ - \*.gemspec
261
+ - Shards
262
+ - shard.yml
263
+ - shard.lock
264
+ - Swift
265
+ - Package.swift
266
+ - Package.resolved
267
+ - Vcpkg
268
+ - vcpkg.json
269
+ - _generated-vcpkg-list.json
205
270
 
206
271
  ## Development
207
272
 
@@ -43,6 +43,10 @@ module Bibliothecary
43
43
  @platform_name ||= name.to_s.split("::").last.downcase.freeze
44
44
  end
45
45
 
46
+ def file_patterns
47
+ []
48
+ end
49
+
46
50
  def map_dependencies(hash, key, type, source = nil)
47
51
  hash.fetch(key, []).map do |name, requirement|
48
52
  Dependency.new(
@@ -18,6 +18,8 @@ module Bibliothecary
18
18
  # for cases where it did not match the resolved name. This can be used for features like aliasing.
19
19
  # @source [String] source An optional string to store the location of the manifest that contained this
20
20
  # dependency, e.g. "src/package.json".
21
+ # @attr_reader [String] integrity An optional integrity hash from the lockfile, stored as-is
22
+ # (e.g. "sha512-abc123..." for npm, "h1:xyz..." for go.sum).
21
23
  class Dependency
22
24
  FIELDS = %i[
23
25
  name
@@ -31,6 +33,7 @@ module Bibliothecary
31
33
  optional
32
34
  original_name
33
35
  source
36
+ integrity
34
37
  ].freeze
35
38
 
36
39
  attr_reader(*FIELDS)
@@ -46,7 +49,8 @@ module Bibliothecary
46
49
  local: nil,
47
50
  optional: nil,
48
51
  original_name: nil,
49
- source: nil
52
+ source: nil,
53
+ integrity: nil
50
54
  )
51
55
  @name = name
52
56
  @platform = platform
@@ -59,6 +63,7 @@ module Bibliothecary
59
63
  @optional = optional
60
64
  @original_name = original_name
61
65
  @source = source
66
+ @integrity = integrity
62
67
  end
63
68
 
64
69
  def eql?(other)
@@ -7,6 +7,10 @@ module Bibliothecary
7
7
 
8
8
  WORKFLOW_REGEX = /^\.github\/workflows\/.*.y(a)?ml/
9
9
 
10
+ def self.file_patterns
11
+ ["action.yml", "action.yaml", ".github/workflows/*.yml", ".github/workflows/*.yaml"]
12
+ end
13
+
10
14
  def self.mapping
11
15
  {
12
16
  match_filenames("action.yml","action.yaml") => {
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bibliothecary
4
+ module Parsers
5
+ class Alpm
6
+ include Bibliothecary::Analyser
7
+
8
+ def self.file_patterns
9
+ ["PKGBUILD"]
10
+ end
11
+
12
+ def self.mapping
13
+ {
14
+ match_filename("PKGBUILD") => {
15
+ kind: "manifest",
16
+ parser: :parse_pkgbuild,
17
+ can_have_lockfile: false,
18
+ },
19
+ }
20
+ end
21
+
22
+ def self.parse_pkgbuild(file_contents, options: {})
23
+ source = options.fetch(:filename, "PKGBUILD")
24
+ dependencies = []
25
+
26
+ # Parse depends (runtime)
27
+ extract_variable(file_contents, "depends").each do |dep|
28
+ name, requirement = parse_dependency(dep)
29
+ dependencies << Dependency.new(
30
+ name: name,
31
+ requirement: requirement || "*",
32
+ type: "runtime",
33
+ source: source,
34
+ platform: platform_name
35
+ )
36
+ end
37
+
38
+ # Parse makedepends (build)
39
+ extract_variable(file_contents, "makedepends").each do |dep|
40
+ name, requirement = parse_dependency(dep)
41
+ dependencies << Dependency.new(
42
+ name: name,
43
+ requirement: requirement || "*",
44
+ type: "build",
45
+ source: source,
46
+ platform: platform_name
47
+ )
48
+ end
49
+
50
+ # Parse checkdepends (test)
51
+ extract_variable(file_contents, "checkdepends").each do |dep|
52
+ name, requirement = parse_dependency(dep)
53
+ dependencies << Dependency.new(
54
+ name: name,
55
+ requirement: requirement || "*",
56
+ type: "test",
57
+ source: source,
58
+ platform: platform_name
59
+ )
60
+ end
61
+
62
+ ParserResult.new(dependencies: dependencies)
63
+ end
64
+
65
+ def self.extract_variable(contents, var_name)
66
+ # PKGBUILD uses bash array syntax: depends=('pkg1' 'pkg2') or depends=(pkg1 pkg2)
67
+ # Can also span multiple lines
68
+ pattern = /^#{var_name}=\(([^)]*)\)/m
69
+ match = contents.match(pattern)
70
+ return [] unless match
71
+
72
+ # Extract items, handling both quoted and unquoted formats
73
+ # 'pkg1' 'pkg2' or "pkg1" "pkg2" or pkg1 pkg2
74
+ items = match[1].scan(/['"]([^'"]+)['"]|(\S+)/).flatten.compact
75
+ items.reject { |d| d.empty? || d.start_with?("$") }
76
+ end
77
+
78
+ def self.parse_dependency(dep_string)
79
+ # Parse version constraints like "glibc>=2.17" or "openssl>1.1"
80
+ # Operators: >=, <=, >, <, =
81
+ if dep_string =~ /^(.+?)([><=]+)(.+)$/
82
+ [$1, "#{$2}#{$3}"]
83
+ else
84
+ [dep_string, nil]
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bibliothecary
4
+ module Parsers
5
+ class Apk
6
+ include Bibliothecary::Analyser
7
+
8
+ def self.file_patterns
9
+ ["APKBUILD"]
10
+ end
11
+
12
+ def self.mapping
13
+ {
14
+ match_filename("APKBUILD") => {
15
+ kind: "manifest",
16
+ parser: :parse_apkbuild,
17
+ can_have_lockfile: false,
18
+ },
19
+ }
20
+ end
21
+
22
+ def self.parse_apkbuild(file_contents, options: {})
23
+ source = options.fetch(:filename, "APKBUILD")
24
+ dependencies = []
25
+
26
+ # Parse depends (runtime)
27
+ extract_variable(file_contents, "depends").each do |dep|
28
+ name, requirement = parse_dependency(dep)
29
+ dependencies << Dependency.new(
30
+ name: name,
31
+ requirement: requirement || "*",
32
+ type: "runtime",
33
+ source: source,
34
+ platform: platform_name
35
+ )
36
+ end
37
+
38
+ # Parse makedepends (build)
39
+ extract_variable(file_contents, "makedepends").each do |dep|
40
+ name, requirement = parse_dependency(dep)
41
+ dependencies << Dependency.new(
42
+ name: name,
43
+ requirement: requirement || "*",
44
+ type: "build",
45
+ source: source,
46
+ platform: platform_name
47
+ )
48
+ end
49
+
50
+ # Parse checkdepends (test)
51
+ extract_variable(file_contents, "checkdepends").each do |dep|
52
+ name, requirement = parse_dependency(dep)
53
+ dependencies << Dependency.new(
54
+ name: name,
55
+ requirement: requirement || "*",
56
+ type: "test",
57
+ source: source,
58
+ platform: platform_name
59
+ )
60
+ end
61
+
62
+ ParserResult.new(dependencies: dependencies)
63
+ end
64
+
65
+ def self.extract_variable(contents, var_name)
66
+ # Match variable assignment with double or single quotes, handling multi-line with backslash
67
+ # Examples:
68
+ # depends="foo bar"
69
+ # makedepends="foo
70
+ # bar"
71
+ # checkdepends='foo bar'
72
+ pattern = /^#{var_name}=["']([^"']*?)["']/m
73
+ match = contents.match(pattern)
74
+ return [] unless match
75
+
76
+ # Split on whitespace and filter out empty strings, negated packages (!), and variable references ($)
77
+ match[1].split(/\s+/).reject { |d| d.empty? || d.start_with?("!") || d.start_with?("$") }
78
+ end
79
+
80
+ def self.parse_dependency(dep_string)
81
+ # Parse version constraints like "openssl-dev>3" or "zlib-dev>=1.2.3"
82
+ # Operators: >=, <=, >, <, =, ~
83
+ if dep_string =~ /^(.+?)([><=~]+)(.+)$/
84
+ [$1, "#{$2}#{$3}"]
85
+ else
86
+ [dep_string, nil]
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -5,12 +5,16 @@ module Bibliothecary
5
5
  class BentoML
6
6
  include Bibliothecary::Analyser
7
7
 
8
+ def self.file_patterns
9
+ ["bentofile.yaml"]
10
+ end
11
+
8
12
  def self.mapping
9
13
  {
10
14
  match_filename("bentofile.yaml") => {
11
15
  kind: 'manifest',
12
16
  parser: :parse_bentofile,
13
- related_to: [ 'manifest' ]
17
+ can_have_lockfile: false,
14
18
  }
15
19
  }
16
20
  end
@@ -7,11 +7,16 @@ module Bibliothecary
7
7
  class Bower
8
8
  include Bibliothecary::Analyser
9
9
 
10
+ def self.file_patterns
11
+ ["bower.json"]
12
+ end
13
+
10
14
  def self.mapping
11
15
  {
12
16
  match_filename("bower.json") => {
13
17
  kind: "manifest",
14
18
  parser: :parse_manifest,
19
+ can_have_lockfile: false,
15
20
  },
16
21
  }
17
22
  end
@@ -5,6 +5,10 @@ module Bibliothecary
5
5
  class Cargo
6
6
  include Bibliothecary::Analyser
7
7
 
8
+ def self.file_patterns
9
+ ["Cargo.toml", "Cargo.lock"]
10
+ end
11
+
8
12
  def self.mapping
9
13
  {
10
14
  match_filename("Cargo.toml") => {
@@ -51,6 +55,7 @@ module Bibliothecary
51
55
  name = block[/name\s*=\s*"([^"]+)"/, 1]
52
56
  version = block[/version\s*=\s*"([^"]+)"/, 1]
53
57
  source = block[/source\s*=\s*"([^"]+)"/, 1]
58
+ checksum = block[/checksum\s*=\s*"([^"]+)"/, 1]
54
59
 
55
60
  # Skip packages without a registry source (local/workspace packages)
56
61
  next unless source&.start_with?("registry+")
@@ -60,7 +65,8 @@ module Bibliothecary
60
65
  requirement: version,
61
66
  type: "runtime",
62
67
  source: options.fetch(:filename, nil),
63
- platform: platform_name
68
+ platform: platform_name,
69
+ integrity: checksum ? "sha256=#{checksum}" : nil
64
70
  )
65
71
  end
66
72
  ParserResult.new(dependencies: dependencies)