The build lifecycle implemented for the first alpha has been extremely helpful, but there are some remaining tasks to allow it to be a complete replacement for the goal graph of Maven 1.x.

Defining the lifecycle according to packaging

I think it is worthwhile defining the lifecycle by the packaging, so the phases are fixed, but their mapping to goals are defined as configuration inside the artifact type handler. For example, this allows a plugin artifact to bind the plugin:descriptor goal automatically. It also allows a packaging of pom to not register any of the goals other than install/deploy.

The alternative is to always register them, disregarding the type, and use the type as a mojo execution guard - but I think this might be less clean in this particular case.

Solution

For per-packaging lifecycles, we can do this with plexus configuration, so a PackagingHandler can specify a lifecycle as configuration, but there will be a default (which is what is there now). It is a replacement lifecycle, not an overlay.

Lifecycle execution

I think the best solution for executions was:
@execute phase="..." lifecycle="some ID"
where phase should be replaced by a name that represents whatever we call phases/goals as a combination (task?)
the lifecycle ID will be inside a /META-INF/maven/lifecycles.xml file

Lifecycle Use Cases

The proposed changes are to allow a parallel lifecycle to execute for certain goals, gathering the end results but not mixing in the lifecycle elements and changed parameters with the existing lifecycle.

So far, we have the @executePhase tag which does this - eg in idea:idea to execute generate-sources first.

Here, we look at a few use cases and how they might work with the proposed changes.

Use cases:

  1. plexus application use case
  2. idea:idea running generate-sources (defined by the mojo)
  3. clover running tests
  4. jcoverage, modifying class files
  5. reports running tests, etc

Plexus application

want to be able to run "plexus:app plexus:bundle-application plexus:test-runtime"

plexus:app and plexus:bundle-application are analogous to war:exploded and war:war, so it would be better there for:

  1. app and bundle to share the same logic, so app is run for a quick deployment, but bundle is all that is actually needed
  2. plexus:bundle-application be the goal used for "package" when type = plexus-application

plexus:test-runtime is like making an assembly. "package" would be the executePhase for this goal, unless it were intended to be attached like an assembly is (though the assembly plugin is probably capable of doing that on its own)

idea:idea running generate-sources

This is covered by the current addition of @executePhase to the mojo declaration, so that generate-sources is
always run before the execution of idea:idea as a new lifecycle instance, with the results that affect the project
(ie the addition of a new compile source root) still applies afterwards.

The project used needs to be a clone that lasts the life of the executed lifecycle and the idea:idea goal, but
goes back to normal afterwards so the effects don't hit other goals.

Clover use case

M1 plugin:

Desired use: m2 clover:clover

  1. register clover compiler goal into generate-sources
  2. modify output directory
  3. run test (based on executePhase)
  4. report database later reused

register clover compiler goal into generate-sources

modify output directory

run test

How to bind the clover compiler goal:

@goal clover
@executePhase test

META-INF/maven/lifecycle.xml (one per plugin - could it be in plugin.xml?)

<lifecycle>
  <phase>
    <id>generate-sources</id>
    <goals>
      <goal>
        <id>clover:compile</id>
      </goal>
    </goals>
  </phase>
</lifecycle>
@goal compile
@parameter name="outputDirectory" expression="$\{project.build.directory\}/generated-sources/clover"

Jcoverage use case

Different to clover in that it modifies classes rather than adding compiled classes. Still not looking at the reporting
case just yet.

Desired use: m2 jcoverage:jcoverage

  1. register jcoverage:instrument goal for process-classes
  2. modify classpath for test running
  3. run test
  4. report database later reused

register jcoverage:instrument goal for process-classes

modify classpath for test running

run test

How to bind:

@goal jcoverage
@executePhase test

META-INF/maven/lifecycle.xml (one per plugin - could it be in plugin.xml?)

<lifecycle>
  <phase>
    <id>process-classes</id>
    <goals>
      <goal>
        <id>jcoverage:instrument</id>
      </goal>
    </goals>
  </phase>
  <!-- ... -->
  <phase>
    <id>test</id>
    <goals>
      <goal>
        <id>surefire:test</id>
        <configuration>
          <!-- This assumes this is used instead of adding a runtime classpath element, which might be a good idea -->
          <classesDirectory>${project.build.directory}/generated-classes/jcoverage</classesDirectory>
          <ignoreFailures>true</ignoreFailures>
        </configuration>
      </goal>
    </goals>
  </phase>
</lifecycle>
@goal instrument
@parameter name="outputDirectory" expression="$\{project.build.directory\}/generated-classes/jcoverage"

Other reporting

Do other reports require anything additional?
junit-report:

pmd:

overall site:

Random notes