bibliothecary 8.0.0 → 8.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50ba5ddf48a3b7d1051272fef2bcef8ca7bca465b13e251fe9656ae8751f1353
4
- data.tar.gz: 40b88cb18308c0d624f00eedb67d1a5a946e42d2f3e242436fa376dd54b2c55a
3
+ metadata.gz: 4dfafc16f9be53462f1eca5e0fa5b09dcc0a5d92531570630c087773ff87d18c
4
+ data.tar.gz: 3d0045a95cc5cff513474aae337e0a032543130cc7b87144adad8033138c6e17
5
5
  SHA512:
6
- metadata.gz: 51675c6be455da5a996fe92f703245aac5f3a148eb65aed33bc48675e1a94677da65e3de1651d28cc511391d241e44bc774b287ff6ae2b27d7494037389f0391
7
- data.tar.gz: 74ceaa45f07deaa972be3a50e5da4e91b2507be75f6a8cf7b46cd8c02319690063e4a6f52f394fafe918debba2af765efceb13e78195de8a827997a343b8128c
6
+ metadata.gz: f984d7445345768463af5f2cb0906bf997e56ca03842ca538b65d95764ac427ed448a062593e293eeaa33779aaa2cb9b59b18f0715de813a6f018a815a03dc3f
7
+ data.tar.gz: 067f0a20d820635cd697b18c43254a818284a66b98a13367146a0f9063b63bfe9316427d32bf6b88d960f6283dd56adb4ad2f874c003c7e4c151d71181f3cd37
@@ -39,8 +39,13 @@ module Bibliothecary
39
39
 
40
40
  attr_reader :manifests
41
41
 
42
- def initialize
42
+ def initialize(parse_queue:)
43
43
  @manifests = {}
44
+
45
+ # Instead of recursing, we'll work through a queue of components
46
+ # to process, letting the different parser add components to the
47
+ # queue however they need to pull them from the source document.
48
+ @parse_queue = parse_queue.dup
44
49
  end
45
50
 
46
51
  def <<(purl)
@@ -55,6 +60,23 @@ module Bibliothecary
55
60
  }
56
61
  end
57
62
 
63
+ # Iterates over each manifest entry in the parse_queue, and accepts a block which will
64
+ # be called on each component. The block has two jobs: 1) add more sub-components
65
+ # to parse (if they exist), and 2) return the components purl.
66
+ def parse!(&block)
67
+ while @parse_queue.length > 0
68
+ component = @parse_queue.shift
69
+
70
+ purl_text = block.call(component, @parse_queue)
71
+
72
+ next unless purl_text
73
+
74
+ purl = PackageURL.parse(purl_text)
75
+
76
+ self << purl
77
+ end
78
+ end
79
+
58
80
  def [](key)
59
81
  @manifests[key]&.to_a
60
82
  end
@@ -94,14 +116,12 @@ module Bibliothecary
94
116
 
95
117
  raise NoComponents unless manifest["components"]
96
118
 
97
- entries = ManifestEntries.new
98
-
99
- manifest["components"].each_with_object(entries) do |component, obj|
100
- next unless component["purl"]
119
+ entries = ManifestEntries.new(parse_queue: manifest["components"])
101
120
 
102
- purl = PackageURL.parse(component["purl"])
121
+ entries.parse! do |component, parse_queue|
122
+ parse_queue.concat(component["components"]) if component["components"]
103
123
 
104
- obj << purl
124
+ component["purl"]
105
125
  end
106
126
 
107
127
  entries[platform_name.to_sym]
@@ -119,16 +139,14 @@ module Bibliothecary
119
139
 
120
140
  raise NoComponents unless root.locate('components').first
121
141
 
122
- entries = ManifestEntries.new
123
-
124
- root.locate('components/*').each_with_object(entries) do |component, obj|
125
- purl_node = component.locate("purl").first
126
-
127
- next unless purl_node
142
+ entries = ManifestEntries.new(parse_queue: root.locate('components/*'))
128
143
 
129
- purl = PackageURL.parse(purl_node.text)
144
+ entries.parse! do |component, parse_queue|
145
+ # #locate returns an empty array if nothing is found, so we can
146
+ # always safely concatenate it to the parse queue.
147
+ parse_queue.concat(component.locate('components/*'))
130
148
 
131
- obj << purl
149
+ component.locate("purl").first&.text
132
150
  end
133
151
 
134
152
  entries[platform_name.to_sym]
@@ -12,6 +12,17 @@ module Bibliothecary
12
12
  # "| \\--- com.google.guava:guava:23.5-jre (*)"
13
13
  GRADLE_DEP_REGEX = /(\+---|\\---){1}/
14
14
 
15
+ # Builtin methods: https://docs.gradle.org/current/userguide/java_plugin.html#tab:configurations
16
+ GRADLE_KTS_DEPENDENCY_METHODS = %w(api compile compileOnlyApi implementation runtimeOnly testCompileOnly testImplementation testRuntimeOnly)
17
+
18
+ # An intentionally overly-simplified regex to scrape deps from build.gradle.kts files.
19
+ # To be truly useful bibliothecary would need a full Kotlin parser that speaks Gradle,
20
+ # because the Kotlin DSL has many dynamic ways of declaring dependencies.
21
+ GRADLE_KTS_SIMPLE_REGEX = /(#{GRADLE_KTS_DEPENDENCY_METHODS.join('|')})\s*\(\s*"([^"]+)"\s*\)/m
22
+
23
+ # e.g. "group:artifactId:1.2.3"
24
+ GRADLE_KTS_GAV_REGEX = /([\w.-]+)\:([\w.-]+)(?:\:([\w.-]+))?/
25
+
15
26
  MAVEN_PROPERTY_REGEX = /\$\{(.+?)\}/
16
27
  MAX_DEPTH = 5
17
28
 
@@ -236,8 +247,17 @@ module Bibliothecary
236
247
  end
237
248
 
238
249
  def self.parse_gradle_kts(file_contents, options: {})
239
- # TODO: the gradle-parser side needs to be implemented for this, coming soon.
240
- []
250
+ file_contents
251
+ .scan(GRADLE_KTS_SIMPLE_REGEX) # match 'implementation("group:artifactId:version")'
252
+ .map { |(_type, dep_match)| GRADLE_KTS_GAV_REGEX.match(dep_match) } # extract ["group", "artifactId", ?"version"]
253
+ .reject { |gav_match| gav_match.nil? || gav_match[1].nil? || gav_match[2].nil? } # remove any with missing group/artifactId
254
+ .map { |gav_match|
255
+ {
256
+ name: [gav_match[1], gav_match[2]].join(":"),
257
+ requirement: gav_match[3] || "*",
258
+ type: nil # TODO: we may be able to infer dep types using the _type var above.
259
+ }
260
+ }
241
261
  end
242
262
 
243
263
  def self.gradle_dependency_name(group, name)
@@ -1,3 +1,3 @@
1
1
  module Bibliothecary
2
- VERSION = "8.0.0"
2
+ VERSION = "8.2.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: 8.0.0
4
+ version: 8.2.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: 2022-04-25 00:00:00.000000000 Z
11
+ date: 2022-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tomlrb