Skip to content

Commit 86de3cc

Browse files
committed
fix(Maven): Do not exclude modules during a Tycho build
As an optimization, the Tycho implementation had a feature to exclude submodules from the Maven build if they are matched by path excludes and the `skip_excluded` flag is set in the Analyzer configuration. However, this mechanism was not working as expected; it caused the Tycho build to fail with errors about unresolvable modules. Therefore, drop this optimization and always build all modules. Signed-off-by: Oliver Heger <[email protected]>
1 parent ee00fa3 commit 86de3cc

File tree

2 files changed

+5
-169
lines changed

2 files changed

+5
-169
lines changed

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

Lines changed: 5 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,9 @@
2020
package org.ossreviewtoolkit.plugins.packagemanagers.maven.tycho
2121

2222
import java.io.File
23-
import java.nio.file.Path
2423
import java.util.concurrent.atomic.AtomicReference
2524
import java.util.jar.Manifest
2625

27-
import kotlin.io.path.invariantSeparatorsPathString
28-
2926
import org.apache.logging.log4j.kotlin.logger
3027
import org.apache.maven.AbstractMavenLifecycleParticipant
3128
import org.apache.maven.cli.MavenCli
@@ -116,13 +113,7 @@ class Tycho(override val descriptor: PluginDescriptor = TychoFactory.Companion.d
116113

117114
val repositoryHelper = LocalRepositoryHelper()
118115
val collector = TychoProjectsCollector()
119-
val (exitCode, buildLog) = runBuild(
120-
analysisRoot,
121-
collector,
122-
definitionFile.parentFile,
123-
excludes,
124-
analyzerConfig.skipExcluded
125-
)
116+
val (exitCode, buildLog) = runBuild(collector, definitionFile.parentFile)
126117

127118
val resolver = P2ArtifactResolver.create(definitionFile.parentFile, collector.mavenProjects.values)
128119

@@ -198,13 +189,7 @@ class Tycho(override val descriptor: PluginDescriptor = TychoFactory.Companion.d
198189
* Run a Maven build on the Tycho project in [projectRoot] utilizing the given [collector]. Return a pair with the
199190
* exit code of the Maven project and a [File] that contains the output generated during the build.
200191
*/
201-
private fun runBuild(
202-
analysisRoot: File,
203-
collector: TychoProjectsCollector,
204-
projectRoot: File,
205-
excludes: Excludes,
206-
skipExcluded: Boolean
207-
): Pair<Int, File> {
192+
private fun runBuild(collector: TychoProjectsCollector, projectRoot: File): Pair<Int, File> {
208193
// The Maven CLI seems to change the context class loader. This has side effects on ORT's plugin mechanism.
209194
// To prevent this, store the class loader and restore it at the end of this function.
210195
val tccl = Thread.currentThread().contextClassLoader
@@ -219,7 +204,7 @@ class Tycho(override val descriptor: PluginDescriptor = TychoFactory.Companion.d
219204
System.setProperty(MavenCli.MULTIMODULE_PROJECT_DIRECTORY, projectRoot.absolutePath)
220205

221206
val exitCode = cli.doMain(
222-
generateMavenOptions(analysisRoot, projectRoot, buildLog, excludes, skipExcluded),
207+
generateMavenOptions(buildLog),
223208
projectRoot.path,
224209
null,
225210
null
@@ -291,16 +276,9 @@ class Tycho(override val descriptor: PluginDescriptor = TychoFactory.Companion.d
291276
}
292277

293278
/**
294-
* Generate the command line options to be passed to the Maven CLI for the given [analysisRoot] and [root] folders
295-
* and the [dependencyTreeFile].
279+
* Generate the command line options to be passed to the Maven CLI for the given [dependencyTreeFile].
296280
*/
297-
private fun generateMavenOptions(
298-
analysisRoot: File,
299-
root: File,
300-
dependencyTreeFile: File,
301-
excludes: Excludes,
302-
skipExcluded: Boolean
303-
): Array<String> =
281+
private fun generateMavenOptions(dependencyTreeFile: File): Array<String> =
304282
buildList {
305283
// The "package" goal is required; otherwise the Tycho extension is not activated.
306284
add("package")
@@ -309,33 +287,7 @@ class Tycho(override val descriptor: PluginDescriptor = TychoFactory.Companion.d
309287
add("-DoutputFile=${dependencyTreeFile.absolutePath}")
310288
add("-DappendOutput=true")
311289
add("-Dverbose=true")
312-
313-
generateModuleExcludes(analysisRoot, root, excludes, skipExcluded)?.takeUnless { it.isEmpty() }
314-
?.let { excludedModules ->
315-
add("-pl")
316-
add(excludedModules)
317-
}
318290
}.toTypedArray()
319-
320-
/**
321-
* Generate a list of submodules to be excluded for the Maven build with the given [rootProject] folder based on
322-
* the configured exclusions. The resulting string (if any) is used as the value of Maven's `-pl` option.
323-
*/
324-
private fun generateModuleExcludes(
325-
analysisRoot: File,
326-
rootProject: File,
327-
excludes: Excludes,
328-
skipExcluded: Boolean
329-
): String? {
330-
if (!skipExcluded) return null
331-
332-
val analysisRootPath = analysisRoot.toPath()
333-
val rootProjectPath = rootProject.toPath()
334-
return rootProject.walk().filter { it.name == "pom.xml" }
335-
.map { it.toPath().parent }
336-
.filter { excludes.isPathExcluded(analysisRootPath.relativeSubPath(it)) }
337-
.joinToString(",") { "!${rootProjectPath.relativeSubPath(it)}" }
338-
}
339291
}
340292

341293
/**
@@ -350,11 +302,6 @@ private const val DEPENDENCY_PLUGIN_VERSION = "3.8.1"
350302
private const val DEPENDENCY_TREE_GOAL =
351303
"org.apache.maven.plugins:maven-dependency-plugin:$DEPENDENCY_PLUGIN_VERSION:tree"
352304

353-
/**
354-
* Return the relative path of [other] to this [Path].
355-
*/
356-
private fun Path.relativeSubPath(other: Path): String = relativize(other).invariantSeparatorsPathString
357-
358305
/**
359306
* A special exception class to indicate that a Tycho build failed completely.
360307
*/

plugins/package-managers/maven/src/test/kotlin/tycho/TychoTest.kt

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,10 @@ import io.kotest.engine.spec.tempdir
2626
import io.kotest.engine.spec.tempfile
2727
import io.kotest.inspectors.forAll
2828
import io.kotest.matchers.collections.beEmpty
29-
import io.kotest.matchers.collections.contain
3029
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
31-
import io.kotest.matchers.comparables.shouldBeGreaterThan
3230
import io.kotest.matchers.nulls.beNull
3331
import io.kotest.matchers.should
3432
import io.kotest.matchers.shouldBe
35-
import io.kotest.matchers.shouldNot
3633
import io.kotest.matchers.string.shouldContain
3734

3835
import io.mockk.every
@@ -62,8 +59,6 @@ import org.ossreviewtoolkit.model.VcsInfo
6259
import org.ossreviewtoolkit.model.VcsType
6360
import org.ossreviewtoolkit.model.config.AnalyzerConfiguration
6461
import org.ossreviewtoolkit.model.config.Excludes
65-
import org.ossreviewtoolkit.model.config.PathExclude
66-
import org.ossreviewtoolkit.model.config.PathExcludeReason
6762
import org.ossreviewtoolkit.model.utils.DependencyGraphBuilder
6863
import org.ossreviewtoolkit.plugins.packagemanagers.maven.utils.PackageResolverFun
6964
import org.ossreviewtoolkit.plugins.packagemanagers.maven.utils.identifier
@@ -286,96 +281,6 @@ class TychoTest : WordSpec({
286281
val rootResults = results.single { it.project.id.name == "root" }
287282
rootResults.issues shouldContainExactlyInAnyOrder issues
288283
}
289-
290-
"exclude projects from the build according to path excludes" {
291-
val analysisRoot = tempdir()
292-
val tychoRoot = analysisRoot.createSubModule("tycho-root")
293-
tychoRoot.createSubModule("tycho-sub1")
294-
tychoRoot.createSubModule("tycho-sub2")
295-
tychoRoot.createSubModule("tycho-excluded-sub1")
296-
val module = tychoRoot.createSubModule("tycho-excluded-sub2")
297-
module.createSubModule("tycho-excluded-sub2-sub")
298-
val rootProject = createMavenProject("root", tychoRoot.pom)
299-
300-
val excludes = Excludes(
301-
paths = listOf(
302-
PathExclude("tycho-root/tycho-excluded-sub1", PathExcludeReason.EXAMPLE_OF),
303-
PathExclude("tycho-root/tycho-excluded-sub2/**", PathExcludeReason.TEST_OF),
304-
PathExclude("other-root/**", PathExcludeReason.EXAMPLE_OF)
305-
)
306-
)
307-
val analyzerConfig = AnalyzerConfiguration(skipExcluded = true)
308-
309-
val tycho = spyk(Tycho())
310-
val cli = injectCliMock(tycho, listOf(rootProject).toJson(), listOf(rootProject))
311-
312-
tycho.resolveDependencies(analysisRoot, tychoRoot.pom, excludes, analyzerConfig, emptyMap())
313-
314-
val slotArgs = slot<Array<String>>()
315-
verify {
316-
cli.doMain(capture(slotArgs), any(), any(), any())
317-
}
318-
319-
with(slotArgs.captured) {
320-
val indexPl = indexOf("-pl")
321-
indexPl shouldBeGreaterThan -1
322-
val excludedProjects = get(indexPl + 1).split(",")
323-
excludedProjects shouldContainExactlyInAnyOrder listOf(
324-
"!tycho-excluded-sub1",
325-
"!tycho-excluded-sub2",
326-
"!tycho-excluded-sub2/tycho-excluded-sub2-sub"
327-
)
328-
}
329-
}
330-
331-
"not add a -pl option if no projects are excluded" {
332-
val analysisRoot = tempdir()
333-
val tychoRoot = analysisRoot.createSubModule("tycho-root")
334-
tychoRoot.createSubModule("tycho-sub1")
335-
tychoRoot.createSubModule("tycho-sub2")
336-
val rootProject = createMavenProject("root", tychoRoot.pom)
337-
338-
val excludes = Excludes(paths = listOf(PathExclude("other-root/**", PathExcludeReason.EXAMPLE_OF)))
339-
val analyzerConfig = AnalyzerConfiguration(skipExcluded = true)
340-
341-
val tycho = spyk(Tycho())
342-
val cli = injectCliMock(tycho, listOf(rootProject).toJson(), listOf(rootProject))
343-
344-
tycho.resolveDependencies(analysisRoot, tychoRoot.pom, excludes, analyzerConfig, emptyMap())
345-
346-
val slotArgs = slot<Array<String>>()
347-
verify {
348-
cli.doMain(capture(slotArgs), any(), any(), any())
349-
}
350-
351-
slotArgs.captured.toList() shouldNot contain("-pl")
352-
}
353-
354-
"not exclude projects if skipExcluded is false" {
355-
val analysisRoot = tempdir()
356-
val tychoRoot = analysisRoot.createSubModule("tycho-root")
357-
tychoRoot.createSubModule("tycho-sub1")
358-
tychoRoot.createSubModule("tycho-sub2")
359-
tychoRoot.createSubModule("tycho-excluded-sub1")
360-
val rootProject = createMavenProject("root", tychoRoot.pom)
361-
362-
val excludes = Excludes(
363-
paths = listOf(PathExclude("tycho-root/tycho-excluded-sub1", PathExcludeReason.EXAMPLE_OF))
364-
)
365-
val analyzerConfig = AnalyzerConfiguration()
366-
367-
val tycho = spyk(Tycho())
368-
val cli = injectCliMock(tycho, listOf(rootProject).toJson(), listOf(rootProject))
369-
370-
tycho.resolveDependencies(analysisRoot, tychoRoot.pom, excludes, analyzerConfig, emptyMap())
371-
372-
val slotArgs = slot<Array<String>>()
373-
verify {
374-
cli.doMain(capture(slotArgs), any(), any(), any())
375-
}
376-
377-
slotArgs.captured.toList() shouldNot contain("-pl")
378-
}
379284
}
380285

381286
"tychoPackageResolverFunc()" should {
@@ -676,22 +581,6 @@ private fun injectCliMock(
676581
return cli
677582
}
678583

679-
/**
680-
* Return a reference to the Maven pom file in this folder.
681-
*/
682-
private val File.pom: File
683-
get() = resolve("pom.xml")
684-
685-
/**
686-
* Create a sub folder with the given [name] and a pom file to simulate a Maven module. Return the created folder
687-
* for the module.
688-
*/
689-
private fun File.createSubModule(name: String): File =
690-
resolve(name).apply {
691-
mkdirs()
692-
pom.also { it.writeText("pom-$name") }
693-
}
694-
695584
/** The test artifact used by many tests. */
696585
private val testArtifact = DefaultArtifact(TEST_GROUP_ID, TEST_ARTIFACT_ID, "jar", TEST_VERSION)
697586

0 commit comments

Comments
 (0)