The lifecycle plugin defines abstract targets defining the build lifecycle of a module, including compile, test, package and install. Other plugins implement such targets, providing the actual functionality.
The lifecycle plugin is central to building projects with quokka. The plugin itself is entirely abstract. i.e. including the plugin on it's own doesn't actually do anything that effects your project files. Instead, it defines an abstract framework that other plugins implement. For example, the lifecycle plugin defines the abstract compile target that Javac plugin implements.
The lifecycle targets are organised as a chain of dependencies. The following lists the targets in order. If you execute any target in the list, all targets that proceed it get executed.
For example, if you execute process-sources, the project build sequence will be initialise, then generate-sources, followed by process-sources
Continuing the example of Javac plugin, let's consider what happens when the Javac plugin implements compile. If you consult the Javac plugin documentation you will see that it declares a target javac:compile that implements lifecycle:compile. When quokka encounters an implements declaration during initialisation, it rewires the target dependencies as follows:
So in the case adding the Javac plugin, the modified build sequence becomes:
This mechanism is quite flexible as it allows the user to continue using the abstract target name of compile regardless of what implementations are available. However, it also exposes the javac:compile to the user for direct access if desired.
There is one detail missing for the above description, namely pre-targets. If you look at the real sequence below you will notice that every lifecycle target is proceed by a target of the same name prefixed by pre-.
So the real build sequence is actually:
Why the extra targets? They are there so the users can reliably insert additional ad hoc targets into the build sequence. For example, let's assume the user wants insert a target between compile and process-resources
Without the pre-targets, they would have to refer to the javac target as follows:
<target name="mytarget" depends="process-resources" dependency-of="javac:compile">
This is problematic because there may be no implementations, or multiple implementations (whose order is undefined), or may break if an additional implementation is added. Using pre-targets, these problems are avoided completely with the delcaration becoming:
<target name="mytarget" depends="process-resources" dependency-of="pre-compile">
The other important aspect to the lifecycle plugin is that it defines some important project paths and controls how they are merged. The following paths are defined:
| id | Description | Descends Default |
| compile | Compilation class path | false |
| test-compile | Tests compilation class path | false |
| test | Tests runtime class path | true |
| itest | Integration tests runtime class path | true |
| runtime | Runtime class path | true |
The descends default value controls whether transitive dependendencies (dependencies of dependencies) are added when you add a dependency to a path. See here for more information.
Targets merge the above paths as follows:
| Target | Merged Paths |
| compile | compile |
| test-compile | test-compile, compile |
| test | test, test-compile, compile, ${q.lifecycle.testPaths}* |
| integration-test-impl | itest, test, test-compile, compile, ${q.lifecycle.itestPaths}* |
* The q.lifecycle.testPaths/itestPaths entries are an elaborate means of adding the runtime paths to the merged testing paths. By default, q.lifecycle.testPaths/itestPaths are defined to be the value of q.project.exportedPaths. q.project.exportedPaths contains any project paths that you are exporting to the repository, which is usually runtime.
Why all this indirection? The reason is that quokka (and it's repositories) supports multiple runtime paths. By default Quokka defines a path with an id of runtime. However, this is just a convenience and users are free to ignore it.
Notes for Maven users:
There are some important differences between how Quokka and Maven handle project paths:
<dependency group="quokka.core.plugin-spi" version="?" paths="compile(bootstrap-util), runtime"/>
Overriding the defaults
The defaults in Quokka are designed to be strict to enforce all dependencies to be declared. However, you can override the defaults simply if you don't like them using path specifications. Here's some examples:
<dependency group="apache.ant" version="1.7.1" paths="runtime+"/>
<dependency group="apache.ant" version="1.7.1" paths="test-compile<"/>
| clean | Cleans the project, deleting all generated files |
| pre-initialise | |
| initialise | Initialisation hook for plugins |
| pre-generate-sources | |
| generate-sources | Generate any source code for inclusion in compilation |
| pre-process-sources | |
| process-sources | Process the source code, for example to filter any values |
| pre-generate-resources | |
| generate-resources | Generate resources for inclusion in the package |
| pre-process-resources | |
| process-resources | Copy and process the resources into the destination directory, ready for packaging |
| pre-compile | |
| compile | Compile the source code of the project |
| pre-process-compiled | |
| process-compiled | Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes |
| pre-instrument-compiled | |
| instrument-compiled | Instruments compiled classes for code coverage |
| pre-generate-test-sources | |
| generate-test-sources | Generate any test source code for inclusion in compilation |
| pre-process-test-sources | |
| process-test-sources | Process the test source code, for example to filter any values |
| pre-generate-test-resources | |
| generate-test-resources | Create resources for testing |
| pre-process-test-resources | |
| process-test-resources | Copy and process the resources into the test destination directory |
| pre-test-compile | |
| test-compile | Compile the test source code into the test destination directory |
| pre-test | |
| test | Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed |
| pre-package | |
| package | Take the compiled code and package it in its distributable format, such as a JAR |
| pre-initialise-integration-test | |
| initialise-integration-test | |
| pre-integration-test-impl | |
| integration-test-impl | Abstract target that plugins that implement integration tests should implement |
| pre-finalise-integration-test | |
| finalise-integration-test | |
| integration-test | Process and deploy the package if necessary into an environment where integration tests can be run |
| pre-verify | |
| verify | Run any checks to verify the package is valid and meets quality criteria |
| pre-install | |
| install | Install the package into the local repository, for use as a dependency in other projects locally |
| q.lifecycle.compileOutput | ${q.project.targetDir}/compile | |
| q.lifecycle.resourcesOutput | ${q.lifecycle.compileOutput} | |
| q.lifecycle.packageOutput | ${q.project.targetDir}/package | |
| q.lifecycle.testCompileOutput | ${q.project.targetDir}/test-compile | |
| q.lifecycle.instrumentCompiledOutput | ${q.project.targetDir}/instrumented-compile | |
| q.lifecycle.testResourcesOutput | ${q.lifecycle.testCompileOutput} |
Generate any source code for inclusion in compilation
Process the source code, for example to filter any values
Generate resources for inclusion in the package
Copy and process the resources into the destination directory, ready for packaging
Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes
Instruments compiled classes for code coverage
Generate any test source code for inclusion in compilation
Process the test source code, for example to filter any values
Create resources for testing
Copy and process the resources into the test destination directory
Compile the test source code into the test destination directory
Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
Default Properties
| q.lifecycle.testPaths | ${q.project.exportedPaths} |
Take the compiled code and package it in its distributable format, such as a JAR
Abstract target that plugins that implement integration tests should implement
Default Properties
| q.lifecycle.itestPaths | ${q.project.exportedPaths} |
Process and deploy the package if necessary into an environment where integration tests can be run
Run any checks to verify the package is valid and meets quality criteria
Install the package into the local repository, for use as a dependency in other projects locally
runtime : Runtime class path
quokka.core.plugin-spi plugin-spi 0.3
quokka.core.bootstrap-util bootstrap-util 0.3
apache.ant ant 1.7.1