bibliothecary 15.1.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0467bf0dd389f6a58cd69510bd2fe2865f3d3d762732e5aac80f0348f2b785a7
4
- data.tar.gz: 0b2015f0e1d5e0c80c82c554f14b5d03fbe96c8be58a27f630eefe6e33083eda
3
+ metadata.gz: ffea645c09e3339df27b102c3a6963e34346002770c9b0d5465cf7bad8e22409
4
+ data.tar.gz: bf2414a526fb1e90f5100efb8099e8f9ecedec8e98ffe7fd7d6df183b5b03f39
5
5
  SHA512:
6
- metadata.gz: 47a1f33ff32ecb3bb8dcf4636e6b1bf4393d95b85a5a7b13c44b8438f14014e200043d45295b3c51f535acb34aa28293563584c8ce049b7af3b43955ac2f26a1
7
- data.tar.gz: 45471c05872e2ec7b29013c4eab33fb268801ccb64c6e5c3238c7f86b0e5c3daea3969f3fdacbc2109f1dab55aeadb06a78084aaef6d82ed7c85135107ebe101
6
+ metadata.gz: 54c363ec31dea80e1f74c63d3067821d9014b4c58c37f4a8aff98a86864ba1bcbc928e6158e0a2b55283139e7bf156c3a81677bcccbfdd635144c40e2a4f6b86
7
+ data.tar.gz: e05042d78d5db12d3053f2e0fe2017a5dd3395a0ac7c986c204a8f3ae4db5e911f305efd799cd5d72f19b56420fe5b760b23cbba7524c676a41fceb7494724af
data/CHANGELOG.md CHANGED
@@ -13,6 +13,18 @@ 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
+ ### Changed
19
+
20
+ - Exclude sub-projects in gradle-dependencies-q.txt unless keep_subprojects_in_maven_tree is true.
21
+ - The format of Gradle sub-project GAVs that were found in a dependency tree has changed from "internal:my-subproject:1.0.0" to ":my-subproject:*".
22
+ - Gradle dependencies in gradle-dependencies-q.txt with "(n)" suffix will be ignored in favor of their resolved dependencies, so the full dependency list could now be smaller but still correct.
23
+
24
+ ### Added
25
+
26
+ - Added support for another project name pattern in gradle-dependencies-q.txt lockfiles.
27
+
16
28
  ## [15.1.3]
17
29
 
18
30
  ### Added
@@ -20,6 +32,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
20
32
  - Start collecting "project_name" from gradle-dependencies-q.txt lockfiles.
21
33
  - Start collecting "project_name" from package.json manifests.
22
34
 
35
+ ### Changed
36
+
37
+ - Bibliothecary::Parsers::Maven's GRADLE_PROJECT_REGEXP constant was renamed to GRADLE_DEPENDENCY_PROJECT_REGEXP.
38
+
23
39
  ### Removed
24
40
 
25
41
  - Remove "go.sum" as a lockfile for Golang because it is not a lockfile.
@@ -21,12 +21,15 @@ module Bibliothecary
21
21
  # e.g. "| \\--- com.google.guava:guava:23.5-jre (*)"
22
22
  GRADLE_DEP_REGEXP = /(\+---|\\---){1}/
23
23
 
24
- GRADLE_PROJECT_REGEXP = /\s*Project '?:?([^\s']+)'?/
24
+ GRADLE_ARROW_REGEXP = / -> /
25
+
26
+ # The name of the project containing the given dependencies
27
+ GRADLE_PROJECT_REGEXP = /\s*(Root p|P)roject '?:?([^\s']+)'?/
25
28
 
26
29
  # Dependencies that are on-disk projects, eg:
27
30
  # e.g. "\--- project :api:my-internal-project"
28
31
  # e.g. "+--- my-group:my-alias:1.2.3 -> project :client (*)"
29
- GRADLE_DEPENDENCY_PROJECT_REGEXP = /project :(\S+)?/
32
+ GRADLE_DEPENDENCY_PROJECT_REGEXP = /project :?(\S+)?/
30
33
 
31
34
  # line ending legend: (c) means a dependency constraint, (n) means not resolved, or (*) means resolved previously, e.g. org.springframework.boot:spring-boot-starter-web:2.1.0.M3 (*)
32
35
  # e.g. the "(n)" in "+--- my-group:my-name:1.2.3 (n)"
@@ -192,12 +195,15 @@ module Bibliothecary
192
195
  end
193
196
 
194
197
  def self.parse_gradle_resolved(file_contents, options: {})
198
+ keep_subprojects = options.fetch(:keep_subprojects_in_maven_tree, false)
195
199
  current_type = nil
196
200
  project_name = nil
197
201
 
198
- dependencies = file_contents.split("\n").map do |line|
202
+ dependencies = file_contents.lines.filter_map do |line|
203
+ next if line.strip.end_with?("(n)") # skip unresolved or already-resolved dependencies
204
+
199
205
  if project_name.nil? && (project_name_match = GRADLE_PROJECT_REGEXP.match(line))
200
- project_name = project_name_match.captures[0]
206
+ project_name = project_name_match.captures[1]
201
207
  next
202
208
  end
203
209
 
@@ -207,66 +213,68 @@ module Bibliothecary
207
213
  gradle_dep_match = GRADLE_DEP_REGEXP.match(line)
208
214
  next unless gradle_dep_match
209
215
 
