Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-T4
-Dtycho.localArtifacts=ignore
-Dtycho.version=5.0.2
-Dtycho.pomless.parent=${maven.multiModuleProjectDirectory}
99 changes: 99 additions & 0 deletions PomlessAggregator.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
= Pomless aggregators with Tycho
:toc: left
:toclevels: 2
:icons: font
:source-highlighter: rouge

== What this repository demonstrates

Tycho's `tycho-build` extension can derive a Maven model for a bundle, feature, product or update site from the files that already describe it, so most modules here have no `pom.xml`.
The same mechanism can also derive an *aggregator*, which is what this repository uses to keep the module list out of the root `pom.xml`.

Two variants are shown:

`build/pom.tycho`:: The reactor module list. The root `pom.xml` declares a single module, and the real list lives in a plain text file.
`lsp/pom.tycho`:: A group of related bundles collected in their own folder, listed by an aggregator of their own.

== How it works

A folder containing a file named `pom.tycho` is turned into an aggregator with packaging `pom`.
The artifactId is the folder name, and every non-comment line becomes a `<module>` entry.

.build/pom.tycho
[source]
----
# "#" comments and blank lines are ignored
../com.vogella.ide.first
../lsp
----

Because the lines are used verbatim, they may point outside the aggregator's own folder.
That is what allows `build/` to reference bundles that sit at the repository root.

The root `pom.xml` keeps everything else it needs to keep, and shrinks to:

[source,xml]
----
<modules>
<module>build</module>
</modules>
----

NOTE: A `pom.tycho` is only read in a folder that has no `pom.xml`.
Where both exist the `pom.xml` always wins, so the root pom cannot source its own module list this way.
That is why the indirection through `build/` is needed.

=== Automatic detection

If a folder is named `bundles`, `plugins`, `tests`, `features`, `sites`, `products` or `releng`, Tycho scans its subfolders and generates the module list without any file at all.
The list of names is configurable with `-Dtycho.pomless.aggregator.names`.

This repository deliberately uses an explicit `lsp/pom.tycho` instead, for two reasons.
The folder name `lsp` says what the group is, and an explicit list keeps the ability to disable a single module by commenting out one line.
Automatic detection always takes every subfolder it finds.

TIP: Tycho writes its generated `pom.tycho` files with a `## tycho automatic module detection <uuid>` first line and deletes them when the JVM exits.
A hand-written file simply must not start with that marker.

== Required configuration

Two settings make the nested layout work.

..mvn/maven.config
[source]
----
-Dtycho.pomless.parent=${maven.multiModuleProjectDirectory}
----

By default a pomless module looks for its parent in `..`.
That holds for a bundle at the repository root, but not for one nested inside `lsp/`, which would look in `lsp/` and find nothing.
Pointing the property at the directory that contains `.mvn` makes every pomless module resolve the root pom as its parent, whatever its depth.
`maven.multiModuleProjectDirectory` is resolved by Maven itself, so the setting keeps working when the build is started from a subdirectory.

The same property can be set per module, as `tycho.pomless.parent` in a bundle's `build.properties`, which takes precedence over the global default.

.pom.xml
[source,xml]
----
<file>${maven.multiModuleProjectDirectory}/target-platform/target-platform.target</file>
----

The target definition was previously referenced as `../target-platform/target-platform.target`.
That path is resolved against each module's own directory, so it breaks for a module one level deeper.
An absolute path avoids the problem for good.

== Trade-offs

The module list is no longer XML, comments are cheaper, and related bundles can be grouped without the root pom growing.
Set against that, the list is no longer where a reader expects it, and `build/` exists only as an indirection.
For a repository with a handful of modules that is a poor trade.
It starts paying off at the scale of this one, where nearly every module is pomless already.

== Building

Nothing changes for the caller:

