Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

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. This For example, this allows a plugin artifact to add a 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

  • we went for a separate xml file instead of java code to be able to easily visualise it
  • the lifecycle in here is overlaid on the existing one when the forked goal is called
  • I've decided to aggregate them in one file for simplicity rather than having per mojo files
  • I don't think we can use plexus configuration here because it would require an assumption in AbstractMojo

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. assembly:assembly running package (defined by the project)
  4. clover running tests
  5. jcoverage, modifying class files
  6. reports running tests, etc

...

plexus:test-runtime is like making an assembly. It would be wired in as the "executePhase" for assembly:assembly (see
below), and in turn "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

...

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.

assembly:assembly running package (defined by the project)

This can be covered by the addition of <executePhase/> to the goal configuration, ie:

...


<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <executePhase>package</executePhase>
  <configuration>
    ...
  </configuration>
</plugin>

Here, this would override anything specified on the mojo using @executePhase, if applicable, but otherwise would
behave identically.

Clover use case

M1 plugin:

...

Do other reports require anything additional?
junit-report:

  • this executes the test goal, no change in parameters

pmd:

  • standard report
  • will use generated sources so needs to ensure this has been run
  • might also fail based on certain threshold
  • all fits

overall site:

  • is this a new lifecycle, or does it run each goal on its own based on the registered reports? I believe it is the
    latter.

Random notes

  • does executePhase need something that indicates "pre" in the name?
  • did we decide on something like an around notation AOP style for the lifecycle?
  • do we really execute a lifecycle, or just require to avoid re-executing?
    • this would avoid running test:test again
    • theoretically, test:test should be smart enough not to run again anyway
    • this could get back to the @prereq situation to some extent
    • how is it actullay run if it hasn't been already? forked lifecycle? Is this a little inconsistent?
    • common use is generated-sources which might not be fast to run over and over
    • here I would like to flatten down the lifecycle
    • still means getting back to a @requires style notation, and auto-ordering seems dangerous
    • perhaps it isn't doing any ordering? All the reports are in a bucket that are in the right place, and only
      required phases get activated?
    • or does it start from a blank lifecycle and each additional goal overlays additional stuff?
    • does this cause a risk of things not working because there are now three test executions, each with different
      parameters?
    • can we instead do the forked execution, but make use of the execution strategies so things still only execute once
      with identical parameters?
    • but what if another goal modifies some of its parameters?
    • general behaviour is that if something is specified twice now, it is run twice, because of the removal of prereqs
    • inclined to say we do the forking here for now at least.
  • @phase vs. lifecycle declaration is a bit arbitrary. eg, should resources:resources always be part of
    process-resources? Why not use the @phase and somehow trigger it's inclusion?
  • encapsulate all transfer in mojo fields, use OGNL to translate back to project
    • how would this be specified? does each field that exports provide an @export tag, or does it have an
      in, out, inout specifier? (urgh, CORBA flashback!)