Richard Vowles 4ef1859d3d Fix #17 - allow for non transitive dependencies
As discussed. Has real tests, doesn't have integration tests
but will make that another ticket.

Change-Id: I9ae5e32b12cf07e5e782f7bb8d37815c06e62837
2014-08-01 10:36:17 +12:00
2014-08-01 10:36:17 +12:00

= Tiles Maven Plugin

== Overview

The _tiles-maven-plugin_ is a Maven Plugin that tries to bringing the *composition* that is available to
dependencies to the parent structure as well.

https://buildhive.cloudbees.com/job/rvowles/job/maven-tiles/[Build Status]

[[img-sunset]]
image::https://buildhive.cloudbees.com/job/rvowles/job/maven-tiles/badge/icon[caption="Cloudbees Build Status"]

== How do I make a Maven Tile?

Tiles are https://github.com/maoo/maven-tiles-examples/tree/master/tiles[plain Maven pom artifacts] which contain
parts of a Maven POM; every tile can contain

- build data, for example the license tags that a company wants to report on all their artifacts
- build aspects, for example the configurations of a plugin, such as Groovy, Java or Clojure.
- release aspects, for example the distribution management section
- references to other tiles

This could, for example, allow you to have build aspects consistent across your organisation and open sourced, and the
distribution of internal vs external artifacts kept in a single tile. In the current single parent hierarchy, this
is all duplicated.

== Composing a Maven Tile

A Maven Tile is made up of a pom.xml and a tile.xml. The pom.xml contains the normal release information. When using
tiles, this would be the name/groupId/artifactId/version/description/packaging(tile) and generally only a declaration
of the Maven Tiles plugin. Only if you are using a tile (and generally you use at least one - the release tile) will
you specify a configuration.

[source,xml,indent=0]
.pom.xml
----
<project>
  <groupId>com.bluetrainsoftware.tiles</groupId>
  <artifactId>license-tile</artifactId>
  <version>1.1-SNAPSHOT</version>
  <packaging>tile</packaging>
  <description>Contains consistent license information.</description>

  <build>
    <plugins>
      <plugin>
        <groupId>com.bluetrainsoftware.maven</groupId>
        <artifactId>tiles-maven-plugin</artifactId>
        <version>1.1</version>
        <extensions>true</extensions>
        <configuration>
          <tiles>
            <tile>com.bluetraisoftware.tiles:github-release-tile:[1.1, 2)</tile>
          </tiles>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
----

With the packaging _tile_, the plugin will look for the attached tile.xml, do some basic validation on it and
attach it as an artifact.

[source.xml,indent=0]
.tile.xml
----
<?xml version="1.0" encoding="UTF-8"?>
<project>
  <licenses>
    <license>
      <name>The Apache Software License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

</project>
----

A tile can define the tiles plugin if it wishes to cascade tile inclusion.

== Composing Build functionality

As a use case, an example of how it will be used for my projects.

I will have:

- *groovy-tile* - which defines the build structure necessary to build a Groovy project, including GMavenPlus, GroovyDoc
and Source plugins
- *java-tile* - for Java only projects which include all the Javadoc and Source plugins
- *s3-tile* - for our Servlet3 modules, which includes Sass, JSP compilation and Karma plugins and depends on the groovy-tile
- *github-release-tile* - for artifacts that release to Github (open source)
- *nexus-release-tile* - for artifacts that release to our local Nexus (not open source)

This allows me to open source all my tiles except for the nexus tile, and then decide in the final artifact where I will
release it.

== Additional Notes

Some interesting notes:

- Tiles support version ranges, so use them. [1.1, 2) allows you to update and release new versions of tiles and have them
propagate out. Maven 3.2.2 allows this with the version ranges in parents, but it isn't a good solution because of single
inheritance.
- You can include as many tiles as you like in a pom and poms can refer to other tiles. The plugin will search through
the poms, telling you which ones it is picking up and then load their configurations in *reverse order*. This means the
poms _closer_ to your artifact get their definitions being the most important ones. If you have duplicate plugins, the one
closest to your pom wins.
- String interpolation for properties works. The plugin first walks the tree of tiles collecting all properties, merges them
together (closest wins), and then reloads the poms and interpolates them. This means all string replacement in plugins and
dependencies works as expected.
- Plugin execution is merged - if you have the same plugin in two different tiles define two different executions, they will
merge.
- The tiles-maven-plugin is _not a plugin the traditional sense_. It does not implement any Mojos and has no Goals. It
  only executes as a Lifecycle Participant, and as such it has no sensible executions, so they are not supported.
- The plugin works fine with alternative packaging. It has been tested with war, grails-plugin and grails-app.


== Final Notes

Tiles-Maven works best when *you* and *your team* own the tiles. I don't recommend relying on open source tiles, always
create your own versions and always lock down versions of third party tiles, just like you would third party dependencies.

== Read More

- https://github.com/maoo/maven-tiles[The Original Tiles Maven plugin] - although the essential start point is the same, the code is significantly different.
- http://jira.codehaus.org/browse/MNG-5102[Mixin POM fragments]
- http://stackoverflow.com/questions/11749375/import-maven-plugin-configuration-by-composition-rather-than-inheritance-can-it[Stack Overflow]
- http://maven.40175.n5.nabble.com/Moving-forward-with-mixins-tc4421069.html[Maven Discussion]


Description
No description provided
Readme 1.1 MiB
Languages
Groovy 99.9%
Java 0.1%