[source,bash]
----
./mvnw clean verify
----
46 changes: 46 additions & 0 deletions build/pom.tycho
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# The reactor module list.
#
# Tycho's pomless build turns this file into an aggregator (packaging=pom,
# artifactId "build"), so the root pom.xml only needs a single <module>build</module>
# entry instead of one line per bundle. Paths are relative to this folder,
# hence the "../" prefix for everything that lives at the repository root.
#
# "#" comments and blank lines are ignored, which makes temporarily disabling
# a module a one-character edit.

../com.vogella.ide.first
../com.vogella.ide.feature
../com.vogella.tasks.model
../com.vogella.tasks.services
../com.vogella.tasks.ui
../com.vogella.ide.editor.tasks
../com.vogella.contribute.parts
../com.vogella.swt.widgets
../com.vogella.tasks.events
../com.vogella.eclipse.css

../com.vogella.resources
../com.vogella.adapters
../com.vogella.tasks.extendedsupplier
../com.vogella.preferences.page
../com.vogella.ide.editor.gradle
../com.vogella.ide.editor.asciidoc
../com.vogella.ide.editor.shell
../com.vogella.ide.debugtools

# Language server example, grouped in its own folder with its own pom.tycho
../lsp

../z.ex.search
../com.vogella.ide.iconreplacer
../com.vogella.ide.parallelstart
../com.vogella.json.validation

# Tests
../com.vogella.json.validation.tests
# ../com.vogella.tasks.services.tests

../updatesite

# releng
# ../com.vogella.ide.product
12 changes: 12 additions & 0 deletions lsp/pom.tycho
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Modules of the "lsp" aggregator.
#
# This file replaces an lsp/pom.xml. Tycho's pomless build reads it and
# generates an aggregator with packaging=pom and artifactId "lsp" (the folder
# name). One module per line, "#" comments and blank lines are ignored.
#
# An explicit list is required here because "lsp" is not one of the folder
# names Tycho scans automatically (bundles, plugins, tests, features, sites,
# products, releng).
com.vogella.lsp.asciidoc.client
com.vogella.lsp.asciidoc.server
com.vogella.lsp.asciidoc.server.tests
42 changes: 3 additions & 39 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<version>${tycho.version}</version>
<configuration>
<target>
<file>../target-platform/target-platform.target</file>
<file>${maven.multiModuleProjectDirectory}/target-platform/target-platform.target</file>
</target>
<!-- Optional set the Java version your are using-->
<executionEnvironment>JavaSE-25</executionEnvironment>
Expand All @@ -115,43 +115,7 @@
</plugins>
</build>
<modules>
<module>com.vogella.ide.first</module>
<module>com.vogella.ide.feature</module>
<module>com.vogella.tasks.model</module>
<module>com.vogella.tasks.services</module>
<module>com.vogella.tasks.ui</module>
<module>com.vogella.ide.editor.tasks</module>
<module>com.vogella.contribute.parts</module>
<module>com.vogella.swt.widgets</module>
<module>com.vogella.tasks.events</module>
<module>com.vogella.eclipse.css</module>
<!---->
<module>com.vogella.resources</module>
<module>com.vogella.adapters</module>
<module>com.vogella.tasks.extendedsupplier</module>
<module>com.vogella.preferences.page</module>
<module>com.vogella.ide.editor.gradle</module>
<module>com.vogella.ide.editor.asciidoc</module>
<module>com.vogella.ide.editor.shell</module>
<module>com.vogella.ide.debugtools</module>
<module>com.vogella.lsp.asciidoc.client</module>
<module>com.vogella.lsp.asciidoc.server</module>
<module>com.vogella.lsp.asciidoc.server.tests</module>
<module>z.ex.search</module>
<module>com.vogella.ide.iconreplacer</module>
<module>com.vogella.ide.parallelstart</module>
<module>com.vogella.json.validation</module>

<!--Tests-->
<module>com.vogella.json.validation.tests</module>
<!--

<module>com.vogella.tasks.services.tests</module>
-->
<module>updatesite</module>
<!--releng-->
<!-- <module>com.vogella.ide.product</module> -->


<!-- The real module list lives in build/pom.tycho -->
<module>build</module>
</modules>
</project>
Loading