Skip to content

Commit 5dae200

Browse files
oheger-boschsschuberth
authored andcommitted
refactor(Maven)!: Introduce a function type to resolve packages
Instead of using `MavenSupport` directly in `MavenDependencyHandler` to create packages for dependencies, use a package resolver function. The main reason for this change is that for Tycho a partially different algorithm for the creation of packages is required. However, the change is also beneficial to simplify the logic in `MavenDependencyHandler` and to reduce its coupling with other objects in the Maven package manager implementation. Signed-off-by: Oliver Heger <[email protected]>
1 parent a8f47a9 commit 5dae200

File tree

5 files changed

+42
-64
lines changed

5 files changed

+42
-64
lines changed

plugins/package-managers/maven/src/main/kotlin/Maven.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ class Maven(
8181
localProjectBuildingResults += mavenSupport.prepareMavenProjects(definitionFiles)
8282

8383
val localProjects = localProjectBuildingResults.mapValues { it.value.project }
84-
val dependencyHandler = MavenDependencyHandler(managerName, projectType, mavenSupport, localProjects, sbtMode)
84+
val dependencyHandler = MavenDependencyHandler(
85+
managerName,
86+
projectType,
87+
localProjects,
88+
mavenSupport.defaultPackageResolverFun(sbtMode)
89+
)
8590
graphBuilder = DependencyGraphBuilder(dependencyHandler)
8691
}
8792

plugins/package-managers/maven/src/main/kotlin/Tycho.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ class Tycho(
151151
mavenSupport: MavenSupport,
152152
mavenProjects: Map<String, MavenProject>
153153
): DependencyGraphBuilder<DependencyNode> {
154-
val dependencyHandler = MavenDependencyHandler(managerName, projectType, mavenSupport, mavenProjects, false)
154+
val dependencyHandler =
155+
MavenDependencyHandler(managerName, projectType, mavenProjects, mavenSupport.defaultPackageResolverFun())
155156
return DependencyGraphBuilder(dependencyHandler)
156157
}
157158

plugins/package-managers/maven/src/main/kotlin/utils/MavenDependencyHandler.kt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,16 @@ import org.ossreviewtoolkit.model.Package
3030
import org.ossreviewtoolkit.model.PackageLinkage
3131
import org.ossreviewtoolkit.model.createAndLogIssue
3232
import org.ossreviewtoolkit.model.utils.DependencyHandler
33-
import org.ossreviewtoolkit.plugins.packagemanagers.maven.Maven
3433
import org.ossreviewtoolkit.utils.common.collectMessages
3534
import org.ossreviewtoolkit.utils.ort.showStackTrace
3635

