|
46 | 46 | import java.util.HashSet; |
47 | 47 | import java.util.Map; |
48 | 48 | import java.util.Set; |
| 49 | +import java.util.TreeMap; |
49 | 50 | import java.util.concurrent.ExecutionException; |
50 | 51 | import java.util.concurrent.ExecutorService; |
51 | 52 | import java.util.concurrent.Executors; |
@@ -285,8 +286,7 @@ void processWorkspaceDependencies( |
285 | 286 | CargoPackage depPackage = findPackageByName(packageMap, depName); |
286 | 287 | try { |
287 | 288 | PackageURL depUrl = |
288 | | - new PackageURL( |
289 | | - Type.CARGO.getType(), null, depPackage.name(), depPackage.version(), null, null); |
| 289 | + createCargoPurl(depPackage.name(), depPackage.version(), depPackage.isPathDependency()); |
290 | 290 | sbom.addDependency(root, depUrl, null); |
291 | 291 | } catch (Exception e) { |
292 | 292 | log.warning("Failed to create PackageURL for workspace dependency: " + depName); |
@@ -332,8 +332,7 @@ private void processWorkspaceMember( |
332 | 332 |
|
333 | 333 | try { |
334 | 334 | PackageURL memberUrl = |
335 | | - new PackageURL( |
336 | | - Type.CARGO.getType(), null, memberPkg.name(), memberPkg.version(), null, null); |
| 335 | + createCargoPurl(memberPkg.name(), memberPkg.version(), memberPkg.isPathDependency()); |
337 | 336 | sbom.addDependency(workspaceRoot, memberUrl, null); |
338 | 337 |
|
339 | 338 | if (debugLoggingIsNeeded()) { |
@@ -528,8 +527,7 @@ private void processDirectDependencies( |
528 | 527 |
|
529 | 528 | try { |
530 | 529 | PackageURL packageUrl = |
531 | | - new PackageURL( |
532 | | - Type.CARGO.getType(), null, childInfo.name(), childInfo.version(), null, null); |
| 530 | + createCargoPurl(childInfo.name(), childInfo.version(), childInfo.isPathDependency()); |
533 | 531 | sbom.addDependency(sourceUrl, packageUrl, null); |
534 | 532 | if (debugLoggingIsNeeded()) { |
535 | 533 | log.info( |
@@ -594,8 +592,7 @@ private void processDependencyNode( |
594 | 592 |
|
595 | 593 | try { |
596 | 594 | PackageURL childUrl = |
597 | | - new PackageURL( |
598 | | - Type.CARGO.getType(), null, childInfo.name(), childInfo.version(), null, null); |
| 595 | + createCargoPurl(childInfo.name(), childInfo.version(), childInfo.isPathDependency()); |
599 | 596 |
|
600 | 597 | String relationshipKey = parent.getCoordinates() + "->" + childUrl.getCoordinates(); |
601 | 598 |
|
@@ -641,7 +638,7 @@ private Map<String, CargoPackage> buildPackageMap(CargoMetadata metadata) { |
641 | 638 |
|
642 | 639 | private DependencyInfo getPackageInfo(String packageId, Map<String, CargoPackage> packageMap) { |
643 | 640 | CargoPackage pkg = packageMap.get(packageId); |
644 | | - return new DependencyInfo(pkg.name(), pkg.version()); |
| 641 | + return new DependencyInfo(pkg.name(), pkg.version(), pkg.source()); |
645 | 642 | } |
646 | 643 |
|
647 | 644 | public CargoProvider(Path manifest) { |
@@ -821,4 +818,16 @@ private boolean lineContainsDependency(String trimmed, String depName) { |
821 | 818 | } |
822 | 819 | return false; |
823 | 820 | } |
| 821 | + |
| 822 | + /** |
| 823 | + * Creates a {@link PackageURL} for a Cargo package. Path dependencies ({@code source == null}) |
| 824 | + * get a {@code repository_url=local} qualifier so the backend can distinguish them from registry |
| 825 | + * packages and skip vulnerability checks. |
| 826 | + */ |
| 827 | + private static PackageURL createCargoPurl(String name, String version, boolean isPathDep) |
| 828 | + throws Exception { |
| 829 | + TreeMap<String, String> qualifiers = |
| 830 | + isPathDep ? new TreeMap<>(Map.of("repository_url", "local")) : null; |
| 831 | + return new PackageURL(Type.CARGO.getType(), null, name, version, qualifiers, null); |
| 832 | + } |
824 | 833 | } |
0 commit comments