ecosystems-bibliothecary 15.1.0 → 15.2.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 +24 -0
- data/README.md +137 -120
- data/lib/bibliothecary/analyser.rb +4 -0
- data/lib/bibliothecary/parsers/actions.rb +4 -0
- data/lib/bibliothecary/parsers/bentoml.rb +4 -0
- data/lib/bibliothecary/parsers/bower.rb +4 -0
- data/lib/bibliothecary/parsers/cargo.rb +4 -0
- data/lib/bibliothecary/parsers/carthage.rb +4 -0
- data/lib/bibliothecary/parsers/clojars.rb +4 -0
- data/lib/bibliothecary/parsers/cocoapods.rb +4 -0
- data/lib/bibliothecary/parsers/cog.rb +4 -0
- data/lib/bibliothecary/parsers/conan.rb +4 -0
- data/lib/bibliothecary/parsers/conda.rb +4 -0
- data/lib/bibliothecary/parsers/cpan.rb +190 -2
- data/lib/bibliothecary/parsers/cran.rb +4 -0
- data/lib/bibliothecary/parsers/deno.rb +98 -0
- data/lib/bibliothecary/parsers/docker.rb +4 -0
- data/lib/bibliothecary/parsers/dub.rb +4 -0
- data/lib/bibliothecary/parsers/dvc.rb +4 -0
- data/lib/bibliothecary/parsers/elm.rb +4 -0
- data/lib/bibliothecary/parsers/go.rb +4 -0
- data/lib/bibliothecary/parsers/hackage.rb +55 -0
- data/lib/bibliothecary/parsers/haxelib.rb +4 -0
- data/lib/bibliothecary/parsers/hex.rb +89 -0
- data/lib/bibliothecary/parsers/homebrew.rb +4 -0
- data/lib/bibliothecary/parsers/julia.rb +55 -0
- data/lib/bibliothecary/parsers/luarocks.rb +4 -0
- data/lib/bibliothecary/parsers/maven.rb +4 -0
- data/lib/bibliothecary/parsers/meteor.rb +4 -0
- data/lib/bibliothecary/parsers/mlflow.rb +4 -0
- data/lib/bibliothecary/parsers/nimble.rb +4 -0
- data/lib/bibliothecary/parsers/nix.rb +205 -0
- data/lib/bibliothecary/parsers/npm.rb +4 -0
- data/lib/bibliothecary/parsers/nuget.rb +4 -0
- data/lib/bibliothecary/parsers/ollama.rb +4 -0
- data/lib/bibliothecary/parsers/packagist.rb +4 -0
- data/lib/bibliothecary/parsers/pub.rb +4 -0
- data/lib/bibliothecary/parsers/pypi.rb +9 -0
- data/lib/bibliothecary/parsers/rubygems.rb +4 -0
- data/lib/bibliothecary/parsers/shard.rb +4 -0
- data/lib/bibliothecary/parsers/swift_pm.rb +4 -0
- data/lib/bibliothecary/parsers/vcpkg.rb +4 -0
- data/lib/bibliothecary/version.rb +1 -1
- data/lib/bibliothecary.rb +7 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c1399499146bc9abb6b2053d1e842cff2a33e05166f4fca7fed6fba222146f5e
|
|
4
|
+
data.tar.gz: 2b1460ba23303796a1b73bfa445fee11771857f5270effce6da04e6ed4ff920f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ab9631fd2e5472d6a60784685252961f75fcae716561d1e7bd6c1bc7f87bba18f346988b26f787cc13bd666fc06a99db133926726880ee983e01fbe4f64a5d9
|
|
7
|
+
data.tar.gz: 1dc6d4efca6e8b643ca7c76e495a6b40364169fc8b51d238f2708e5da1ec8d04515adafec8d2042951088729258b3552a547473c93a59ae3f12c7a89ff681065
|
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
13
|
|
|
14
14
|
### Removed
|
|
15
15
|
|
|
16
|
+
## [15.2.0]
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Deno parser for deno.json, deno.jsonc, and deno.lock files (supports npm: and jsr: specifiers)
|
|
21
|
+
- Nix parser for flake.nix, flake.lock, nix/sources.json (niv), and npins/sources.json (npins)
|
|
22
|
+
- Gleam support in Hex parser for gleam.toml and manifest.toml
|
|
23
|
+
- Rebar3 support in Hex parser for rebar.lock
|
|
24
|
+
- Julia Project.toml and Manifest.toml support
|
|
25
|
+
- Hackage cabal.project.freeze support
|
|
26
|
+
|
|
27
|
+
## [15.1.1]
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- CPAN: cpanfile parser for Perl dependency declarations
|
|
32
|
+
- CPAN: cpanfile.snapshot parser for Carton lockfiles
|
|
33
|
+
- CPAN: Makefile.PL parser for ExtUtils::MakeMaker build scripts
|
|
34
|
+
- CPAN: Build.PL parser for Module::Build scripts
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- CPAN: META.json and META.yml are now classified as lockfiles (they are generated, not hand-written)
|
|
39
|
+
|
|
16
40
|
## [15.1.0]
|
|
17
41
|
|
|
18
42
|
### Added
|
data/README.md
CHANGED
|
@@ -44,160 +44,177 @@ All available config options are in: https://github.com/ecosyste-ms/bibliothecar
|
|
|
44
44
|
|
|
45
45
|
## Supported package manager file formats
|
|
46
46
|
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
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
|
-
- CocoaPods
|
|
110
|
-
- Podfile
|
|
111
|
-
- Podfile.lock
|
|
112
|
-
- *.podspec
|
|
113
|
-
- *.podspec.json
|
|
47
|
+
- Actions
|
|
48
|
+
- action.yml
|
|
49
|
+
- action.yaml
|
|
50
|
+
- .github/workflows/\*.yml
|
|
51
|
+
- .github/workflows/\*.yaml
|
|
114
52
|
- Anaconda
|
|
115
53
|
- environment.yml
|
|
116
54
|
- environment.yaml
|
|
55
|
+
- BentoML
|
|
56
|
+
- bentofile.yaml
|
|
57
|
+
- Bower
|
|
58
|
+
- bower.json
|
|
59
|
+
- Cargo
|
|
60
|
+
- Cargo.toml
|
|
61
|
+
- Cargo.lock
|
|
62
|
+
- Carthage
|
|
63
|
+
- Cartfile
|
|
64
|
+
- Cartfile.private
|
|
65
|
+
- Cartfile.resolved
|
|
117
66
|
- Clojars
|
|
118
67
|
- project.clj
|
|
68
|
+
- CocoaPods
|
|
69
|
+
- Podfile
|
|
70
|
+
- \*.podspec
|
|
71
|
+
- Podfile.lock
|
|
72
|
+
- \*.podspec.json
|
|
119
73
|
- Cog
|
|
120
74
|
- cog.yaml
|
|
121
75
|
- Conan
|
|
122
76
|
- conanfile.py
|
|
123
77
|
- conanfile.txt
|
|
124
78
|
- conan.lock
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
79
|
+
- CPAN
|
|
80
|
+
- META.json
|
|
81
|
+
- META.yml
|
|
82
|
+
- cpanfile
|
|
83
|
+
- cpanfile.snapshot
|
|
84
|
+
- Makefile.PL
|
|
85
|
+
- Build.PL
|
|
129
86
|
- CRAN
|
|
130
87
|
- DESCRIPTION
|
|
131
88
|
- renv.lock
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
- Package.swift
|
|
140
|
-
- Package.resolved
|
|
141
|
-
- Pub
|
|
142
|
-
- pubspec.yaml
|
|
143
|
-
- pubspec.lock
|
|
144
|
-
- Carthage
|
|
145
|
-
- Cartfile
|
|
146
|
-
- Cartfile.private
|
|
147
|
-
- Cartfile.resolved
|
|
89
|
+
- Deno
|
|
90
|
+
- deno.json
|
|
91
|
+
- deno.jsonc
|
|
92
|
+
- deno.lock
|
|
93
|
+
- Docker
|
|
94
|
+
- docker-compose\*.yml
|
|
95
|
+
- Dockerfile
|
|
148
96
|
- Dub
|
|
149
97
|
- dub.json
|
|
150
98
|
- dub.sdl
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
99
|
+
- DVC
|
|
100
|
+
- dvc.yaml
|
|
101
|
+
- Elm
|
|
102
|
+
- elm-package.json
|
|
103
|
+
- elm_dependencies.json
|
|
104
|
+
- elm-stuff/exact-dependencies.json
|
|
156
105
|
- Go
|
|
106
|
+
- go.mod
|
|
107
|
+
- go.sum
|
|
157
108
|
- glide.yaml
|
|
158
109
|
- glide.lock
|
|
159
|
-
- Godeps
|
|
160
110
|
- Godeps/Godeps.json
|
|
111
|
+
- Godeps
|
|
161
112
|
- vendor/manifest
|
|
162
113
|
- vendor/vendor.json
|
|
163
114
|
- Gopkg.toml
|
|
164
115
|
- Gopkg.lock
|
|
165
|
-
- go.mod
|
|
166
|
-
- go.sum
|
|
167
116
|
- go-resolved-dependencies.json
|
|
168
|
-
- Elm
|
|
169
|
-
- elm-package.json
|
|
170
|
-
- elm_dependencies.json
|
|
171
|
-
- elm-stuff/exact-dependencies.json
|
|
172
|
-
- Haxelib
|
|
173
|
-
- haxelib.json
|
|
174
117
|
- Hackage
|
|
175
118
|
- \*.cabal
|
|
176
|
-
- cabal.config
|
|
119
|
+
- \*cabal.config
|
|
177
120
|
- stack.yaml.lock
|
|
178
|
-
-
|
|
179
|
-
|
|
180
|
-
-
|
|
181
|
-
|
|
182
|
-
- .
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
- DVC
|
|
188
|
-
- dvc.yaml
|
|
189
|
-
- Vcpkg
|
|
190
|
-
- vcpkg.json
|
|
191
|
-
- _generated-vcpkg-list.json
|
|
121
|
+
- cabal.project.freeze
|
|
122
|
+
- Haxelib
|
|
123
|
+
- haxelib.json
|
|
124
|
+
- Hex
|
|
125
|
+
- mix.exs
|
|
126
|
+
- mix.lock
|
|
127
|
+
- gleam.toml
|
|
128
|
+
- manifest.toml
|
|
129
|
+
- rebar.lock
|
|
192
130
|
- Homebrew
|
|
193
131
|
- Brewfile
|
|
194
132
|
- Brewfile.lock.json
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
-
|
|
133
|
+
- Julia
|
|
134
|
+
- REQUIRE
|
|
135
|
+
- Project.toml
|
|
136
|
+
- Manifest.toml
|
|
199
137
|
- LuaRocks
|
|
200
138
|
- \*.rockspec
|
|
139
|
+
- Maven
|
|
140
|
+
- ivy.xml
|
|
141
|
+
- pom.xml
|
|
142
|
+
- build.gradle
|
|
143
|
+
- build.gradle.kts
|
|
144
|
+
- gradle-dependencies-q.txt
|
|
145
|
+
- maven-resolved-dependencies.txt
|
|
146
|
+
- sbt-update-full.txt
|
|
147
|
+
- maven-dependency-tree.txt
|
|
148
|
+
- maven-dependency-tree.dot
|
|
149
|
+
- gradle.lockfile
|
|
150
|
+
- verification-metadata.xml
|
|
151
|
+
- Meteor
|
|
152
|
+
- versions.json
|
|
153
|
+
- MLflow
|
|
154
|
+
- MLmodel
|
|
155
|
+
- Nimble
|
|
156
|
+
- \*.nimble
|
|
157
|
+
- Nix
|
|
158
|
+
- flake.nix
|
|
159
|
+
- flake.lock
|
|
160
|
+
- nix/sources.json
|
|
161
|
+
- npins/sources.json
|
|
162
|
+
- npm
|
|
163
|
+
- package.json
|
|
164
|
+
- package-lock.json
|
|
165
|
+
- npm-shrinkwrap.json
|
|
166
|
+
- yarn.lock
|
|
167
|
+
- pnpm-lock.yaml
|
|
168
|
+
- bun.lock
|
|
169
|
+
- npm-ls.json
|
|
170
|
+
- Nuget
|
|
171
|
+
- Project.json
|
|
172
|
+
- Project.lock.json
|
|
173
|
+
- packages.lock.json
|
|
174
|
+
- packages.config
|
|
175
|
+
- \*.nuspec
|
|
176
|
+
- \*.csproj
|
|
177
|
+
- paket.lock
|
|
178
|
+
- project.assets.json
|
|
179
|
+
- \*.deps.json
|
|
180
|
+
- Ollama
|
|
181
|
+
- Modelfile
|
|
182
|
+
- Packagist
|
|
183
|
+
- composer.json
|
|
184
|
+
- composer.lock
|
|
185
|
+
- Pub
|
|
186
|
+
- pubspec.yaml
|
|
187
|
+
- pubspec.lock
|
|
188
|
+
- PyPi
|
|
189
|
+
- setup.py
|
|
190
|
+
- requirements\*.txt
|
|
191
|
+
- requirements\*.pip
|
|
192
|
+
- requirements\*.in
|
|
193
|
+
- requirements.frozen
|
|
194
|
+
- Pipfile
|
|
195
|
+
- Pipfile.lock
|
|
196
|
+
- pyproject.toml
|
|
197
|
+
- poetry.lock
|
|
198
|
+
- uv.lock
|
|
199
|
+
- pylock.toml
|
|
200
|
+
- pdm.lock
|
|
201
|
+
- pip-resolved-dependencies.txt
|
|
202
|
+
- pip-dependency-graph.json
|
|
203
|
+
- RubyGems
|
|
204
|
+
- Gemfile
|
|
205
|
+
- Gemfile.lock
|
|
206
|
+
- gems.rb
|
|
207
|
+
- gems.locked
|
|
208
|
+
- \*.gemspec
|
|
209
|
+
- Shards
|
|
210
|
+
- shard.yml
|
|
211
|
+
- shard.lock
|
|
212
|
+
- Swift
|
|
213
|
+
- Package.swift
|
|
214
|
+
- Package.resolved
|
|
215
|
+
- Vcpkg
|
|
216
|
+
- vcpkg.json
|
|
217
|
+
- _generated-vcpkg-list.json
|
|
201
218
|
|
|
202
219
|
## Development
|
|
203
220
|
|
|
@@ -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(
|
|
@@ -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") => {
|
|
@@ -15,6 +15,10 @@ module Bibliothecary
|
|
|
15
15
|
# Group 4: unquoted requirement (e.g., >= 1.0, ~> 2.0)
|
|
16
16
|
CARTFILE_REGEXP = /^(github|git|binary)\s+"([^"]+)"(?:\s+(?:"([^"]+)"|((?:>=|<=|~>|==|>|<)\s*[\d.]+)))?/
|
|
17
17
|
|
|
18
|
+
def self.file_patterns
|
|
19
|
+
["Cartfile", "Cartfile.private", "Cartfile.resolved"]
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
def self.mapping
|
|
19
23
|
{
|
|
20
24
|
match_filename("Cartfile") => {
|
|
@@ -7,6 +7,10 @@ module Bibliothecary
|
|
|
7
7
|
# Name can be like: org.clojure/clojure, cheshire, ring/ring-defaults
|
|
8
8
|
DEPENDENCY_REGEXP = %r{\[([a-zA-Z0-9_./\-]+)\s+"([^"]+)"\]}
|
|
9
9
|
|
|
10
|
+
def self.file_patterns
|
|
11
|
+
["project.clj"]
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
def self.mapping
|
|
11
15
|
{
|
|
12
16
|
match_filename("project.clj") => {
|
|
@@ -17,6 +17,10 @@ module Bibliothecary
|
|
|
17
17
|
# Podspec pattern: .dependency "Name", "version"
|
|
18
18
|
PODSPEC_DEPENDENCY = /\.dependency\s+['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]+)['"])?/
|
|
19
19
|
|
|
20
|
+
def self.file_patterns
|
|
21
|
+
["Podfile", "*.podspec", "Podfile.lock", "*.podspec.json"]
|
|
22
|
+
end
|
|
23
|
+
|
|
20
24
|
def self.mapping
|
|
21
25
|
{
|
|
22
26
|
match_filename("Podfile") => {
|
|
@@ -8,16 +8,36 @@ module Bibliothecary
|
|
|
8
8
|
class CPAN
|
|
9
9
|
include Bibliothecary::Analyser
|
|
10
10
|
|
|
11
|
+
def self.file_patterns
|
|
12
|
+
["META.json", "META.yml", "cpanfile", "cpanfile.snapshot", "Makefile.PL", "Build.PL"]
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
def self.mapping
|
|
12
16
|
{
|
|
13
17
|
match_filename("META.json", case_insensitive: true) => {
|
|
14
|
-
kind: "
|
|
18
|
+
kind: "lockfile",
|
|
15
19
|
parser: :parse_json_manifest,
|
|
16
20
|
},
|
|
17
21
|
match_filename("META.yml", case_insensitive: true) => {
|
|
18
|
-
kind: "
|
|
22
|
+
kind: "lockfile",
|
|
19
23
|
parser: :parse_yaml_manifest,
|
|
20
24
|
},
|
|
25
|
+
match_filename("cpanfile", case_insensitive: true) => {
|
|
26
|
+
kind: "manifest",
|
|
27
|
+
parser: :parse_cpanfile,
|
|
28
|
+
},
|
|
29
|
+
match_filename("cpanfile.snapshot", case_insensitive: true) => {
|
|
30
|
+
kind: "lockfile",
|
|
31
|
+
parser: :parse_cpanfile_snapshot,
|
|
32
|
+
},
|
|
33
|
+
match_filename("Makefile.PL", case_insensitive: true) => {
|
|
34
|
+
kind: "manifest",
|
|
35
|
+
parser: :parse_makefile_pl,
|
|
36
|
+
},
|
|
37
|
+
match_filename("Build.PL", case_insensitive: true) => {
|
|
38
|
+
kind: "manifest",
|
|
39
|
+
parser: :parse_build_pl,
|
|
40
|
+
},
|
|
21
41
|
}
|
|
22
42
|
end
|
|
23
43
|
|
|
@@ -35,6 +55,174 @@ module Bibliothecary
|
|
|
35
55
|
dependencies = map_dependencies(manifest, "requires", "runtime", options.fetch(:filename, nil))
|
|
36
56
|
ParserResult.new(dependencies: dependencies)
|
|
37
57
|
end
|
|
58
|
+
|
|
59
|
+
def self.parse_cpanfile(file_contents, options: {})
|
|
60
|
+
filename = options.fetch(:filename, nil)
|
|
61
|
+
dependencies = []
|
|
62
|
+
current_phase = "runtime"
|
|
63
|
+
current_feature = nil
|
|
64
|
+
|
|
65
|
+
file_contents.each_line do |line|
|
|
66
|
+
line = line.strip
|
|
67
|
+
|
|
68
|
+
# Track phase changes: on 'test' => sub {
|
|
69
|
+
if line =~ /\bon\s+['"](\w+)['"]\s*=>/
|
|
70
|
+
current_phase = $1
|
|
71
|
+
next
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Track feature blocks: feature 'name', 'desc' => sub {
|
|
75
|
+
if line =~ /\bfeature\s+['"]([\w-]+)['"]/
|
|
76
|
+
current_feature = $1
|
|
77
|
+
next
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# End of block - reset to defaults
|
|
81
|
+
if line =~ /^\s*\};\s*$/
|
|
82
|
+
current_phase = "runtime"
|
|
83
|
+
current_feature = nil
|
|
84
|
+
next
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Parse dependency declarations
|
|
88
|
+
# requires 'Module::Name', 'version';
|
|
89
|
+
# requires 'Module::Name';
|
|
90
|
+
# recommends 'Module::Name', 'version';
|
|
91
|
+
if line =~ /\b(requires|recommends|suggests|conflicts)\s+['"]([^'"]+)['"](?:\s*,\s*['"]?([^'";]+)['"]?)?/
|
|
92
|
+
dep_type = $1
|
|
93
|
+
name = $2
|
|
94
|
+
version = $3&.strip || "*"
|
|
95
|
+
|
|
96
|
+
# Map cpanfile phases to our types
|
|
97
|
+
type = case current_phase
|
|
98
|
+
when "test" then "test"
|
|
99
|
+
when "develop" then "develop"
|
|
100
|
+
when "build" then "build"
|
|
101
|
+
when "configure" then "build"
|
|
102
|
+
else dep_type == "requires" ? "runtime" : dep_type
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
dependencies << Dependency.new(
|
|
106
|
+
name: name,
|
|
107
|
+
requirement: version,
|
|
108
|
+
type: type,
|
|
109
|
+
platform: "cpan",
|
|
110
|
+
source: filename
|
|
111
|
+
)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
ParserResult.new(dependencies: dependencies)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def self.parse_cpanfile_snapshot(file_contents, options: {})
|
|
119
|
+
filename = options.fetch(:filename, nil)
|
|
120
|
+
dependencies = []
|
|
121
|
+
|
|
122
|
+
file_contents.each_line do |line|
|
|
123
|
+
# Match distribution header: Module-Name-1.23
|
|
124
|
+
if (match = line.match(/^ (\S+)-v?([\d._]+)$/))
|
|
125
|
+
dist_name = match[1].gsub("-", "::")
|
|
126
|
+
version = match[2]
|
|
127
|
+
dependencies << Dependency.new(
|
|
128
|
+
name: dist_name,
|
|
129
|
+
requirement: version,
|
|
130
|
+
type: "runtime",
|
|
131
|
+
platform: "cpan",
|
|
132
|
+
source: filename
|
|
133
|
+
)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
ParserResult.new(dependencies: dependencies)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Parse Makefile.PL (ExtUtils::MakeMaker format)
|
|
141
|
+
# Looks for PREREQ_PM, BUILD_REQUIRES, TEST_REQUIRES, CONFIGURE_REQUIRES
|
|
142
|
+
def self.parse_makefile_pl(file_contents, options: {})
|
|
143
|
+
filename = options.fetch(:filename, nil)
|
|
144
|
+
dependencies = []
|
|
145
|
+
|
|
146
|
+
# Map of hash key names to dependency types
|
|
147
|
+
type_mapping = {
|
|
148
|
+
"PREREQ_PM" => "runtime",
|
|
149
|
+
"BUILD_REQUIRES" => "build",
|
|
150
|
+
"TEST_REQUIRES" => "test",
|
|
151
|
+
"CONFIGURE_REQUIRES" => "build",
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type_mapping.each do |key, type|
|
|
155
|
+
deps = extract_perl_hash(file_contents, key)
|
|
156
|
+
deps.each do |name, version|
|
|
157
|
+
dependencies << Dependency.new(
|
|
158
|
+
name: name,
|
|
159
|
+
requirement: version,
|
|
160
|
+
type: type,
|
|
161
|
+
platform: "cpan",
|
|
162
|
+
source: filename
|
|
163
|
+
)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
ParserResult.new(dependencies: dependencies)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Parse Build.PL (Module::Build format)
|
|
171
|
+
# Looks for requires, build_requires, test_requires, configure_requires
|
|
172
|
+
def self.parse_build_pl(file_contents, options: {})
|
|
173
|
+
filename = options.fetch(:filename, nil)
|
|
174
|
+
dependencies = []
|
|
175
|
+
|
|
176
|
+
# Map of hash key names to dependency types
|
|
177
|
+
type_mapping = {
|
|
178
|
+
"requires" => "runtime",
|
|
179
|
+
"build_requires" => "build",
|
|
180
|
+
"test_requires" => "test",
|
|
181
|
+
"configure_requires" => "build",
|
|
182
|
+
"recommends" => "runtime",
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
type_mapping.each do |key, type|
|
|
186
|
+
deps = extract_perl_hash(file_contents, key)
|
|
187
|
+
deps.each do |name, version|
|
|
188
|
+
dependencies << Dependency.new(
|
|
189
|
+
name: name,
|
|
190
|
+
requirement: version,
|
|
191
|
+
type: type,
|
|
192
|
+
platform: "cpan",
|
|
193
|
+
source: filename
|
|
194
|
+
)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
ParserResult.new(dependencies: dependencies)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Extract a Perl hash from source code
|
|
202
|
+
# Handles patterns like: KEY => { 'Module' => '1.0', ... }
|
|
203
|
+
def self.extract_perl_hash(content, key)
|
|
204
|
+
deps = {}
|
|
205
|
+
|
|
206
|
+
# Match the hash assignment: KEY => { ... }
|
|
207
|
+
# Use word boundary to avoid matching configure_requires when looking for requires
|
|
208
|
+
pattern = /(?:^|[^\w])#{Regexp.escape(key)}\s*=>\s*\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/m
|
|
209
|
+
|
|
210
|
+
if (match = content.match(pattern))
|
|
211
|
+
hash_content = match[1]
|
|
212
|
+
|
|
213
|
+
# Extract 'Module::Name' => 'version' or 'Module::Name' => version patterns
|
|
214
|
+
hash_content.scan(/['"]([^'"]+)['"]\s*=>\s*['"]?([^'",}\s]+)['"]?/) do |name, version|
|
|
215
|
+
# Skip perl version requirements and non-module entries
|
|
216
|
+
next if name == "perl"
|
|
217
|
+
|
|
218
|
+
# Normalize version: 0 means any version
|
|
219
|
+
version = "*" if version == "0"
|
|
220
|
+
deps[name] = version
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
deps
|
|
225
|
+
end
|
|
38
226
|
end
|
|
39
227
|
end
|
|
40
228
|
end
|