From 630c50223814d57368cb2ff8e93bdfa26b8e3c01 Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Mon, 8 Apr 2024 15:21:16 +0200 Subject: [PATCH] fix(cargo): Do not make assumptions about the package ID for projects Instead of determining projects based on Cargo's internal package ID, use the `source` property which is `null` for local code. Fixes #8480. Signed-off-by: Sebastian Schuberth --- .../cargo/src/main/kotlin/Cargo.kt | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/plugins/package-managers/cargo/src/main/kotlin/Cargo.kt b/plugins/package-managers/cargo/src/main/kotlin/Cargo.kt index 6a265249ba318..95ea7a9b30dc6 100644 --- a/plugins/package-managers/cargo/src/main/kotlin/Cargo.kt +++ b/plugins/package-managers/cargo/src/main/kotlin/Cargo.kt @@ -127,16 +127,6 @@ class Cargo( } } - /** - * Check if a package is a project. All path dependencies inside the analyzer root are treated as project - * dependencies. - */ - private fun isProjectDependency(id: String) = - PATH_DEPENDENCY_REGEX.matchEntire(id)?.groups?.get(1)?.let { match -> - val packageDir = File(match.value) - packageDir.startsWith(analysisRoot) - } == true - override fun resolveDependencies(definitionFile: File, labels: Map): List { val workingDir = definitionFile.parentFile val metadataProcess = run(workingDir, "metadata", "--format-version=1") @@ -156,11 +146,7 @@ class Cargo( } } - val hashes = readHashes(resolveLockfile(metadata)) - val packages = metadata.packages.associateBy( - { it.id }, - { parsePackage(it, hashes) } - ) + val packageById = metadata.packages.associateBy { it.id } fun Collection.toPackageReferences(): Set = mapNotNullTo(mutableSetOf()) { node -> @@ -173,9 +159,10 @@ class Cargo( metadata.resolve.nodes.single { it.id == dep.pkg } } - val linkage = if (isProjectDependency(node.id)) PackageLinkage.PROJECT_STATIC else PackageLinkage.STATIC - packages[node.id]?.toReference( - linkage = linkage, + val pkg = packageById.getValue(node.id) + PackageReference( + id = Identifier("Crate", "", pkg.name, pkg.version), + linkage = if (pkg.isProject()) PackageLinkage.PROJECT_STATIC else PackageLinkage.STATIC, dependencies = dependencyNodes.toPackageReferences() ) } @@ -186,7 +173,10 @@ class Cargo( depNodesByKind[BUILD_KIND_NAME]?.let { Scope("build-dependencies", it.toPackageReferences()) } ) - val projectPkg = packages.getValue(projectId).let { it.copy(id = it.id.copy(type = managerName)) } + val hashes = readHashes(resolveLockfile(metadata)) + val projectPkg = packageById.getValue(projectId).let { cargoPkg -> + parsePackage(cargoPkg, hashes).let { it.copy(id = it.id.copy(type = managerName)) } + } val project = Project( id = projectPkg.id, @@ -200,15 +190,15 @@ class Cargo( scopeDependencies = scopes ) - val nonProjectPackages = packages - .filterNot { isProjectDependency(it.key) } - .mapTo(mutableSetOf()) { it.value } + val nonProjectPackages = packageById.values.mapNotNullTo(mutableSetOf()) { cargoPkg -> + cargoPkg.takeUnless { it.isProject() }?.let { parsePackage(cargoPkg, hashes) } + } return listOf(ProjectAnalyzerResult(project, nonProjectPackages)) } } -private val PATH_DEPENDENCY_REGEX = Regex("""^.*\(path\+file://(.*)\)$""") +private fun CargoMetadata.Package.isProject() = source == null private fun parseDeclaredLicenses(pkg: CargoMetadata.Package): Set { val declaredLicenses = pkg.license.orEmpty().split('/')