36+
/**
37+
* Type alias for a function used by [MavenDependencyHandler] to create [Package] objects for detected dependencies.
38+
* The function expects the [DependencyNode] representing the dependency. It returns the created [Package] object or
39+
* throws an exception if the package could not be created (which will then lead to the creation of issue).
40+
*/
41+
typealias PackageResolverFun = (DependencyNode) -> Package
42+
3743
/**
3844
* A specialized [DependencyHandler] implementation for the dependency model of Maven.
3945
*/
@@ -44,19 +50,14 @@ class MavenDependencyHandler(
4450
/** The type of projects to handle. */
4551
private val projectType: String,
4652

47-
/** The helper object to invoke Maven-related functionality. */
48-
internal val support: MavenSupport,
49-
5053
/**
5154
* A map with information about the local projects in the current Maven build. Dependencies pointing to projects
5255
* sometimes need to be treated in a special way.
5356
*/
5457
localProjects: Map<String, MavenProject>,
5558

56-
/**
57-
* A flag whether [SBT compatibility mode][Maven.enableSbtMode] is enabled.
58-
*/
59-
private val sbtMode: Boolean
59+
/** The function for creating [Package] objects for detected dependencies. */
60+
private val packageResolverFun: PackageResolverFun
6061
) : DependencyHandler<DependencyNode> {
6162
/**
6263
* A set of identifiers that are known to point to local projects. This is updated for packages that are resolved
@@ -95,7 +96,7 @@ class MavenDependencyHandler(
9596
if (isLocalProject(dependency)) return null
9697

9798
return runCatching {
98-
val pkg = support.parsePackage(dependency.artifact, dependency.repositories, sbtMode = sbtMode)
99+
val pkg = packageResolverFun(dependency)
99100

100101
// There is the corner case that a dependency references a project, but in a different version than
101102
// the one used by the local build. Then, this dependency is actually a package, but Maven's

plugins/package-managers/maven/src/main/kotlin/utils/MavenSupport.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,16 @@ class MavenSupport(private val workspaceReader: WorkspaceReader) : Closeable {
563563
)
564564
}
565565

566+
/**
567+
* Return a [PackageResolverFun] that uses functionality provided by this object (mainly the [parsePackage]
568+
* function) to resolve a package for a given dependency. The function is configured with the given
569+
* [SBT compatibility mode][sbtMode].
570+
*/
571+
fun defaultPackageResolverFun(sbtMode: Boolean = false): PackageResolverFun =
572+
{ dependencyNode ->
573+
parsePackage(dependencyNode.artifact, dependencyNode.repositories, sbtMode = sbtMode)
574+
}
575+
566576
/**
567577
* Create a [MavenSession] and setup the [LegacySupport] and [SessionScope] because this is required to load
568578
* extensions using Maven Wagon.

plugins/package-managers/maven/src/test/kotlin/utils/MavenDependencyHandlerTest.kt

Lines changed: 14 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import org.apache.maven.project.ProjectBuildingException
4040

4141
import org.eclipse.aether.artifact.Artifact
4242
import org.eclipse.aether.graph.DependencyNode
43-
import org.eclipse.aether.repository.RemoteRepository
4443

4544
import org.ossreviewtoolkit.model.Identifier
4645
import org.ossreviewtoolkit.model.Issue
@@ -134,31 +133,13 @@ class MavenDependencyHandlerTest : WordSpec({
134133
"createPackage" should {
135134
"create a package for a dependency" {
136135
val dependency = createDependency(PACKAGE_ID_SUFFIX)
137-
val artifact = dependency.artifact
138-
val repos = listOf(createRepository(), createRepository())
139136
val pkg = createPackage(PACKAGE_ID_SUFFIX)
140137
val issues = mutableListOf<Issue>()
141138

142-
val handler = createHandler()
143-
144-
every { dependency.repositories } returns repos
145-
every { handler.support.parsePackage(artifact, repos) } returns pkg
146-
147-
handler.createPackage(dependency, issues) shouldBe pkg
148-
issues should beEmpty()
149-
}
150-
151-
"take the sbtMode flag into account" {
152-
val dependency = createDependency(PACKAGE_ID_SUFFIX)
153-
val artifact = dependency.artifact
154-
val repos = listOf(createRepository())
155-
val pkg = createPackage(PACKAGE_ID_SUFFIX)
156-
val issues = mutableListOf<Issue>()
157-
158-
val handler = createHandler(sbtMode = true)
159-
160-
every { dependency.repositories } returns repos
161-
every { handler.support.parsePackage(artifact, repos, sbtMode = true) } returns pkg
139+
val handler = createHandler { node ->
140+
node shouldBe dependency
141+
pkg
142+
}
162143

163144
handler.createPackage(dependency, issues) shouldBe pkg
164145
issues should beEmpty()
@@ -176,28 +157,18 @@ class MavenDependencyHandlerTest : WordSpec({
176157

177158
"return null for a package that is resolved to a project dependency" {
178159
val dependency = createDependency(PACKAGE_ID_SUFFIX)
179-
val artifact = dependency.artifact
180-
val repos = listOf(createRepository(), createRepository())
181160
val pkg = createPackage(PROJECT_ID_SUFFIX)
182161

183-
val handler = createHandler()
184-
185-
every { dependency.repositories } returns repos
186-
every { handler.support.parsePackage(artifact, repos) } returns pkg
162+
val handler = createHandler { pkg }
187163

188164
handler.createPackage(dependency, mutableListOf()) should beNull()
189165
}
190166

191167
"report the correct linkage for a package that is resolved to a project dependency" {
192168
val dependency = createDependency(PACKAGE_ID_SUFFIX)
193-
val artifact = dependency.artifact
194-
val repos = listOf(createRepository(), createRepository())
195169
val pkg = createPackage(PROJECT_ID_SUFFIX)
196170

197-
val handler = createHandler()
198-
199-
every { dependency.repositories } returns repos
200-
every { handler.support.parsePackage(artifact, repos) } returns pkg
171+
val handler = createHandler { pkg }
201172

202173
handler.createPackage(dependency, mutableListOf())
203174

@@ -210,14 +181,9 @@ class MavenDependencyHandlerTest : WordSpec({
210181
IOException("General failure when reading hard disk.")
211182
)
212183
val dependency = createDependency(PACKAGE_ID_SUFFIX)
213-
val artifact = dependency.artifact
214-
val repos = listOf(createRepository())
215184
val issues = mutableListOf<Issue>()
216185

217-
val handler = createHandler()
218-
219-
every { dependency.repositories } returns repos
220-
every { handler.support.parsePackage(artifact, repos) } throws exception
186+
val handler = createHandler { throw exception }
221187

222188
handler.createPackage(dependency, issues) should beNull()
223189

@@ -249,6 +215,9 @@ private val LOCAL_PROJECTS = mapOf(
249215
/** ID of an inter-project dependency. */
250216
private val PROJECT_ID_SUFFIX = LOCAL_PROJECTS.keys.first()
251217

218+
/** Constant for a resolver function that can be used if no interaction with the resolver is expected. */
219+
private val unusedPackageResolverFun: PackageResolverFun = { throw NotImplementedError() }
220+
252221
/**
253222
* Return an [Identifier] from the given [mavenId]. The identifiers used by Maven internally are very close to
254223
* ORT's identifiers; only the type component is missing.
@@ -283,19 +252,11 @@ private fun createDependency(id: String): DependencyNode {
283252
}
284253

285254
/**
286-
* Create the [MavenDependencyHandler] instance to be tested with mock dependencies and test data with the given
287-
* [sbtMode] flag.
288-
*/
289-
private fun createHandler(sbtMode: Boolean = false): MavenDependencyHandler {
290-
val mvn = mockk<MavenSupport>()
291-
return MavenDependencyHandler(MANAGER_NAME, PROJECT_TYPE, mvn, LOCAL_PROJECTS, sbtMode)
292-
}
293-
294-
/**
295-
* Convenience function to create a mock [RemoteRepository]. Note: This function solves some nasty false-positive
296-
* warnings about explicit type arguments.
255+
* Create the [MavenDependencyHandler] instance to be tested with default parameters and the given
256+
* [packageResolverFun].
297257
*/
298-
private fun createRepository(): RemoteRepository = mockk()
258+
private fun createHandler(packageResolverFun: PackageResolverFun = unusedPackageResolverFun): MavenDependencyHandler =
259+
MavenDependencyHandler(MANAGER_NAME, PROJECT_TYPE, LOCAL_PROJECTS, packageResolverFun)
299260

300261
/**
301262
* Convenience function to create a mock [MavenProject]. Note: This function solves some nasty false-positive

0 commit comments

Comments
 (0)