From a02aa1b07254ec6fa06183f9d68e79bb97208a19 Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Wed, 3 Jun 2026 16:13:21 +0200 Subject: [PATCH 1/6] chore(gradle-plugin): Move `resolvePoms()` out of the class The class context is not used. Signed-off-by: Frank Viernau --- .../src/main/kotlin/OrtModelBuilder.kt | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt index 649c5d3382dc4..e1e7806db69dd 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt @@ -103,47 +103,6 @@ internal class OrtModelBuilder : ToolingModelBuilder { ) } - /** - * Resolve the POM files for all dependences in the given [Gradle configuration][config] incl. their parent POMs. - */ - private fun Project.resolvePoms(config: Configuration): Map { - val allComponentIds = config.incoming.resolutionResult.allDependencies - .filterIsInstance() - .map { it.selected.id } - .distinct() - - // Get the POM files for all resolved dependencies. - val pomFiles = resolvePoms(allComponentIds) - - val fileModelBuilder = FileModelBuilder { groupId, artifactId, version -> - val moduleId = DefaultModuleIdentifier.newId(groupId, artifactId) - val componentId = DefaultModuleComponentIdentifier.newId(moduleId, version) - - val pomFile = resolvePoms(listOf(componentId)).single().file - - FileModelSource(pomFile) - } - - return pomFiles.associate { - // Trigger resolution of parent POMs by building the POM model. - it.id.componentIdentifier.toString() to fileModelBuilder.buildModel(it.file) - } - } - - /** - * Resolve the POM files for the given [componentIds] and return them. - */ - private fun Project.resolvePoms(componentIds: List): List { - val resolutionResult = dependencies.createArtifactResolutionQuery() - .forComponents(componentIds) - .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java) - .execute() - - return resolutionResult.resolvedComponents.flatMap { - it.getArtifacts(MavenPomArtifact::class.java) - }.filterIsInstance() - } - private fun Collection.toOrtDependencies( poms: Map, visited: Set @@ -316,6 +275,47 @@ internal class OrtModelBuilder : ToolingModelBuilder { } } +/** + * Resolve the POM files for all dependences in the given [Gradle configuration][config] incl. their parent POMs. + */ +private fun Project.resolvePoms(config: Configuration): Map { + val allComponentIds = config.incoming.resolutionResult.allDependencies + .filterIsInstance() + .map { it.selected.id } + .distinct() + + // Get the POM files for all resolved dependencies. + val pomFiles = resolvePoms(allComponentIds) + + val fileModelBuilder = FileModelBuilder { groupId, artifactId, version -> + val moduleId = DefaultModuleIdentifier.newId(groupId, artifactId) + val componentId = DefaultModuleComponentIdentifier.newId(moduleId, version) + + val pomFile = resolvePoms(listOf(componentId)).single().file + + FileModelSource(pomFile) + } + + return pomFiles.associate { + // Trigger resolution of parent POMs by building the POM model. + it.id.componentIdentifier.toString() to fileModelBuilder.buildModel(it.file) + } +} + +/** + * Resolve the POM files for the given [componentIds] and return them. + */ +private fun Project.resolvePoms(componentIds: List): List { + val resolutionResult = dependencies.createArtifactResolutionQuery() + .forComponents(componentIds) + .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java) + .execute() + + return resolutionResult.resolvedComponents.flatMap { + it.getArtifacts(MavenPomArtifact::class.java) + }.filterIsInstance() +} + /** * Add a string with information about the causes of the given [exception] to this [StringBuilder]. This is used to * log the reason why a dependency could not be resolved. To get meaningful information, all causes need to be obtained From 5395e7c8edd4c29826566dbf84d4baaf8443c4b5 Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Wed, 3 Jun 2026 16:23:33 +0200 Subject: [PATCH 2/6] refactor(gradle-plugin): Move a `distinct()` downwards in call tree Be on the safe side to not create a request with duplicate component IDs. Signed-off-by: Frank Viernau --- .../gradle-plugin/src/main/kotlin/OrtModelBuilder.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt index e1e7806db69dd..a672d75728b0c 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt @@ -282,7 +282,6 @@ private fun Project.resolvePoms(config: Configuration): Map() .map { it.selected.id } - .distinct() // Get the POM files for all resolved dependencies. val pomFiles = resolvePoms(allComponentIds) @@ -307,7 +306,7 @@ private fun Project.resolvePoms(config: Configuration): Map): List { val resolutionResult = dependencies.createArtifactResolutionQuery() - .forComponents(componentIds) + .forComponents(componentIds.distinct()) .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java) .execute() From 72d3aed40a4e831c0df3c3ac2e639644beb3740f Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Wed, 3 Jun 2026 16:25:31 +0200 Subject: [PATCH 3/6] chore(gradle-plugin): Trivially simplify obtaining all components The previously used function [2] returns items which are either resolved components or unresolved components, while `getAllComponents()` returns exactly the resolved ones. Make use of the latter, to avoid the need to filter. [1]: https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/result/ResolutionResult.html#getAllComponents() [2]: https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/result/ResolutionResult.html#getAllDependencies() Signed-off-by: Frank Viernau --- .../gradle-plugin/src/main/kotlin/OrtModelBuilder.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt index a672d75728b0c..bd8facabd054f 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt @@ -279,9 +279,7 @@ internal class OrtModelBuilder : ToolingModelBuilder { * Resolve the POM files for all dependences in the given [Gradle configuration][config] incl. their parent POMs. */ private fun Project.resolvePoms(config: Configuration): Map { - val allComponentIds = config.incoming.resolutionResult.allDependencies - .filterIsInstance() - .map { it.selected.id } + val allComponentIds = config.incoming.resolutionResult.allComponents.map { it.id } // Get the POM files for all resolved dependencies. val pomFiles = resolvePoms(allComponentIds) From 26ff5491796422bb2048f5bbf106ef54ad24a69c Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Wed, 3 Jun 2026 16:46:46 +0200 Subject: [PATCH 4/6] refactor(gradle-model): Rename `OrtDependency` to `OrtComponent` Align with the naming used in the Gradle API and prepare for factoring out an `OrtComponentIdentifier`. Signed-off-by: Frank Viernau --- .../main/kotlin/GradleDependencyHandler.kt | 20 +++---- .../src/main/kotlin/Extensions.kt | 6 +- .../src/main/kotlin/GradleModel.kt | 6 +- .../src/main/kotlin/OrtModelBuilder.kt | 36 +++++------ .../src/main/kotlin/OrtModelImpl.kt | 10 ++-- .../main/kotlin/GradleDependencyHandler.kt | 14 ++--- .../gradle/src/main/resources/init.gradle | 60 +++++++++---------- .../kotlin/GradleDependencyHandlerTest.kt | 18 +++--- 8 files changed, 85 insertions(+), 85 deletions(-) diff --git a/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt b/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt index 92919e979c39a..7f5dfc371d929 100644 --- a/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt +++ b/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt @@ -19,7 +19,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradleinspector -import OrtDependency +import OrtComponent import java.lang.invoke.MethodHandles @@ -58,16 +58,16 @@ import org.ossreviewtoolkit.utils.spdxexpression.SpdxOperator internal class GradleDependencyHandler( /** The type of projects to handle. */ private val projectType: String -) : DependencyHandler { - override fun identifierFor(dependency: OrtDependency): Identifier = +) : DependencyHandler { + override fun identifierFor(dependency: OrtComponent): Identifier = with(dependency) { Identifier(getIdentifierType(projectType), groupId, artifactId, version) } - override fun dependenciesFor(dependency: OrtDependency): List = dependency.dependencies + override fun dependenciesFor(dependency: OrtComponent): List = dependency.dependencies - override fun linkageFor(dependency: OrtDependency): PackageLinkage = + override fun linkageFor(dependency: OrtComponent): PackageLinkage = if (dependency.isProjectDependency) PackageLinkage.PROJECT_DYNAMIC else PackageLinkage.DYNAMIC - override fun createPackage(dependency: OrtDependency, issues: MutableCollection): Package? { + override fun createPackage(dependency: OrtComponent, issues: MutableCollection): Package? { // Only look for a package if there was no error resolving the dependency and it is no project dependency. if (dependency.error != null || dependency.isProjectDependency) return null @@ -136,7 +136,7 @@ internal class GradleDependencyHandler( ) } - override fun areDependenciesEqual(dependenciesA: List, dependenciesB: List): Boolean { + override fun areDependenciesEqual(dependenciesA: List, dependenciesB: List): Boolean { if (dependenciesA === dependenciesB) return true if (dependenciesA.isEmpty() && dependenciesB.isEmpty()) return true @@ -167,7 +167,7 @@ private val USER_HOST_REGEX = Regex("scm:(?[^:@]+)@(?[^:]+)[:/](? @@ -178,7 +178,7 @@ private fun OrtDependency.toVcsInfo(): VcsInfo = } ?: handleInvalidScmInfo(connection, tag) }.orEmpty() -private fun OrtDependency.handleValidScmInfo(type: String, url: String, tag: String): VcsInfo = +private fun OrtComponent.handleValidScmInfo(type: String, url: String, tag: String): VcsInfo = when { // Maven does not officially support git-repo as an SCM, see http://maven.apache.org/scm/scms-overview.html, so // come up with the convention to use the "manifest" query parameter for the path to the manifest inside the @@ -229,7 +229,7 @@ private fun OrtDependency.handleValidScmInfo(type: String, url: String, tag: Str } } -private fun OrtDependency.handleInvalidScmInfo(connection: String, tag: String): VcsInfo = +private fun OrtComponent.handleInvalidScmInfo(connection: String, tag: String): VcsInfo = @Suppress("UnsafeCallOnNullableType") USER_HOST_REGEX.matchEntire(connection)?.let { match -> // Some projects omit the provider and use the SCP-like Git URL syntax, for example diff --git a/plugins/package-managers/gradle-model/src/main/kotlin/Extensions.kt b/plugins/package-managers/gradle-model/src/main/kotlin/Extensions.kt index 43320120274ea..0ffc69c997843 100644 --- a/plugins/package-managers/gradle-model/src/main/kotlin/Extensions.kt +++ b/plugins/package-managers/gradle-model/src/main/kotlin/Extensions.kt @@ -19,13 +19,13 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradlemodel -import OrtDependency +import OrtComponent /** * The type of this Gradle dependency. In case of a project, it is [projectType]. Otherwise it is "Maven" unless there * is no POM, then it is "Unknown". */ -fun OrtDependency.getIdentifierType(projectType: String) = +fun OrtComponent.getIdentifierType(projectType: String) = when { isProjectDependency -> projectType pomFile != null -> "Maven" @@ -35,5 +35,5 @@ fun OrtDependency.getIdentifierType(projectType: String) = /** * A flag to indicate whether this Gradle dependency refers to a project, or to a package. */ -val OrtDependency.isProjectDependency: Boolean +val OrtComponent.isProjectDependency: Boolean get() = localPath != null diff --git a/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt b/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt index 55d61d8259fbc..5ed08d6074db4 100644 --- a/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt +++ b/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt @@ -34,17 +34,17 @@ interface OrtDependencyTreeModel { interface OrtConfiguration { val name: String - val dependencies: List + val dependencies: List } -interface OrtDependency { +interface OrtComponent { val groupId: String val artifactId: String val version: String val classifier: String val extension: String val variants: Map> - val dependencies: List + val dependencies: List val error: String? val warning: String? val pomFile: String? diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt index bd8facabd054f..287b08c675809 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt @@ -19,7 +19,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradleplugin -import OrtDependency +import OrtComponent import OrtDependencyTreeModel import org.apache.maven.model.building.FileModelSource @@ -54,10 +54,10 @@ internal class OrtModelBuilder : ToolingModelBuilder { private val logger = Logging.getLogger(OrtModelBuilder::class.java) private val errors = mutableListOf() private val warnings = mutableListOf() - private val globalDependencySubtrees = mutableMapOf>() + private val globalDependencySubtrees = mutableMapOf>() - // Only create one "OrtDependency" for each "ResolvedComponentResult". - private val ortDependencyCache = mutableMapOf() + // Only create one "OrtComponent" for each "ResolvedComponentResult". + private val ortComponentCache = mutableMapOf() override fun canBuild(modelName: String): Boolean = modelName == OrtDependencyTreeModel::class.java.name @@ -88,7 +88,7 @@ internal class OrtModelBuilder : ToolingModelBuilder { // Omit configurations without dependencies. root.dependencies.takeUnless { it.isEmpty() }?.let { dep -> - OrtConfigurationImpl(name = config.name, dependencies = dep.toOrtDependencies(poms, emptySet())) + OrtConfigurationImpl(name = config.name, dependencies = dep.toOrtComponents(poms, emptySet())) } } @@ -103,22 +103,22 @@ internal class OrtModelBuilder : ToolingModelBuilder { ) } - private fun Collection.toOrtDependencies( + private fun Collection.toOrtComponents( poms: Map, visited: Set - ): List = + ): List = if (GradleVersion.current() < GradleVersion.version("5.1")) { this } else { filterNot { it.isConstraint } }.mapNotNull { - it.toOrtDependency(poms, visited) + it.toOrtComponent(poms, visited) } - private fun DependencyResult.toOrtDependency( + private fun DependencyResult.toOrtComponent( poms: Map, visited: Set - ): OrtDependency? { + ): OrtComponent? { if (this is UnresolvedDependencyResult) { if (attempted is ProjectComponentSelector) { // Ignore unresolved project dependencies. For example for complex Android projects, Gradle's @@ -158,8 +158,8 @@ internal class OrtModelBuilder : ToolingModelBuilder { // Cut the graph on cyclic dependencies. if (id in visited) return null - if (selected in ortDependencyCache) { - return ortDependencyCache[selected] + if (selected in ortComponentCache) { + return ortComponentCache[selected] } if (id is ModuleComponentIdentifier) { @@ -174,10 +174,10 @@ internal class OrtModelBuilder : ToolingModelBuilder { // Check if we have scanned the dependencies of this subtree before, and if so, reuse them. val dependencies = globalDependencySubtrees.getOrPut(id.displayName) { - selected.dependencies.toOrtDependencies(poms, visited + id) + selected.dependencies.toOrtComponents(poms, visited + id) } - return OrtDependencyImpl( + return OrtComponentImpl( groupId = id.group, artifactId = id.module, version = id.version, @@ -203,15 +203,15 @@ internal class OrtModelBuilder : ToolingModelBuilder { }, localPath = null ).also { - ortDependencyCache[selected] = it + ortComponentCache[selected] = it } } if (id is ProjectComponentIdentifier) { val moduleId = selected.moduleVersion ?: return null - val dependencies = selected.dependencies.toOrtDependencies(poms, visited + id) + val dependencies = selected.dependencies.toOrtComponents(poms, visited + id) - return OrtDependencyImpl( + return OrtComponentImpl( groupId = moduleId.group, artifactId = moduleId.name, version = moduleId.version.takeUnless { it == "unspecified" }.orEmpty(), @@ -229,7 +229,7 @@ internal class OrtModelBuilder : ToolingModelBuilder { mavenModel = null, localPath = id.projectPath ).also { - ortDependencyCache[selected] = it + ortComponentCache[selected] = it } } diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt index cc45188f2e564..53fafc8e99600 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt @@ -19,8 +19,8 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradleplugin +import OrtComponent import OrtConfiguration -import OrtDependency import OrtDependencyTreeModel import OrtMavenModel import OrtRepository @@ -42,24 +42,24 @@ internal class OrtDependencyTreeModelImpl( @Suppress("SerialVersionUIDInSerializableClass") internal class OrtConfigurationImpl( override val name: String, - override val dependencies: List + override val dependencies: List ) : OrtConfiguration, Serializable @Suppress("LongParameterList", "SerialVersionUIDInSerializableClass") -internal class OrtDependencyImpl( +internal class OrtComponentImpl( override val groupId: String, override val artifactId: String, override val version: String, override val classifier: String, override val extension: String, override val variants: Map>, - override val dependencies: List, + override val dependencies: List, override val error: String?, override val warning: String?, override val pomFile: String?, override val mavenModel: OrtMavenModel?, override val localPath: String? -) : OrtDependency, Serializable +) : OrtComponent, Serializable @Suppress("SerialVersionUIDInSerializableClass") internal class OrtMavenModelImpl( diff --git a/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt b/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt index 20c356f666fe0..9a11666ebb57c 100644 --- a/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt +++ b/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt @@ -19,7 +19,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradle -import OrtDependency +import OrtComponent import org.apache.maven.project.ProjectBuildingException @@ -50,7 +50,7 @@ internal class GradleDependencyHandler( /** The helper object to resolve packages via Maven. */ private val maven: MavenSupport -) : DependencyHandler { +) : DependencyHandler { /** * A list with repositories to use when resolving packages. This list must be set before using this handler for * constructing the dependency graph of a project. As different projects may use different repositories, this @@ -58,12 +58,12 @@ internal class GradleDependencyHandler( */ var repositories = emptyList() - override fun identifierFor(dependency: OrtDependency): Identifier = + override fun identifierFor(dependency: OrtComponent): Identifier = with(dependency) { Identifier(getIdentifierType(projectType), groupId, artifactId, version) } - override fun dependenciesFor(dependency: OrtDependency): List = dependency.dependencies + override fun dependenciesFor(dependency: OrtComponent): List = dependency.dependencies - override fun issuesFor(dependency: OrtDependency): List = + override fun issuesFor(dependency: OrtComponent): List = listOfNotNull( dependency.error?.let { createAndLogIssue( @@ -82,10 +82,10 @@ internal class GradleDependencyHandler( } ) - override fun linkageFor(dependency: OrtDependency): PackageLinkage = + override fun linkageFor(dependency: OrtComponent): PackageLinkage = if (dependency.isProjectDependency) PackageLinkage.PROJECT_DYNAMIC else PackageLinkage.DYNAMIC - override fun createPackage(dependency: OrtDependency, issues: MutableCollection): Package? { + override fun createPackage(dependency: OrtComponent, issues: MutableCollection): Package? { // Only look for a package if there was no error resolving the dependency and it is no project dependency. if (dependency.error != null || dependency.isProjectDependency) return null diff --git a/plugins/package-managers/gradle/src/main/resources/init.gradle b/plugins/package-managers/gradle/src/main/resources/init.gradle index 96bbffef95812..57209505505a7 100644 --- a/plugins/package-managers/gradle/src/main/resources/init.gradle +++ b/plugins/package-managers/gradle/src/main/resources/init.gradle @@ -66,17 +66,17 @@ interface OrtDependencyTreeModel { interface OrtConfiguration { String getName() - List getDependencies() + List getDependencies() } -interface OrtDependency { +interface OrtComponent { String getGroupId() String getArtifactId() String getVersion() String getClassifier() String getExtension() Map> getVariants() - List getDependencies() + List getDependencies() String getError() String getWarning() String getPomFile() @@ -107,19 +107,19 @@ class OrtDependencyTreeModelImpl implements OrtDependencyTreeModel, Serializable @TupleConstructor class OrtConfigurationImpl implements OrtConfiguration, Serializable { String name - List dependencies + List dependencies } @ToString(includeNames = true) @TupleConstructor -class OrtDependencyImpl implements OrtDependency, Serializable { +class OrtComponentImpl implements OrtComponent, Serializable { String groupId = '' String artifactId = '' String version = '' String classifier = '' String extension = '' Map> variants = [:] - List dependencies = [] + List dependencies = [] String error String warning String pomFile @@ -162,15 +162,15 @@ class AbstractOrtDependencyTreePlugin implements Plugin { private static class OrtDependencyTreeModelBuilder implements ToolingModelBuilder { /** - * Stores the OrtDependency objects created by this builder, so that they can be reused when the same + * Stores the OrtComponent objects created by this builder, so that they can be reused when the same * dependency is encountered again in the dependency graph. As dependencies can occur many times in large * dependency graphs, de-duplicating these objects can save a significant amount of memory. * * Note, however, that packages can be referenced in the graph multiple times with a different set of - * dependencies. Therefore, for a package with a given identifier, there can be different OrtDependency + * dependencies. Therefore, for a package with a given identifier, there can be different OrtComponent * objects; hence the values of the map are lists. */ - private final Map> dependencies = new HashMap<>() + private final Map> dependencies = new HashMap<>() /** * All root projects of included builds, mapped by included build name. @@ -232,7 +232,7 @@ class AbstractOrtDependencyTreePlugin implements Plugin { "available: ${collectCauses(e)}") } - List dependencies = result.getRoot().getDependencies().findResults { + List dependencies = result.getRoot().getDependencies().findResults { fetchDependency(it, project, resolvedArtifacts, [] as Set) } @@ -273,17 +273,17 @@ class AbstractOrtDependencyTreePlugin implements Plugin { } /** - * Returns an OrtDependency for the given DependencyResult. The function checks whether there is already an - * OrtDependency instance in the cache compatible with the result. If this is not the case, parseDependency() + * Returns an OrtComponent for the given DependencyResult. The function checks whether there is already an + * OrtComponent instance in the cache compatible with the result. If this is not the case, parseDependency() * is called to generate a new instance. * * @param dependencyResult represents the package to be processed * @param project the current project * @param resolvedArtifacts the set of resolved artifacts * @param visited a set with dependency nodes already visited to detect cycles in the graph - * @return the OrtDependency representing this result + * @return the OrtComponent representing this result */ - private OrtDependency fetchDependency(DependencyResult dependencyResult, Project project, + private OrtComponent fetchDependency(DependencyResult dependencyResult, Project project, Set resolvedArtifacts, Set visited) { // Ignore version constraints, because they are not real dependencies but only document why a certain // version of their parent was chosen. @@ -330,19 +330,19 @@ class AbstractOrtDependencyTreePlugin implements Plugin { } /** - * Creates a new OrtDependency object to represent the given DependencyResult. The different types of + * Creates a new OrtComponent object to represent the given DependencyResult. The different types of * dependencies are evaluated. The (transitive) dependencies of this dependency are processed recursively. * * @param dependencyResult represents the package to be processed * @param project the current project * @param resolvedArtifacts the set of resolved artifacts * @param parents a set with dependency nodes already visited to detect cycles in the graph - * @return the newly created OrtDependency + * @return the newly created OrtComponent */ - private OrtDependency parseDependency(DependencyResult dependencyResult, Project project, + private OrtComponent parseDependency(DependencyResult dependencyResult, Project project, Set resolvedArtifacts, Set parents) { if (dependencyResult instanceof ResolvedDependencyResult) { - List dependencies = dependencyResult.selected.dependencies.findResults { dependency -> + List dependencies = dependencyResult.selected.dependencies.findResults { dependency -> // Do not follow constraints, because they are not real dependencies but only document why a certain // version of their parent was chosen. // Do not follow circular dependencies, these can exist for project dependencies. @@ -397,12 +397,12 @@ class AbstractOrtDependencyTreePlugin implements Plugin { def classifier = artifact?.classifier ?: '' def extension = artifact?.extension ?: '' - return new OrtDependencyImpl(id.group, id.module, id.version, classifier, extension, [:], dependencies, + return new OrtComponentImpl(id.group, id.module, id.version, classifier, extension, [:], dependencies, error, warning, pomFile, null) } else if (id instanceof ProjectComponentIdentifier) { if (isCurrentBuild(id.build, project) || !project.gradle.gradleVersion.isAtLeastVersion(7, 2)) { def dependencyProject = project.rootProject.findProject(id.projectPath) - return new OrtDependencyImpl(groupId: dependencyProject.group.toString(), + return new OrtComponentImpl(groupId: dependencyProject.group.toString(), artifactId: dependencyProject.name, version: dependencyProject.version.toString(), dependencies: dependencies, localPath: dependencyProject.projectDir.absolutePath) } else { @@ -412,7 +412,7 @@ class AbstractOrtDependencyTreePlugin implements Plugin { def dependencyProject = id.projectPath == ":" ? includedProject : includedProject.findProject(id.projectName) - return new OrtDependencyImpl(groupId: dependencyProject.group.toString(), + return new OrtComponentImpl(groupId: dependencyProject.group.toString(), artifactId: dependencyProject.name, version: dependencyProject.version.toString(), dependencies: dependencies, localPath: dependencyProject.projectDir.absolutePath) } @@ -480,7 +480,7 @@ class AbstractOrtDependencyTreePlugin implements Plugin { * @param visited stores the name of already visited dependencies to deal with cycles * @return a flag whether the dependency trees are equal */ - private boolean dependencyTreeEquals(OrtDependency dependency, DependencyResult dependencyResult, + private boolean dependencyTreeEquals(OrtComponent dependency, DependencyResult dependencyResult, Project project, Set visited) { def displayName = dependencyResult.requested.displayName if (displayName in visited) { @@ -501,7 +501,7 @@ class AbstractOrtDependencyTreePlugin implements Plugin { return dependencyMap.every { entry -> def matchingResult = resultMap[entry.key] - matchingResult != null && dependencyTreeEquals(entry.value as OrtDependency, + matchingResult != null && dependencyTreeEquals(entry.value as OrtComponent, matchingResult as DependencyResult, project, nextVisited) } } @@ -578,12 +578,12 @@ class AbstractOrtDependencyTreePlugin implements Plugin { } /** - * Generates a unique identifier for the given OrtDependency. + * Generates a unique identifier for the given OrtComponent. * - * @param dependency the OrtDependency - * @return the identifier for this OrtDependency + * @param dependency the OrtComponent + * @return the identifier for this OrtComponent */ - private static String identifierFor(OrtDependency dependency) { + private static String identifierFor(OrtComponent dependency) { return toIdentifier(dependency.groupId, dependency.artifactId, dependency.version) } @@ -598,10 +598,10 @@ class AbstractOrtDependencyTreePlugin implements Plugin { * @param warning an optional warning message * @return the newly created dependency representation */ - private static OrtDependencyImpl dependencyFromDisplayName(String displayName, List dependencies, - String error, String warning) { + private static OrtComponentImpl dependencyFromDisplayName(String displayName, List dependencies, + String error, String warning) { def coordinates = displayNameToCoordinates(displayName) - return new OrtDependencyImpl(groupId: coordinates[0], artifactId: coordinates[1], version: coordinates[2], + return new OrtComponentImpl(groupId: coordinates[0], artifactId: coordinates[1], version: coordinates[2], dependencies: dependencies, error: error?.toString(), warning: warning?.toString()) } diff --git a/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt b/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt index 3230172545602..4f3a088e16b47 100644 --- a/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt +++ b/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt @@ -19,7 +19,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradle -import OrtDependency +import OrtComponent import io.kotest.core.spec.style.WordSpec import io.kotest.inspectors.forAll @@ -332,9 +332,9 @@ private fun createDependency( artifact: String, version: String, path: String? = null, - dependencies: List = emptyList() -): OrtDependency { - val dependency = mockk() + dependencies: List = emptyList() +): OrtComponent { + val dependency = mockk() every { dependency.groupId } returns group every { dependency.artifactId } returns artifact every { dependency.version } returns version @@ -352,7 +352,7 @@ private fun createDependency( * Create a [DependencyGraphBuilder] equipped with a [GradleDependencyHandler] that is used by the test cases in * this class. */ -private fun createGraphBuilder(): DependencyGraphBuilder { +private fun createGraphBuilder(): DependencyGraphBuilder { val dependencyHandler = GradleDependencyHandler(PROJECT_TYPE, createMavenSupport()) dependencyHandler.repositories = remoteRepositories return DependencyGraphBuilder(dependencyHandler) @@ -382,9 +382,9 @@ private fun createMavenSupport(): MavenSupport { } /** - * Returns an [Identifier] for this [OrtDependency]. + * Returns an [Identifier] for this [OrtComponent]. */ -private fun OrtDependency.toId() = Identifier(getIdentifierType(PROJECT_TYPE), groupId, artifactId, version) +private fun OrtComponent.toId() = Identifier(getIdentifierType(PROJECT_TYPE), groupId, artifactId, version) /** * Return the package references from the given [scopes] associated with the scope with the given [scopeName]. @@ -400,7 +400,7 @@ private fun Collection.identifiers(): List = map { /** * Find the package corresponding to the given [dependency] in this collection. */ -private fun Collection.findDependency(dependency: OrtDependency): PackageReference = +private fun Collection.findDependency(dependency: OrtComponent): PackageReference = findId(dependency.toId()) /** @@ -412,7 +412,7 @@ private fun Collection.findId(id: Identifier): PackageReferenc /** * Check whether this [PackageReference] contains exactly the given [dependencies][expectedDependencies]. */ -private fun PackageReference.checkDependencies(vararg expectedDependencies: OrtDependency): Set { +private fun PackageReference.checkDependencies(vararg expectedDependencies: OrtComponent): Set { val ids = expectedDependencies.map { it.toId() } dependencies.identifiers() should containExactlyInAnyOrder(ids) return dependencies From 94cb08fd73dbe2aa2c6c8e8b58864727e4248404 Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Tue, 2 Jun 2026 11:12:01 +0200 Subject: [PATCH 5/6] refactor(gradle-model): Introduce an `OrtComponentIdentifier` Prepare for an upcoming change, which re-designs the representation of the tree structure. Use the same set of attributes as Gradle's `ModuleComponentIdentifier`. Signed-off-by: Frank Viernau --- .../main/kotlin/GradleDependencyHandler.kt | 12 +++-- .../src/main/kotlin/GradleModel.kt | 6 ++- .../src/main/kotlin/OrtModelBuilder.kt | 12 ++--- .../src/main/kotlin/OrtModelImpl.kt | 10 ++++- .../main/kotlin/GradleDependencyHandler.kt | 8 ++-- .../gradle/src/main/resources/init.gradle | 45 +++++++++++++------ .../kotlin/GradleDependencyHandlerTest.kt | 19 +++++--- 7 files changed, 78 insertions(+), 34 deletions(-) diff --git a/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt b/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt index 7f5dfc371d929..fabcb32d262be 100644 --- a/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt +++ b/plugins/package-managers/gradle-inspector/src/main/kotlin/GradleDependencyHandler.kt @@ -60,7 +60,9 @@ internal class GradleDependencyHandler( private val projectType: String ) : DependencyHandler { override fun identifierFor(dependency: OrtComponent): Identifier = - with(dependency) { Identifier(getIdentifierType(projectType), groupId, artifactId, version) } + with(dependency.componentId) { + Identifier(dependency.getIdentifierType(projectType), groupId, artifactId, version) + } override fun dependenciesFor(dependency: OrtComponent): List = dependency.dependencies @@ -208,8 +210,10 @@ private fun OrtComponent.handleValidScmInfo(type: String, url: String, tag: Stri // Try to detect the Maven SCM provider from the URL only, e.g. by looking at the host or special URL paths. VcsHost.parseUrl(fixedUrl).copy(revision = tag).also { - logger.info { - "Fixed up invalid SCM connection without a provider in '$groupId:$artifactId:$version' to $it." + with(componentId) { + logger.info { + "Fixed up invalid SCM connection without a provider in '$groupId:$artifactId:$version' to $it." + } } } } @@ -244,7 +248,7 @@ private fun OrtComponent.handleInvalidScmInfo(connection: String, tag: String): VcsInfo.EMPTY } } ?: run { - val dep = "$groupId:$artifactId:$version" + val dep = with(componentId) { "$groupId:$artifactId:$version" } if (connection.startsWith("git://") || connection.endsWith(".git")) { // It is a common mistake to omit the "scm:[provider]:" prefix. Add fall-backs for nevertheless clear diff --git a/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt b/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt index 5ed08d6074db4..835830d2572f4 100644 --- a/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt +++ b/plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt @@ -37,10 +37,14 @@ interface OrtConfiguration { val dependencies: List } -interface OrtComponent { +interface OrtComponentIdentifier { val groupId: String val artifactId: String val version: String +} + +interface OrtComponent { + val componentId: OrtComponentIdentifier val classifier: String val extension: String val variants: Map> diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt index 287b08c675809..538b3a9b65de0 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt @@ -178,9 +178,7 @@ internal class OrtModelBuilder : ToolingModelBuilder { } return OrtComponentImpl( - groupId = id.group, - artifactId = id.module, - version = id.version, + componentId = OrtComponentIdentifierImpl(id.group, id.module, id.version), classifier = "", extension = modelBuildingResult?.effectiveModel?.packaging.orEmpty(), variants = selected.variants.associate { @@ -212,9 +210,11 @@ internal class OrtModelBuilder : ToolingModelBuilder { val dependencies = selected.dependencies.toOrtComponents(poms, visited + id) return OrtComponentImpl( - groupId = moduleId.group, - artifactId = moduleId.name, - version = moduleId.version.takeUnless { it == "unspecified" }.orEmpty(), + componentId = OrtComponentIdentifierImpl( + groupId = moduleId.group, + artifactId = moduleId.name, + version = moduleId.version.takeUnless { it == "unspecified" }.orEmpty() + ), classifier = "", extension = "", variants = selected.variants.associate { diff --git a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt index 53fafc8e99600..ac9aa6dea8ea5 100644 --- a/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt +++ b/plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt @@ -20,6 +20,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradleplugin import OrtComponent +import OrtComponentIdentifier import OrtConfiguration import OrtDependencyTreeModel import OrtMavenModel @@ -46,10 +47,15 @@ internal class OrtConfigurationImpl( ) : OrtConfiguration, Serializable @Suppress("LongParameterList", "SerialVersionUIDInSerializableClass") -internal class OrtComponentImpl( +internal class OrtComponentIdentifierImpl( override val groupId: String, override val artifactId: String, - override val version: String, + override val version: String +) : OrtComponentIdentifier, Serializable + +@Suppress("LongParameterList", "SerialVersionUIDInSerializableClass") +internal class OrtComponentImpl( + override val componentId: OrtComponentIdentifier, override val classifier: String, override val extension: String, override val variants: Map>, diff --git a/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt b/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt index 9a11666ebb57c..6ff1d13e81f98 100644 --- a/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt +++ b/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt @@ -59,7 +59,9 @@ internal class GradleDependencyHandler( var repositories = emptyList() override fun identifierFor(dependency: OrtComponent): Identifier = - with(dependency) { Identifier(getIdentifierType(projectType), groupId, artifactId, version) } + with(dependency.componentId) { + Identifier(dependency.getIdentifierType(projectType), groupId, artifactId, version) + } override fun dependenciesFor(dependency: OrtComponent): List = dependency.dependencies @@ -90,8 +92,8 @@ internal class GradleDependencyHandler( if (dependency.error != null || dependency.isProjectDependency) return null val artifact = DefaultArtifact( - dependency.groupId, dependency.artifactId, dependency.classifier, - dependency.extension, dependency.version + dependency.componentId.groupId, dependency.componentId.artifactId, dependency.classifier, + dependency.extension, dependency.componentId.version ) return runCatching { diff --git a/plugins/package-managers/gradle/src/main/resources/init.gradle b/plugins/package-managers/gradle/src/main/resources/init.gradle index 57209505505a7..2c8c064b3a9bc 100644 --- a/plugins/package-managers/gradle/src/main/resources/init.gradle +++ b/plugins/package-managers/gradle/src/main/resources/init.gradle @@ -69,10 +69,14 @@ interface OrtConfiguration { List getDependencies() } -interface OrtComponent { +interface OrtComponentIdentifier { String getGroupId() String getArtifactId() String getVersion() +} + +interface OrtComponent { + OrtComponentIdentifier getComponentId() String getClassifier() String getExtension() Map> getVariants() @@ -112,10 +116,16 @@ class OrtConfigurationImpl implements OrtConfiguration, Serializable { @ToString(includeNames = true) @TupleConstructor -class OrtComponentImpl implements OrtComponent, Serializable { +class OrtComponentIdentifierImpl implements OrtComponentIdentifier, Serializable { String groupId = '' String artifactId = '' String version = '' +} + +@ToString(includeNames = true) +@TupleConstructor +class OrtComponentImpl implements OrtComponent, Serializable { + OrtComponentIdentifier componentId String classifier = '' String extension = '' Map> variants = [:] @@ -396,25 +406,31 @@ class AbstractOrtDependencyTreePlugin implements Plugin { def classifier = artifact?.classifier ?: '' def extension = artifact?.extension ?: '' + def componentId = new OrtComponentIdentifierImpl(groupId: id.group, artifactId: id.module, version: id.version) - return new OrtComponentImpl(id.group, id.module, id.version, classifier, extension, [:], dependencies, - error, warning, pomFile, null) + return new OrtComponentImpl(componentId, classifier, extension, [:], dependencies, error, warning, + pomFile, null) } else if (id instanceof ProjectComponentIdentifier) { if (isCurrentBuild(id.build, project) || !project.gradle.gradleVersion.isAtLeastVersion(7, 2)) { def dependencyProject = project.rootProject.findProject(id.projectPath) - return new OrtComponentImpl(groupId: dependencyProject.group.toString(), - artifactId: dependencyProject.name, version: dependencyProject.version.toString(), - dependencies: dependencies, localPath: dependencyProject.projectDir.absolutePath) + + def componentId = new OrtComponentIdentifierImpl(groupId: dependencyProject.group.toString(), + artifactId: dependencyProject.name, version: dependencyProject.version.toString()) + + return new OrtComponentImpl(componentId: componentId, dependencies: dependencies, + localPath: dependencyProject.projectDir.absolutePath) } else { project.logger.quiet("Project '$id' is not part of current build. Assuming included build.") def includedProject = findRootProjectOfIncludedBuild(project, id) def dependencyProject = id.projectPath == ":" ? includedProject : includedProject.findProject(id.projectName) + def componentId = new OrtComponentIdentifierImpl(groupId: dependencyProject.group.toString(), + artifactId: dependencyProject.name, version: dependencyProject.version.toString()) + - return new OrtComponentImpl(groupId: dependencyProject.group.toString(), - artifactId: dependencyProject.name, version: dependencyProject.version.toString(), - dependencies: dependencies, localPath: dependencyProject.projectDir.absolutePath) + return new OrtComponentImpl(componentId: componentId, dependencies: dependencies, + localPath: dependencyProject.projectDir.absolutePath) } } else { return dependencyFromDisplayName(id.displayName, dependencies, @@ -584,7 +600,8 @@ class AbstractOrtDependencyTreePlugin implements Plugin { * @return the identifier for this OrtComponent */ private static String identifierFor(OrtComponent dependency) { - return toIdentifier(dependency.groupId, dependency.artifactId, dependency.version) + def componentId = dependency.componentId + return toIdentifier(componentId.groupId, componentId.artifactId, componentId.version) } /** @@ -601,8 +618,10 @@ class AbstractOrtDependencyTreePlugin implements Plugin { private static OrtComponentImpl dependencyFromDisplayName(String displayName, List dependencies, String error, String warning) { def coordinates = displayNameToCoordinates(displayName) - return new OrtComponentImpl(groupId: coordinates[0], artifactId: coordinates[1], version: coordinates[2], - dependencies: dependencies, error: error?.toString(), warning: warning?.toString()) + def componentId = new OrtComponentIdentifierImpl(groupId: coordinates[0], artifactId: coordinates[1], + version: coordinates[2]) + return new OrtComponentImpl(componentId: componentId, dependencies: dependencies, error: error?.toString(), + warning: warning?.toString()) } /** diff --git a/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt b/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt index 4f3a088e16b47..26221113456f4 100644 --- a/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt +++ b/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt @@ -20,6 +20,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradle import OrtComponent +import OrtComponentIdentifier import io.kotest.core.spec.style.WordSpec import io.kotest.inspectors.forAll @@ -315,7 +316,9 @@ class GradleDependencyHandlerTest : WordSpec({ with(issues.first()) { source shouldBe GradleFactory.descriptor.displayName severity shouldBe Severity.ERROR - message should contain("${dep.groupId}:${dep.artifactId}:${dep.version}") + with(dep.componentId) { + message should contain("$groupId:$artifactId:$version") + } } } } @@ -334,10 +337,13 @@ private fun createDependency( path: String? = null, dependencies: List = emptyList() ): OrtComponent { + val componentId = mockk() + every { componentId.groupId } returns group + every { componentId.artifactId } returns artifact + every { componentId.version } returns version + val dependency = mockk() - every { dependency.groupId } returns group - every { dependency.artifactId } returns artifact - every { dependency.version } returns version + every { dependency.componentId } returns componentId every { dependency.localPath } returns path every { dependency.pomFile } returns "pom.xml" every { dependency.dependencies } returns dependencies @@ -384,7 +390,10 @@ private fun createMavenSupport(): MavenSupport { /** * Returns an [Identifier] for this [OrtComponent]. */ -private fun OrtComponent.toId() = Identifier(getIdentifierType(PROJECT_TYPE), groupId, artifactId, version) +private fun OrtComponent.toId() = + with(componentId) { + Identifier(getIdentifierType(PROJECT_TYPE), groupId, artifactId, version) + } /** * Return the package references from the given [scopes] associated with the scope with the given [scopeName]. From ecc64620459a52ac052db369202b3a6cebedc570 Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Wed, 3 Jun 2026 17:20:51 +0200 Subject: [PATCH 6/6] refactor(gradle): Inline the code from `gradle-model` Stop sharing the model between the legacy `Gradle` package manager and `GradleInspector` to prepare for changing the representation of the dependency tree structure to fix an issue with `GradleInspector`. With a shared model also `Gradle` would need to be aligned, which would result in a (too) large commit, quite a bit of development effort and not least impose the risk of introducing new bugs into `Gradle`. It is planned to remove `Gradle` once `GradleInspector` covers all its features, which is why it does not make sense to put much effort into `Gradle` anymore. So, decouple the implementations entirely to reflect these priorities. Signed-off-by: Frank Viernau --- .../package-managers/gradle/build.gradle.kts | 1 - .../gradle/src/main/kotlin/Extensions.kt | 39 +++++++++ .../main/kotlin/GradleDependencyHandler.kt | 2 - .../gradle/src/main/kotlin/GradleModel.kt | 79 +++++++++++++++++++ .../kotlin/GradleDependencyHandlerTest.kt | 1 - 5 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 plugins/package-managers/gradle/src/main/kotlin/Extensions.kt create mode 100644 plugins/package-managers/gradle/src/main/kotlin/GradleModel.kt diff --git a/plugins/package-managers/gradle/build.gradle.kts b/plugins/package-managers/gradle/build.gradle.kts index ffb30aa2ba954..780656a71c77b 100644 --- a/plugins/package-managers/gradle/build.gradle.kts +++ b/plugins/package-managers/gradle/build.gradle.kts @@ -30,7 +30,6 @@ dependencies { implementation(libs.maven.core) implementation(libs.maven.resolver.api) implementation(projects.downloader) - implementation(projects.plugins.packageManagers.gradleModel) implementation(projects.plugins.packageManagers.mavenPackageManager) implementation(projects.utils.commonUtils) implementation(projects.utils.ortUtils) diff --git a/plugins/package-managers/gradle/src/main/kotlin/Extensions.kt b/plugins/package-managers/gradle/src/main/kotlin/Extensions.kt new file mode 100644 index 0000000000000..b9869811e683a --- /dev/null +++ b/plugins/package-managers/gradle/src/main/kotlin/Extensions.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 The ORT Project Copyright Holders + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.ossreviewtoolkit.plugins.packagemanagers.gradle + +import OrtComponent + +/** + * The type of this Gradle dependency. In case of a project, it is [projectType]. Otherwise it is "Maven" unless there + * is no POM, then it is "Unknown". + */ +internal fun OrtComponent.getIdentifierType(projectType: String) = + when { + isProjectDependency -> projectType + pomFile != null -> "Maven" + else -> "Unknown" + } + +/** + * A flag to indicate whether this Gradle dependency refers to a project, or to a package. + */ +internal val OrtComponent.isProjectDependency: Boolean + get() = localPath != null diff --git a/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt b/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt index 6ff1d13e81f98..80159367b3ac7 100644 --- a/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt +++ b/plugins/package-managers/gradle/src/main/kotlin/GradleDependencyHandler.kt @@ -34,8 +34,6 @@ import org.ossreviewtoolkit.model.PackageLinkage import org.ossreviewtoolkit.model.Severity import org.ossreviewtoolkit.model.createAndLogIssue import org.ossreviewtoolkit.model.utils.DependencyHandler -import org.ossreviewtoolkit.plugins.packagemanagers.gradlemodel.getIdentifierType -import org.ossreviewtoolkit.plugins.packagemanagers.gradlemodel.isProjectDependency import org.ossreviewtoolkit.plugins.packagemanagers.maven.utils.MavenSupport import org.ossreviewtoolkit.plugins.packagemanagers.maven.utils.identifier import org.ossreviewtoolkit.utils.common.collectMessages diff --git a/plugins/package-managers/gradle/src/main/kotlin/GradleModel.kt b/plugins/package-managers/gradle/src/main/kotlin/GradleModel.kt new file mode 100644 index 0000000000000..024b6059d4d6a --- /dev/null +++ b/plugins/package-managers/gradle/src/main/kotlin/GradleModel.kt @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2017 The ORT Project Copyright Holders + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +// As it is not possible to declare a package in "init.gradle" also no package is declared here. + +// The following interfaces have to match those in "plugins/package-managers/gradle/src/main/resources/init.gradle" +// because they are used to deserialize the model produced there. + +internal interface OrtDependencyTreeModel { + val group: String + val name: String + val version: String + val configurations: List + val repositories: List + val errors: List + val warnings: List +} + +internal interface OrtConfiguration { + val name: String + val dependencies: List +} + +internal interface OrtComponentIdentifier { + val groupId: String + val artifactId: String + val version: String +} + +internal interface OrtComponent { + val componentId: OrtComponentIdentifier + val classifier: String + val extension: String + val variants: Map> + val dependencies: List + val error: String? + val warning: String? + val pomFile: String? + val mavenModel: OrtMavenModel? + val localPath: String? +} + +internal interface OrtMavenModel { + val licenses: Set + val authors: Set + val description: String? + val homepageUrl: String? + val vcs: OrtVcsModel? +} + +internal interface OrtVcsModel { + val connection: String + val tag: String + val browsableUrl: String +} + +internal interface OrtRepository { + val url: String + val username: String? + val password: String? + val headerName: String? + val headerValue: String? +} diff --git a/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt b/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt index 26221113456f4..54a69d0b90b39 100644 --- a/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt +++ b/plugins/package-managers/gradle/src/test/kotlin/GradleDependencyHandlerTest.kt @@ -56,7 +56,6 @@ import org.ossreviewtoolkit.model.Scope import org.ossreviewtoolkit.model.Severity import org.ossreviewtoolkit.model.VcsInfo import org.ossreviewtoolkit.model.utils.DependencyGraphBuilder -import org.ossreviewtoolkit.plugins.packagemanagers.gradlemodel.getIdentifierType import org.ossreviewtoolkit.plugins.packagemanagers.maven.utils.MavenSupport /**