Skip to content

Commit 45ef6fe

Browse files
ruromeroclaude
andcommitted
fix: remove scope qualifier from Maven/Gradle provider purls
Purls no longer contain ?scope=compile or ?scope=provided qualifiers, aligning with the JS client. Test-scope filtering now uses DependencyAggregator.isTestDependency() instead of reading from purl qualifiers. CycloneDX component scope is still set via addDependency(). Implements TC-3920 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c77e471 commit 45ef6fe

37 files changed

Lines changed: 2497 additions & 2513 deletions

File tree

src/main/java/io/github/guacsec/trustifyda/providers/BaseJavaProvider.java

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
import io.github.guacsec.trustifyda.tools.Ecosystem;
2424
import java.nio.file.Path;
2525
import java.util.Arrays;
26-
import java.util.Map;
2726
import java.util.Objects;
28-
import java.util.TreeMap;
2927

3028
public abstract class BaseJavaProvider extends Provider {
3129

@@ -45,10 +43,10 @@ void parseDependencyTree(String src, int srcDepth, String[] lines, Sbom sbom, St
4543
int targetDepth = getDepth(target);
4644
while (targetDepth > srcDepth && index < lines.length) {
4745
if (targetDepth == srcDepth + 1) {
48-
PackageURL from = parseDep(src);
49-
PackageURL to = parseDep(target);
50-
if (dependencyIsNotTestScope(from) && dependencyIsNotTestScope(to)) {
51-
sbom.addDependency(from, to, scope);
46+
DependencyAggregator fromAgg = parseDep(src);
47+
DependencyAggregator toAgg = parseDep(target);
48+
if (!fromAgg.isTestDependency() && !toAgg.isTestDependency()) {
49+
sbom.addDependency(fromAgg.toPurl(), toAgg.toPurl(), scope);
5250
}
5351
} else {
5452
String[] modifiedLines = Arrays.copyOfRange(lines, index, lines.length);
@@ -64,13 +62,11 @@ void parseDependencyTree(String src, int srcDepth, String[] lines, Sbom sbom, St
6462
}
6563
}
6664

67-
static boolean dependencyIsNotTestScope(PackageURL artifact) {
68-
return (Objects.nonNull(artifact.getQualifiers())
69-
&& !artifact.getQualifiers().get("scope").equals("test"))
70-
|| Objects.isNull(artifact.getQualifiers());
65+
static boolean dependencyIsNotTestScope(DependencyAggregator dep) {
66+
return !dep.isTestDependency();
7167
}
7268

73-
PackageURL parseDep(String dep) {
69+
DependencyAggregator parseDep(String dep) {
7470
// root package
7571
DependencyAggregator dependencyAggregator = new DependencyAggregator();
7672
// in case line in dependency tree text starts with a letter ( for root artifact).
@@ -81,7 +77,7 @@ PackageURL parseDep(String dep) {
8177
dependencyAggregator.artifactId = parts[1];
8278
dependencyAggregator.version = parts[3];
8379

84-
return dependencyAggregator.toPurl();
80+
return dependencyAggregator;
8581
}
8682
int firstDash = dep.indexOf("-");
8783
String dependency = dep.substring(++firstDash).trim();
@@ -137,7 +133,7 @@ else if (parts.length == 6) {
137133
Integer.min(parts[parts.length - 1].indexOf(""), parts[parts.length - 1].indexOf("-"));
138134
dependencyAggregator.scope = parts[parts.length - 1].substring(0, endOfLine).trim();
139135
}
140-
return dependencyAggregator.toPurl();
136+
return dependencyAggregator;
141137
}
142138

143139
int getDepth(String line) {
@@ -185,12 +181,7 @@ boolean isTestDependency() {
185181
PackageURL toPurl() {
186182
try {
187183
return new PackageURL(
188-
Ecosystem.Type.MAVEN.getType(),
189-
groupId,
190-
artifactId,
191-
version,
192-
this.scope.equals("*") ? null : new TreeMap<>(Map.of("scope", this.scope)),
193-
null);
184+
Ecosystem.Type.MAVEN.getType(), groupId, artifactId, version, null, null);
194185
} catch (MalformedPackageURLException e) {
195186
throw new IllegalArgumentException("Unable to parse PackageURL", e);
196187
}

src/main/java/io/github/guacsec/trustifyda/providers/GradleProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ private Sbom buildSbomFromTextFormat(
307307
Sbom sbom = SbomFactory.newInstance(Sbom.BelongingCondition.PURL, "sensitive");
308308
String root = getRoot(textFormatFile, propertiesMap);
309309

310-
PackageURL rootPurl = parseDep(root);
310+
PackageURL rootPurl = parseDep(root).toPurl();
311311
sbom.addRoot(rootPurl, readLicenseFromManifest());
312312

313313
List<String> runtimeConfig = extractLines(textFormatFile, RUNTIME_CLASSPATH);

src/main/java/io/github/guacsec/trustifyda/providers/JavaMavenProvider.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import java.util.List;
4141
import java.util.Map;
4242
import java.util.Objects;
43-
import java.util.TreeMap;
4443
import java.util.logging.Level;
4544
import java.util.logging.Logger;
4645
import java.util.stream.Collectors;
@@ -179,7 +178,7 @@ private Sbom buildSbomFromTextFormat(Path textFormatFile) throws IOException {
179178
sbom.setCoordinateBasedMatching();
180179
List<String> lines = Files.readAllLines(textFormatFile);
181180
var root = lines.get(0);
182-
var rootPurl = parseDep(root);
181+
var rootPurl = parseDep(root).toPurl();
183182
sbom.addRoot(rootPurl, readLicenseFromManifest());
184183
lines.remove(0);
185184
String[] array = new String[lines.size()];
@@ -463,13 +462,7 @@ public boolean isTestDependency() {
463462

464463
public PackageURL toPurl() {
465464
try {
466-
return new PackageURL(
467-
Type.MAVEN.getType(),
468-
groupId,
469-
artifactId,
470-
version,
471-
this.scope.equals("*") ? null : new TreeMap<>(Map.of("scope", this.scope)),
472-
null);
465+
return new PackageURL(Type.MAVEN.getType(), groupId, artifactId, version, null, null);
473466
} catch (MalformedPackageURLException e) {
474467
throw new IllegalArgumentException("Unable to parse PackageURL", e);
475468
}

src/test/resources/tst_manifests/gradle-groovy/deps_with_duplicate_different_versions/expected_component_sbom.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"name" : "log4j",
3030
"version" : "1.2.17",
3131
"scope":"required",
32-
"purl" : "pkg:maven/log4j/log4j@1.2.17?scope=compile"
32+
"purl" : "pkg:maven/log4j/log4j@1.2.17"
3333
}
3434
],
3535
"dependencies" : [

src/test/resources/tst_manifests/gradle-groovy/deps_with_duplicate_different_versions/expected_stack_sbom.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"name" : "log4j",
3030
"version" : "1.2.17",
3131
"scope":"required",
32-
"purl" : "pkg:maven/log4j/log4j@1.2.17?scope=compile"
32+
"purl" : "pkg:maven/log4j/log4j@1.2.17"
3333
}
3434
],
3535
"dependencies" : [

src/test/resources/tst_manifests/gradle-groovy/deps_with_duplicate_no_version/expected_component_sbom.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"name" : "log4j",
3030
"version" : "1.2.17",
3131
"scope":"required",
32-
"purl" : "pkg:maven/log4j/log4j@1.2.17?scope=compile"
32+
"purl" : "pkg:maven/log4j/log4j@1.2.17"
3333
}
3434
],
3535
"dependencies" : [

src/test/resources/tst_manifests/gradle-groovy/deps_with_duplicate_no_version/expected_stack_sbom.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"name" : "log4j",
3030
"version" : "1.2.17",
3131
"scope":"required",
32-
"purl" : "pkg:maven/log4j/log4j@1.2.17?scope=compile"
32+
"purl" : "pkg:maven/log4j/log4j@1.2.17"
3333
}
3434
],
3535
"dependencies" : [

src/test/resources/tst_manifests/gradle-groovy/deps_with_ignore_full_specification/expected_component_sbom.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"name" : "quarkus-hibernate-orm",
2929
"version" : "2.13.5.Final",
3030
"scope" : "required",
31-
"purl" : "pkg:maven/io.quarkus/quarkus-hibernate-orm@2.13.5.Final?scope=compile"
31+
"purl" : "pkg:maven/io.quarkus/quarkus-hibernate-orm@2.13.5.Final"
3232
},
3333
{
3434
"type" : "library",
@@ -37,7 +37,7 @@
3737
"name" : "quarkus-agroal",
3838
"version" : "2.13.5.Final",
3939
"scope" : "required",
40-
"purl" : "pkg:maven/io.quarkus/quarkus-agroal@2.13.5.Final?scope=compile"
40+
"purl" : "pkg:maven/io.quarkus/quarkus-agroal@2.13.5.Final"
4141
},
4242
{
4343
"type" : "library",
@@ -46,7 +46,7 @@
4646
"name" : "quarkus-resteasy",
4747
"version" : "2.13.7.Final",
4848
"scope" : "required",
49-
"purl" : "pkg:maven/io.quarkus/quarkus-resteasy@2.13.7.Final?scope=compile"
49+
"purl" : "pkg:maven/io.quarkus/quarkus-resteasy@2.13.7.Final"
5050
},
5151
{
5252
"type" : "library",
@@ -55,7 +55,7 @@
5555
"name" : "quarkus-resteasy-jackson",
5656
"version" : "2.13.5.Final",
5757
"scope" : "required",
58-
"purl" : "pkg:maven/io.quarkus/quarkus-resteasy-jackson@2.13.5.Final?scope=compile"
58+
"purl" : "pkg:maven/io.quarkus/quarkus-resteasy-jackson@2.13.5.Final"
5959
},
6060
{
6161
"type" : "library",
@@ -64,7 +64,7 @@
6464
"name" : "quarkus-jdbc-postgresql",
6565
"version" : "2.13.5.Final",
6666
"scope" : "required",
67-
"purl" : "pkg:maven/io.quarkus/quarkus-jdbc-postgresql@2.13.5.Final?scope=compile"
67+
"purl" : "pkg:maven/io.quarkus/quarkus-jdbc-postgresql@2.13.5.Final"
6868
},
6969
{
7070
"type" : "library",
@@ -73,7 +73,7 @@
7373
"name" : "quarkus-vertx-http",
7474
"version" : "2.13.7.Final",
7575
"scope" : "required",
76-
"purl" : "pkg:maven/io.quarkus/quarkus-vertx-http@2.13.7.Final?scope=compile"
76+
"purl" : "pkg:maven/io.quarkus/quarkus-vertx-http@2.13.7.Final"
7777
},
7878
{
7979
"type" : "library",
@@ -82,7 +82,7 @@
8282
"name" : "quarkus-kubernetes-service-binding",
8383
"version" : "2.13.5.Final",
8484
"scope" : "required",
85-
"purl" : "pkg:maven/io.quarkus/quarkus-kubernetes-service-binding@2.13.5.Final?scope=compile"
85+
"purl" : "pkg:maven/io.quarkus/quarkus-kubernetes-service-binding@2.13.5.Final"
8686
},
8787
{
8888
"type" : "library",
@@ -91,7 +91,7 @@
9191
"name" : "quarkus-container-image-docker",
9292
"version" : "2.13.5.Final",
9393
"scope" : "required",
94-
"purl" : "pkg:maven/io.quarkus/quarkus-container-image-docker@2.13.5.Final?scope=compile"
94+
"purl" : "pkg:maven/io.quarkus/quarkus-container-image-docker@2.13.5.Final"
9595
},
9696
{
9797
"type" : "library",
@@ -100,7 +100,7 @@
100100
"name" : "jakarta.validation-api",
101101
"version" : "2.0.2",
102102
"scope" : "required",
103-
"purl" : "pkg:maven/jakarta.validation/jakarta.validation-api@2.0.2?scope=compile"
103+
"purl" : "pkg:maven/jakarta.validation/jakarta.validation-api@2.0.2"
104104
},
105105
{
106106
"type" : "library",
@@ -109,7 +109,7 @@
109109
"name" : "quarkus-resteasy-multipart",
110110
"version" : "2.13.7.Final",
111111
"scope" : "required",
112-
"purl" : "pkg:maven/io.quarkus/quarkus-resteasy-multipart@2.13.7.Final?scope=compile"
112+
"purl" : "pkg:maven/io.quarkus/quarkus-resteasy-multipart@2.13.7.Final"
113113
},
114114
{
115115
"type" : "library",
@@ -118,7 +118,7 @@
118118
"name" : "quarkus-hibernate-orm-deployment",
119119
"version" : "2.0.2.Final",
120120
"scope" : "required",
121-
"purl" : "pkg:maven/io.quarkus/quarkus-hibernate-orm-deployment@2.0.2.Final?scope=compile"
121+
"purl" : "pkg:maven/io.quarkus/quarkus-hibernate-orm-deployment@2.0.2.Final"
122122
}
123123
],
124124
"dependencies" : [

0 commit comments

Comments
 (0)