bibliothecary 11.0.1 → 12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78844f8813583a84df76e0ad0c72f9b8136b47d82aec8194e3e6766049ba721b
4
- data.tar.gz: bb84e383f0bbded7361d7efbf4550f100d08281a294def960c95ddb1dca4f97c
3
+ metadata.gz: 12b592879fc7f4fbe3622f495e8ef989b541c81487915b693d02907cedeb62a0
4
+ data.tar.gz: fd266f3924f202a864017c52ff1c2eb84fd68c4451b16b95e6aa44d80b850598
5
5
  SHA512:
6
- metadata.gz: f537a3fd368046789baf28c758b8f60d8832b7601f2ae78211a78d4d583ee7ddc4d4729f1ca3387e92958756586a6c1608099a4849db70c9e0a2a3b7405ff564
7
- data.tar.gz: 8b9d7e93affe8df9d4e898bf4c128f912f16dd2e1c61ba7dfde0163690df91c173ed0a75c48717a702ddb45dfff2053527b5730c3d76738e7bf51b2344d09cff
6
+ metadata.gz: e4622e4be1424fd679fac201929bcdf77ed02f0f5782799cf506c93af1d21b803a7e8319e8f471b4747eb5d1a02dba3c0bf8914bae3c4a7a9c95c1b49c37c7b8
7
+ data.tar.gz: 16950d0fdfcf98cbef1b0faeb61fe1e398816b5499a2fe7af02ea3380975fce4bf85e81a64bfc2d9bb382753f2bdd538e2a46896e8a7e08476716a777adc32aa
data/.circleci/config.yml CHANGED
@@ -5,7 +5,7 @@ orbs:
5
5
  executors:
6
6
  bibliothecary:
7
7
  docker:
8
- - image: cimg/ruby:3.0.7
8
+ - image: cimg/ruby:3.2.4
9
9
  working_directory: ~/bibliothecary
10
10
 
11
11
 
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.5
1
+ 3.2.4
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.0.0] - 2025-01-27
17
+
18
+ ### Removed
19
+
20
+ - This is a MAJOR release in that it removes support for hackage, carthage, hex, clojar, and swiftpm
21
+ from Bibliothecary. We are no longer doing any network calls when using Bibliothecary and reimplementing
22
+ parsing for those file types natively is non-trivial. Patches welcome :-)
23
+
24
+ ### Changed
25
+
26
+ - Rewrote conda and yarn parsers to be in process vs calling out over the network
16
27
 
17
28
  ## [11.0.1] - 2024-12-20
18
29
 
@@ -31,7 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rake", "~> 12.0"
32
32
  spec.add_development_dependency "rspec", "~> 3.0"
33
33
  spec.add_development_dependency "webmock"
34
- spec.add_development_dependency "vcr"
35
34
  spec.add_development_dependency "rubocop"
36
35
  spec.add_development_dependency "rubocop-rails"
37
36
  end
@@ -5,7 +5,6 @@ module Bibliothecary
5
5
  attr_accessor :carthage_parser_host
6
6
  attr_accessor :clojars_parser_host
7
7
  attr_accessor :mix_parser_host
8
- attr_accessor :yarn_parser_host
9
8
  attr_accessor :conda_parser_host
10
9
  attr_accessor :swift_parser_host
11
10
  attr_accessor :cabal_parser_host
@@ -16,8 +15,6 @@ module Bibliothecary
16
15
  @carthage_parser_host = "https://carthage.libraries.io"
17
16
  @clojars_parser_host = "https://clojars.libraries.io"
18
17
  @mix_parser_host = "https://mix.libraries.io"
19
- @yarn_parser_host = "https://yarn-parser.libraries.io"
20
- @conda_parser_host = "https://conda-parser.libraries.io"
21
18
  @swift_parser_host = "http://swift.libraries.io"
22
19
  @cabal_parser_host = "http://cabal.libraries.io"
23
20
  end
@@ -1,4 +1,4 @@
1
- require "json"
1
+ require "yaml"
2
2
 
3
3
  module Bibliothecary
4
4
  module Parsers
@@ -15,14 +15,6 @@ module Bibliothecary
15
15
  parser: :parse_conda,
16
16
  kind: "manifest",
17
17
  },
18
- match_filename("environment.yml.lock") => {
19
- parser: :parse_conda_lockfile,
20
- kind: "lockfile",
21
- },
22
- match_filename("environment.yaml.lock") => {
23
- parser: :parse_conda_lockfile,
24
- kind: "lockfile",
25
- },
26
18
  }
27
19
  end
28
20
 
@@ -31,34 +23,63 @@ module Bibliothecary
31
23
  add_multi_parser(Bibliothecary::MultiParsers::Spdx)
32
24
 
33
25
  def self.parse_conda(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
34
- parse_conda_with_kind(file_contents, "manifest")
35
- end
26
+ manifest = YAML.load(file_contents)
27
+ deps = manifest.dig("dependencies")
28
+ deps.map do |dep|
29
+ next unless dep.is_a? String # only deal with strings to skip parsing pip stuff
36
30
 
37
- def self.parse_conda_lockfile(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
38
- parse_conda_with_kind(file_contents, "lockfile")
31
+ parsed = parse_name_requirement_from_matchspec(dep)
32
+ Dependency.new(**parsed.merge(type: "runtime"))
33
+ end.compact
39
34
  end
40
35
 
41
- def self.parse_conda_with_kind(info, kind)
42
- dependencies = call_conda_parser_web(info, kind)[kind.to_sym]
43
- dependencies.map { |dep_kv| Dependency.new(**dep_kv.merge(type: "runtime")) }
44
- end
36
+ def self.parse_name_requirement_from_matchspec(ms)
37
+ # simplified version of the implementation in conda to handle what we care about
38
+ # https://github.com/conda/conda/blob/main/conda/models/match_spec.py#L598
39
+ # (channel(/subdir):(namespace):)name(version(build))[key1=value1,key2=value2]
40
+ return if ms.end_with?("@")
45
41
 
46
- private_class_method def self.call_conda_parser_web(file_contents, kind)
47
- host = Bibliothecary.configuration.conda_parser_host
48
- response = Typhoeus.post(
49
- "#{host}/parse",
50
- headers: {
51
- ContentType: "multipart/form-data",
52
- },
53
- body: {
54
- file: file_contents,
55
- # Unfortunately we do not get the filename in the mapping parsers, so hardcoding the file name depending on the kind
56
- filename: kind == "manifest" ? "environment.yml" : "environment.yml.lock",
57
- }
58
- )
59
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{host}/parse", response.response_code) unless response.success?
42
+ # strip off comments and optional features
43
+ ms = ms.split(/#/, 2).first
44
+ ms = ms.split(/ if /, 2).first
45
+
46
+ # strip off brackets
47
+ ms = ms.match(/^(.*)(?:\[(.*)\])?$/)[1]
60
48
 
61
- JSON.parse(response.body, symbolize_names: true)
49
+ # strip off any parens
50
+ ms = ms.match(/^(.*)(?:(\(.*\)))?$/)[1]
51
+
52
+ # deal with channel and namespace, I wish there was rsplit in ruby
53
+ split = ms.reverse.split(":", 2)
54
+ ms = split.last.reverse
55
+
56
+ # split the name from the version/build combo
57
+ matches = ms.match(/([^ =<>!~]+)?([><!=~ ].+)?/)
58
+ name = matches[1]
59
+ version_build = matches[2]
60
+
61
+ version = nil
62
+ if matches && matches[2]
63
+ version_build = matches[2]
64
+ # and now deal with getting the version from version/build
65
+ matches = version_build.match(/((?:.+?)[^><!,|]?)(?:(?<![=!|,<>~])(?:[ =])([^-=,|<>~]+?))?$/)
66
+ version = if matches
67
+ matches[1].strip
68
+ else
69
+ version_build.strip
70
+ end
71
+ end
72
+ # if it's an exact requirement, lose the =
73
+ if version&.start_with?("==")
74
+ version = version[2..]
75
+ elsif version&.start_with?("=")
76
+ version = version[1..]
77
+ end
78
+
79
+ return {
80
+ name: name,
81
+ requirement: version || "", # NOTE: this ignores build info
82
+ }
62
83
  end
63
84
  end
64
85
  end
@@ -105,7 +105,7 @@ module Bibliothecary
105
105
  end
106
106
 
107
107
  def self.parse_glide_lockfile(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
108
- manifest = YAML.load file_contents
108
+ manifest = YAML.load(file_contents, permitted_classes: [Time])
109
109
  map_dependencies(manifest, "imports", "name", "version", "runtime")
110
110
  end
111
111
 
@@ -128,25 +128,74 @@ module Bibliothecary
128
128
  end
129
129
 
130
130
  def self.parse_yarn_lock(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
131
- response = Typhoeus.post("#{Bibliothecary.configuration.yarn_parser_host}/parse", body: file_contents)
131
+ dep_hash = if file_contents.match(/__metadata:/)
132
+ parse_v2_yarn_lock(file_contents)
133
+ else
134
+ parse_v1_yarn_lock(file_contents)
135
+ end
132
136
 
133
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.yarn_parser_host}/parse", response.response_code) unless response.success?
137
+ dep_hash.map do |dep|
138
+ Dependency.new(
139
+ name: dep[:name],
140
+ requirement: dep[:version],
141
+ type: "runtime", # lockfile doesn't tell us more about the type of dep
142
+ local: dep[:requirements]&.first&.start_with?("file:"),
143
+ )
144
+ end
145
+ end
134
146
 
135
- json = JSON.parse(response.body, symbolize_names: true)
136
- json
137
- .uniq
138
- .reject do |dep|
139
- dep[:requirement]&.include?("workspace") && dep[:version].include?("use.local")
140
- end
141
- .map do |dep|
142
- Dependency.new(
143
- name: dep[:name],
144
- requirement: dep[:version],
145
- type: dep[:type],
146
- local: dep[:requirement]&.start_with?("file:"),
147
- )
148
- end
149
- end
147
+ # Returns a hash representation of the deps in yarn.lock, eg:
148
+ # [{
149
+ # name: "foo",
150
+ # requirements: [["foo", "^1.0.0"], ["foo", "^1.0.1"]],
151
+ # version: "1.2.0",
152
+ # }, ...]
153
+ def self.parse_v1_yarn_lock(contents)
154
+ contents
155
+ .gsub(/^#.*/, "")
156
+ .strip
157
+ .split("\n\n")
158
+ .map do |chunk|
159
+ requirements = chunk
160
+ .lines
161
+ .find { |l| !l.start_with?(" ") && l.strip.end_with?(":") } # first line, eg: '"@bar/foo@1.0.0", "@bar/foo@^1.0.1":'
162
+ .strip
163
+ .gsub(/"|:$/, "") # don't need quotes or trailing colon
164
+ .split(",") # split the list of requirements
165
+ .map { |d| d.strip.split(/(?<!^)@/, 2) } # split each requirement on name/version "@"", not on leading namespace "@"
166
+ version = chunk.match(/version "?([^"]*)"?/)[1]
167
+
168
+ {
169
+ name: requirements.first.first,
170
+ requirements: requirements.map { |x| x[1] },
171
+ version: version,
172
+ }
173
+ end
174
+ end
175
+
176
+ def self.parse_v2_yarn_lock(contents)
177
+ parsed = YAML.load(contents)
178
+ parsed = parsed.except("__metadata")
179
+ parsed
180
+ .reject do |packages, info|
181
+ # yarn v4+ creates a lockfile entry: "myproject@workspace" with a "use.local" version
182
+ # this lockfile entry is a reference to the project to which the lockfile belongs
183
+ # skip this self-referential package
184
+ info["version"].to_s.include?("use.local") && packages.include?("workspace")
185
+ end
186
+ .map do |packages, info|
187
+ packages = packages.split(", ")
188
+ # use first requirement's name, assuming that deps will always resolve from deps of the same name
189
+ name = packages.first.rpartition("@").first
190
+ requirements = packages.map { |p| p.rpartition("@").last.gsub(/^.*:/, "") }
191
+
192
+ {
193
+ name: name,
194
+ requirements: requirements,
195
+ version: info["version"].to_s,
196
+ }
197
+ end
198
+ end
150
199
 
151
200
  def self.parse_ls(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
152
201
  manifest = JSON.parse(file_contents)
@@ -79,14 +79,6 @@ module Bibliothecary
79
79
  parser: :parse_conda,
80
80
  kind: "manifest",
81
81
  },
82
- match_filename("environment.yml.lock") => {
83
- parser: :parse_conda,
84
- kind: "lockfile",
85
- },
86
- match_filename("environment.yaml.lock") => {
87
- parser: :parse_conda,
88
- kind: "lockfile",
89
- },
90
82
  }
91
83
  end
92
84
 
@@ -13,11 +13,8 @@ module Bibliothecary
13
13
  "conda" => :conda,
14
14
  "cran" => :cran,
15
15
  "gem" => :rubygems,
16
- "hackage" => :hackage,
17
- "hex" => :hex,
18
16
  "nuget" => :nuget,
19
17
  "pypi" => :pypi,
20
- "swift" => :swift_pm,
21
18
  }.freeze
22
19
 
23
20
 
@@ -1,3 +1,3 @@
1
1
  module Bibliothecary
2
- VERSION = "11.0.1"
2
+ VERSION = "12.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bibliothecary
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.0.1
4
+ version: 12.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-20 00:00:00.000000000 Z
11
+ date: 2025-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tomlrb
@@ -178,20 +178,6 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: vcr
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: rubocop
197
183
  requirement: !ruby/object:Gem::Requirement
@@ -265,8 +251,6 @@ files:
265
251
  - lib/bibliothecary/multi_parsers/spdx.rb
266
252
  - lib/bibliothecary/parsers/bower.rb
267
253
  - lib/bibliothecary/parsers/cargo.rb
268
- - lib/bibliothecary/parsers/carthage.rb
269
- - lib/bibliothecary/parsers/clojars.rb
270
254
  - lib/bibliothecary/parsers/cocoapods.rb
271
255
  - lib/bibliothecary/parsers/conda.rb
272
256
  - lib/bibliothecary/parsers/cpan.rb
@@ -274,9 +258,7 @@ files:
274
258
  - lib/bibliothecary/parsers/dub.rb
275
259
  - lib/bibliothecary/parsers/elm.rb
276
260
  - lib/bibliothecary/parsers/go.rb
277
- - lib/bibliothecary/parsers/hackage.rb
278
261
  - lib/bibliothecary/parsers/haxelib.rb
279
- - lib/bibliothecary/parsers/hex.rb
280
262
  - lib/bibliothecary/parsers/julia.rb
281
263
  - lib/bibliothecary/parsers/maven.rb
282
264
  - lib/bibliothecary/parsers/meteor.rb
@@ -287,7 +269,6 @@ files:
287
269
  - lib/bibliothecary/parsers/pypi.rb
288
270
  - lib/bibliothecary/parsers/rubygems.rb
289
271
  - lib/bibliothecary/parsers/shard.rb
290
- - lib/bibliothecary/parsers/swift_pm.rb
291
272
  - lib/bibliothecary/purl_util.rb
292
273
  - lib/bibliothecary/related_files_info.rb
293
274
  - lib/bibliothecary/runner.rb
@@ -1,52 +0,0 @@
1
- module Bibliothecary
2
- module Parsers
3
- class Carthage
4
- include Bibliothecary::Analyser
5
-
6
- def self.mapping
7
- {
8
- match_filename("Cartfile") => {
9
- kind: "manifest",
10
- parser: :parse_cartfile,
11
- },
12
- match_filename("Cartfile.private") => {
13
- kind: "manifest",
14
- parser: :parse_cartfile_private,
15
- },
16
- match_filename("Cartfile.resolved") => {
17
- kind: "lockfile",
18
- parser: :parse_cartfile_resolved,
19
- },
20
- }
21
- end
22
-
23
- add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
24
-
25
- def self.parse_cartfile(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
26
- map_dependencies(file_contents, "cartfile")
27
- end
28
-
29
- def self.parse_cartfile_private(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
30
- map_dependencies(file_contents, "cartfile.private")
31
- end
32
-
33
- def self.parse_cartfile_resolved(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
34
- map_dependencies(file_contents, "cartfile.resolved")
35
- end
36
-
37
- def self.map_dependencies(manifest, path)
38
- response = Typhoeus.post("#{Bibliothecary.configuration.carthage_parser_host}/#{path}", params: { body: manifest })
39
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.carthage_parser_host}/#{path}", response.response_code) unless response.success?
40
- json = JSON.parse(response.body)
41
-
42
- json.map do |dependency|
43
- Dependency.new(
44
- name: dependency["name"],
45
- requirement: dependency["version"],
46
- type: dependency["type"],
47
- )
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,38 +0,0 @@
1
- require "json"
2
- require "typhoeus"
3
-
4
- module Bibliothecary
5
- module Parsers
6
- class Clojars
7
- include Bibliothecary::Analyser
8
-
9
- def self.mapping
10
- {
11
- match_filename("project.clj") => {
12
- kind: "manifest",
13
- parser: :parse_manifest,
14
- },
15
- }
16
- end
17
-
18
- add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
19
-
20
- def self.parse_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
21
- response = Typhoeus.post("#{Bibliothecary.configuration.clojars_parser_host}/project.clj", body: file_contents)
22
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.clojars_parser_host}/project.clj", response.response_code) unless response.success?
23
- json = JSON.parse response.body
24
- index = json.index("dependencies")
25
-
26
- return [] unless index;
27
- dependencies = json[index + 1]
28
- dependencies.map do |dependency|
29
- Dependency.new(
30
- name: dependency[0],
31
- requirement: dependency[1],
32
- type: "runtime",
33
- )
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,53 +0,0 @@
1
- require "json"
2
- require "deb_control"
3
-
4
- module Bibliothecary
5
- module Parsers
6
- class Hackage
7
- include Bibliothecary::Analyser
8
-
9
- def self.mapping
10
- {
11
- match_extension(".cabal") => {
12
- kind: "manifest",
13
- parser: :parse_cabal,
14
- },
15
- match_extension("cabal.config") => {
16
- kind: "lockfile",
17
- parser: :parse_cabal_config,
18
- },
19
- }
20
- end
21
-
22
- add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
23
- add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
24
- add_multi_parser(Bibliothecary::MultiParsers::Spdx)
25
-
26
- def self.parse_cabal(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
27
- headers = {
28
- "Content-Type" => "text/plain;charset=utf-8",
29
- }
30
-
31
- response = Typhoeus.post("#{Bibliothecary.configuration.cabal_parser_host}/parse", headers: headers, body: file_contents)
32
-
33
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.cabal_parser_host}/parse", response.response_code) unless response.success?
34
- JSON
35
- .parse(response.body, symbolize_names: true)
36
- .map { |dep_kvs| Dependency.new(**dep_kvs) }
37
- end
38
-
39
- def self.parse_cabal_config(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
40
- manifest = DebControl::ControlFileBase.parse(file_contents)
41
- deps = manifest.first["constraints"].delete("\n").split(",").map(&:strip)
42
- deps.map do |dependency|
43
- dep = dependency.delete("==").split(" ")
44
- Dependency.new(
45
- name: dep[0],
46
- requirement: dep[1],
47
- type: "runtime",
48
- )
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,54 +0,0 @@
1
- require "json"
2
-
3
- module Bibliothecary
4
- module Parsers
5
- class Hex
6
- include Bibliothecary::Analyser
7
-
8
- def self.mapping
9
- {
10
- match_filename("mix.exs") => {
11
- kind: "manifest",
12
- parser: :parse_mix,
13
- },
14
- match_filename("mix.lock") => {
15
- kind: "lockfile",
16
- parser: :parse_mix_lock,
17
- },
18
- }
19
- end
20
-
21
- add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
22
- add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
23
- add_multi_parser(Bibliothecary::MultiParsers::Spdx)
24
-
25
- def self.parse_mix(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
26
- response = Typhoeus.post("#{Bibliothecary.configuration.mix_parser_host}/", body: file_contents)
27
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.mix_parser_host}/", response.response_code) unless response.success?
28
- json = JSON.parse response.body
29
-
30
- json.map do |name, version|
31
- Dependency.new(
32
- name: name,
33
- requirement: version,
34
- type: "runtime",
35
- )
36
- end
37
- end
38
-
39
- def self.parse_mix_lock(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
40
- response = Typhoeus.post("#{Bibliothecary.configuration.mix_parser_host}/lock", body: file_contents)
41
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.mix_parser_host}/", response.response_code) unless response.success?
42
- json = JSON.parse response.body
43
-
44
- json.map do |name, info|
45
- Dependency.new(
46
- name: name,
47
- requirement: info["version"],
48
- type: "runtime",
49
- )
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,35 +0,0 @@
1
- module Bibliothecary
2
- module Parsers
3
- class SwiftPM
4
- include Bibliothecary::Analyser
5
-
6
- def self.mapping
7
- {
8
- match_filename("Package.swift", case_insensitive: true) => {
9
- kind: "manifest",
10
- parser: :parse_package_swift,
11
- },
12
- }
13
- end
14
-
15
- add_multi_parser(Bibliothecary::MultiParsers::CycloneDX)
16
- add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
17
- add_multi_parser(Bibliothecary::MultiParsers::Spdx)
18
-
19
- def self.parse_package_swift(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
20
- response = Typhoeus.post("#{Bibliothecary.configuration.swift_parser_host}/to-json", body: file_contents)
21
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.swift_parser_host}/to-json", response.response_code) unless response.success?
22
- json = JSON.parse(response.body)
23
- json["dependencies"].map do |dependency|
24
- name = dependency["url"].gsub(/^https?:\/\//, "").gsub(/\.git$/,"")
25
- version = "#{dependency['version']['lowerBound']} - #{dependency['version']['upperBound']}"
26
- Dependency.new(
27
- name: name,
28
- requirement: version,
29
- type: "runtime",
30
- )
31
- end
32
- end
33
- end
34
- end
35
- end