feat: Add details about merging tiles

Extract a sample based on existing unit test
This commit is contained in:
Hack Kampbjørn 2024-12-18 10:18:18 +01:00 committed by Mark Derricutt
parent 239c9cbb4c
commit 6cb675f656
2 changed files with 155 additions and 4 deletions

View File

@ -218,7 +218,8 @@ been a bad idea. Get rid of it as soon as possible.
better idea here. Just don't use this section anywhere other than your actual artifact or composite poms.
Almost made a build smell:
- pluginmanagement - plugin management is used in parents to define all of the necessary options for a plugin but
- *pluginmanagement* - plugin management is used in parents to define all the necessary options for a plugin but
not have that plugin actually run during the release of the parent artifact, and also give the child the option of
running it. The reason this is bad is that it is mostly not necessary. You should split your plugins up into tiles
so that they be pulled into a build as a standalone set of functionality that will always run and be properly configured.
@ -237,9 +238,9 @@ If you need to use them, add them to your configuration section:
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.15</version>
<version>2.40</version>
<configuration>
<buildSmells>dependencymanagement, dependencies, repositories, pluginrepositories</buildSmells>
<buildSmells>dependencymanagement, dependencies, repositories, pluginrepositories, pluginmanagement</buildSmells>
<tiles>
<tile>groupid:antrun1-tile:1.1-SNAPSHOT</tile>
<tile>groupid:antrun2-tile:1.1-SNAPSHOT</tile>
@ -345,6 +346,156 @@ There are two mojos in the plugin, attach-tile and validate. attach-tile is only
process and attaches the tile.xml. validate is for your use to ensure your tile is valid before releasing it - this
ensures it can be read and any errors or warnings about content will appear.
== Merging Tiles
Tiles can provide configuration fragments to other tiles:
* tile-merge-source: a tile that contributes configuration fragments to other tiles
* tile-merge-target: a tile that can receive configuration fragments from other tiles
Source and target tiles are matched by execution id, so both should use `tiles-keep-id="true"`
Given a source tile with an configuration fragment adding an annotation processor path
[source,xml,indent=0]
.pom.xml
----
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<properties>
<dinject-generator.version>1.8</dinject-generator.version>
<tile-merge-source>true</tile-merge-source>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>kapt</id>
<configuration tiles-keep-id="true">
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>io.dinject</groupId>
<artifactId>dinject-generator</artifactId>
<version>${dinject-generator.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
----
And a target tile marked as such and accepting configuration fragments under `tiles-append`
[source,xml,indent=0]
.pom.xml
----
<project>
<modelVersion>4.0.0</modelVersion>
<properties>
<tile-merge-target>true</tile-merge-target>
<kotlin.version>1.3.31</kotlin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration tiles-keep-id="true" tiles-append="annotationProcessorPaths">
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/main/java</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<!-- annotation processors added here -->
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
----
then these tiles can be combined into a single tile, where:
* the `tile-merge-target` and `tile-merge-source` properties are removed and remaining properties are merged.
* and `tiles-append` configuration node from the source tile is added to the target tile
[source,xml,indent=0]
.pom.xml
----
<project>
<modelVersion>4.0.0</modelVersion>
<properties>
<kotlin.version>1.3.31</kotlin.version>
<dinject-generator.version>1.8</dinject-generator.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration tiles-keep-id="true" tiles-append="annotationProcessorPaths">
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/main/java</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<!-- annotation processors added here -->
<annotationProcessorPath>
<groupId>io.dinject</groupId>
<artifactId>dinject-generator</artifactId>
<version>${dinject-generator.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
----
=== Limitations of Merging Tiles
* only execution configuration can be merged, other details like default configuration will not be merged
* the `tiles-append` is a name of a child node under execution configuration, it is not a path or a list
* the `tiles-append` node must be present in the target tile, else merging will be skipped
* only a single fragment can be merged, in the example above we cannot also merge the `annotationProcessors` names
== Additional Notes
Some interesting notes:

View File

@ -126,7 +126,7 @@ been a bad idea. Get rid of it as soon as possible.
better idea here. Just dont use this section anywhere other than your actual artifact or composite poms.
Almost made a build smell:
- pluginmanagement - plugin management is used in parents to define all of the necessary options for a plugin but
- **pluginmanagement** - plugin management is used in parents to define all of the necessary options for a plugin but
not have that plugin actually run during the release of the parent artifact, and also give the child the option of
running it. The reason this is bad is that it is mostly not necessary. You should split your plugins up into tiles
so that they be pulled into a build as a standalone set of functionality that will always run and be properly configured.