210
- split = gradle_dep_match.captures[0]
211
-
212
- # gradle can import on-disk projects and deps will be listed under them, e.g. `+--- project :test:integration`,
213
- # so we treat these projects as "internal" deps with requirement of "1.0.0"
216
+ # omit Gradle project dependencies
214
217
  if (project_match = line.match(GRADLE_DEPENDENCY_PROJECT_REGEXP))
215
- # an empty project name is self-referential (i.e. a cycle), and we don't need to track the manifest's project itself, e.g. "+--- project :"
218
+ next unless keep_subprojects
219
+
220
+ # an empty project name is self-referential (i.e. a cycle), and we don't need to track the manifest's
221
+ # project itself, e.g. "+--- project :"
216
222
  next if project_match[1].nil?
217
223
 
218
- # project names can have colons (e.g. for gradle projects in subfolders), which breaks maven artifact naming assumptions, so just replace them with hyphens.
219
- project_name = project_match[1].gsub(":", "-")
220
- line = line.sub(GRADLE_DEPENDENCY_PROJECT_REGEXP, "internal:#{project_name}:1.0.0")
224
+ sub_project_name = project_match[1]
225
+ # gradle sub-project versions cannot be specified when including them (gradle just uses whichever version is in the
226
+ # codebase), and their versions are 'unspecified' if not set, so just use a wildcard placeholder since it doesn't matter.
227
+ line = line.sub(GRADLE_DEPENDENCY_PROJECT_REGEXP, ":#{sub_project_name}:*")
221
228
  end
222
229
 
223
- dep = line
224
- .split(split)[1]
230
+ cleaned_line = line
231
+ .split(gradle_dep_match.captures[0])[1]
225
232
  .sub(GRADLE_LINE_ENDING_REGEXP, "")
226
233
  .sub(/ FAILED$/, "") # dependency could not be resolved (but still may have a version)
227
- .sub(" -> ", ":") # handle version arrow syntax
228
234
  .strip
229
- .split(":")
230
235
 
231
- # A testImplementation line can look like this so just skip those
232
- # \--- org.springframework.security:spring-security-test (n)
233
- next unless dep.length >= 3
236
+ # " -> " is either for an aliased dependency, or a version that was resolved from a different requirement or no requirement.
237
+ if cleaned_line =~ GRADLE_ARROW_REGEXP
238
+ original_depstring, resolved_depstring = *cleaned_line.split(GRADLE_ARROW_REGEXP, 2)
234
239
 
235
- if dep.count == 6
236
- # get name from renamed package resolution "org:name:version -> renamed_org:name:version"
237
- Dependency.new(
238
- original_name: dep[0, 2].join(":"),
239
- original_requirement: dep[2],
240
- name: dep[-3..-2].join(":"),
241
- requirement: dep[-1],
242
- type: current_type,
243
- source: options.fetch(:filename, nil),
244
- platform: platform_name
245
- )
246
- elsif dep.count == 5
247
- # get name from renamed package resolution "org:name -> renamed_org:name:version"
248
- Dependency.new(
249
- original_name: dep[0, 2].join(":"),
250
- original_requirement: "*",
251
- name: dep[-3..-2].join(":"),
252
- requirement: dep[-1],
253
- type: current_type,
254
- source: options.fetch(:filename, nil),
255
- platform: platform_name
256
- )
240
+ parts = original_depstring.split(":")
241
+ original_name = parts[0..1].join(":") # original at minimum will have a 2-part name
242
+ original_requirement = parts[2] || "*"
243
+
244
+ parts = resolved_depstring.split(":")
245
+ resolved_requirement = parts.pop # resolved at minimum will have a 1-part version
246
+ resolved_name = parts.join(":")
247
+
248
+ # this case is not an actual alias, just a different version was resolved, so won't keep track of original
249
+ if resolved_name.empty? && !original_name.empty?
250
+ resolved_name = original_name
251
+ original_name = nil
252
+ original_requirement = nil
253
+ end
257
254
  else
258
- # get name from version conflict resolution ("org:name:version -> version") and no-resolution ("org:name:version")
259
- Dependency.new(
260
- name: dep[0..1].join(":"),
261
- requirement: dep[-1],
262
- type: current_type,
263
- source: options.fetch(:filename, nil),
264
- platform: platform_name
265
- )
255
+ original_name = nil
256
+ original_requirement = nil
257
+
258
+ # handle simple resolved dep
259
+ parts = cleaned_line.split(":")
260
+ next if parts.size < 3 # we didn't get a full name and version, so skip it
261
+
262
+ resolved_requirement = parts.pop
263
+ resolved_name = parts.join(":")
266
264
  end
265
+
266
+ Dependency.new(
267
+ original_name: original_name,
268
+ original_requirement: original_requirement,
269
+ name: resolved_name,
270
+ requirement: resolved_requirement,
271
+ type: current_type,
272
+ source: options.fetch(:filename, nil),
273
+ platform: platform_name
274
+ )
267
275
  end
268
- .compact
269
276
  .uniq { |item| [item.name, item.requirement, item.type, item.original_name, item.original_requirement] }
277
+
270
278
  ParserResult.new(
271
279
  project_name: project_name,
272
280
  dependencies: dependencies
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bibliothecary
4
- VERSION = "15.1.3"
4
+ VERSION = "15.2.0"
5
5
  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: 15.1.3
4
+ version: 15.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: 2026-02-10 00:00:00.000000000 Z
11
+ date: 2026-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander