Skip to content

Commit acec540

Browse files
authored
[MNG-8052] New lifecycle for Maven 4 (#1448)
1 parent 9bc5cc8 commit acec540

File tree

24 files changed

+1001
-110
lines changed

24 files changed

+1001
-110
lines changed

api/maven-api-core/src/main/java/org/apache/maven/api/Lifecycle.java

Lines changed: 121 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import java.util.Collection;
2222
import java.util.List;
2323
import java.util.Optional;
24+
import java.util.stream.Stream;
2425

2526
import org.apache.maven.api.annotations.Experimental;
2627
import org.apache.maven.api.annotations.Immutable;
28+
import org.apache.maven.api.annotations.Nonnull;
2729
import org.apache.maven.api.model.Plugin;
2830

2931
/**
@@ -41,14 +43,20 @@
4143
@Immutable
4244
public interface Lifecycle extends ExtensibleEnum {
4345

46+
// =========================
47+
// Maven defined lifecycles
48+
// =========================
4449
String CLEAN = "clean";
45-
4650
String DEFAULT = "default";
47-
4851
String SITE = "site";
49-
5052
String WRAPPER = "wrapper";
5153

54+
// ======================
55+
// Phase qualifiers
56+
// ======================
57+
String BEFORE = "before:";
58+
String AFTER = "after:";
59+
5260
/**
5361
* Name or identifier of this lifecycle.
5462
*
@@ -62,6 +70,18 @@ public interface Lifecycle extends ExtensibleEnum {
6270
*/
6371
Collection<Phase> phases();
6472

73+
/**
74+
* Stream of phases containing all child phases recursively.
75+
*/
76+
default Stream<Phase> allPhases() {
77+
return phases().stream().flatMap(Phase::allPhases);
78+
}
79+
80+
/**
81+
* Collection of aliases.
82+
*/
83+
Collection<Alias> aliases();
84+
6585
/**
6686
* Pre-ordered list of phases.
6787
* If not provided, a default order will be computed.
@@ -72,10 +92,108 @@ default Optional<List<String>> orderedPhases() {
7292

7393
/**
7494
* A phase in the lifecycle.
95+
*
96+
* A phase is identified by its name. It also contains a list of plugins bound to that phase,
97+
* a list of {@link Link links}, and a list of sub-phases. This forms a tree of phases.
7598
*/
7699
interface Phase {
100+
101+
// ======================
102+
// Maven defined phases
103+
// ======================
104+
String BUILD = "build";
105+
String INITIALIZE = "initialize";
106+
String VALIDATE = "validate";
107+
String SOURCES = "sources";
108+
String RESOURCES = "resources";
109+
String COMPILE = "compile";
110+
String READY = "ready";
111+
String PACKAGE = "package";
112+
String VERIFY = "verify";
113+
String UNIT_TEST = "unit-test";
114+
String TEST_SOURCES = "test-sources";
115+
String TEST_RESOURCES = "test-resources";
116+
String TEST_COMPILE = "test-compile";
117+
String TEST = "test";
118+
String INTEGRATION_TEST = "integration-test";
119+
String INSTALL = "install";
120+
String DEPLOY = "deploy";
121+
String CLEAN = "clean";
122+
123+
@Nonnull
77124
String name();
78125

126+
@Nonnull
79127
List<Plugin> plugins();
128+
129+
@Nonnull
130+
Collection<Link> links();
131+
132+
/**
133+
* {@return the list of sub-phases}
134+
*/
135+
@Nonnull
136+
List<Phase> phases();
137+
138+
@Nonnull
139+
Stream<Phase> allPhases();
140+
}
141+
142+
/**
143+
* A phase alias, mostly used to support the Maven 3 phases which are mapped
144+
* to dynamic phases in Maven 4.
145+
*/
146+
interface Alias {
147+
String v3Phase();
148+
149+
String v4Phase();
150+
}
151+
152+
/**
153+
* A link from a phase to another phase, consisting of a type which can be
154+
* {@link Kind#BEFORE} or {@link Kind#AFTER}, and a {@link Pointer} to
155+
* another phase.
156+
*/
157+
interface Link {
158+
enum Kind {
159+
BEFORE,
160+
AFTER
161+
}
162+
163+
Kind kind();
164+
165+
Pointer pointer();
166+
}
167+
168+
interface Pointer {
169+
enum Type {
170+
PROJECT,
171+
DEPENDENCIES,
172+
CHILDREN
173+
}
174+
175+
String phase();
176+
177+
Type type();
178+
}
179+
180+
interface PhasePointer extends Pointer {
181+
default Type type() {
182+
return Type.PROJECT;
183+
}
184+
}
185+
186+
interface DependenciesPointer extends Pointer {
187+
String scope(); // default: all
188+
189+
default Type type() {
190+
return Type.DEPENDENCIES;
191+
}
192+
}
193+
194+
interface ChildrenPointer extends Pointer {
195+
default Type type() {
196+
return Type.CHILDREN;
197+
}
80198
}
81199
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.api.plugin.annotations;
20+
21+
import java.lang.annotation.Documented;
22+
import java.lang.annotation.ElementType;
23+
import java.lang.annotation.Inherited;
24+
import java.lang.annotation.Retention;
25+
import java.lang.annotation.RetentionPolicy;
26+
import java.lang.annotation.Target;
27+
28+
import org.apache.maven.api.annotations.Experimental;
29+
30+
/**
31+
* Specifies that the mojo should be run after the specific phase.
32+
*
33+
* @since 4.0.0
34+
*/
35+
@Experimental
36+
@Documented
37+
@Retention(RetentionPolicy.RUNTIME)
38+
@Target(ElementType.TYPE)
39+
@Inherited
40+
public @interface After {
41+
42+
/**
43+
* Type of pointer.
44+
* @see org.apache.maven.api.Lifecycle.Pointer.Type
45+
*/
46+
enum Type {
47+
PROJECT,
48+
DEPENDENCIES,
49+
CHILDREN
50+
}
51+
52+
/**
53+
* The phase name.
54+
*/
55+
String phase();
56+
57+
/**
58+
* The type of this pointer.
59+
*/
60+
Type type();
61+
62+
/**
63+
* The scope for dependencies, only if {@code type() == Type.Dependencies}.
64+
*/
65+
String scope() default "";
66+
}

api/maven-api-core/src/main/java/org/apache/maven/api/services/LifecycleRegistry.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.apache.maven.api.services;
2020

21+
import java.util.List;
2122
import java.util.stream.Stream;
2223
import java.util.stream.StreamSupport;
2324

@@ -28,4 +29,6 @@ public interface LifecycleRegistry extends ExtensibleEnumRegistry<Lifecycle>, It
2829
default Stream<Lifecycle> stream() {
2930
return StreamSupport.stream(spliterator(), false);
3031
}
32+
33+
List<String> computePhases(Lifecycle lifecycle);
3134
}

api/maven-api-plugin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ under the License.
9494
<phase>generate-sources</phase>
9595
<configuration>
9696
<velocityBasedir>${project.basedir}/../../src/mdo</velocityBasedir>
97-
<version>1.0.0</version>
97+
<version>2.0.0</version>
9898
<models>
9999
<model>src/main/mdo/lifecycle.mdo</model>
100100
</models>

api/maven-api-plugin/src/main/mdo/lifecycle.mdo

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ under the License.
3030
<classes>
3131
<class rootElement="true" xml.tagName="lifecycles" xsd.compositor="sequence">
3232
<name>LifecycleConfiguration</name>
33-
<version>1.0.0</version>
33+
<version>1.0.0+</version>
3434
<description>Root element of the {@code lifecycle.xml} file.</description>
3535
<fields>
3636
<field>
3737
<name>lifecycles</name>
38-
<version>1.0.0</version>
38+
<version>1.0.0+</version>
3939
<association xml.itemsStyle="flat">
4040
<type>Lifecycle</type>
4141
<multiplicity>*</multiplicity>
@@ -45,19 +45,19 @@ under the License.
4545
</class>
4646
<class>
4747
<name>Lifecycle</name>
48-
<version>1.0.0</version>
48+
<version>1.0.0+</version>
4949
<description>A custom lifecycle mapping definition.</description>
5050
<fields>
5151
<field>
5252
<name>id</name>
5353
<required>true</required>
54-
<version>1.0.0</version>
54+
<version>1.0.0+</version>
5555
<type>String</type>
5656
<description>The ID of this lifecycle, for identification in the mojo descriptor.</description>
5757
</field>
5858
<field>
5959
<name>phases</name>
60-
<version>1.0.0</version>
60+
<version>1.0.0+</version>
6161
<description>The phase mappings for this lifecycle.</description>
6262
<association>
6363
<type>Phase</type>
@@ -68,19 +68,35 @@ under the License.
6868
</class>
6969
<class>
7070
<name>Phase</name>
71-
<version>1.0.0</version>
71+
<version>1.0.0+</version>
7272
<description>A phase mapping definition.</description>
7373
<fields>
7474
<field>
7575
<name>id</name>
7676
<required>true</required>
77-
<version>1.0.0</version>
77+
<version>1.0.0+</version>
7878
<type>String</type>
79-
<description>The ID of this phase, e.g., &lt;code&gt;generate-sources&lt;/code&gt;.</description>
79+
<description>The ID of this phase, e.g., {@code generate-sources}.</description>
80+
</field>
81+
<field xml.attribute="true">
82+
<name>executionPoint</name>
83+
<required>false</required>
84+
<version>2.0.0+</version>
85+
<type>String</type>
86+
<defaultValue><![CDATA[]]></defaultValue>
87+
<description><![CDATA[If specified, identifies this phase as a dynamic phase to decorate the specified phase id, e.g. {@code after} or {@code before}.]]></description>
88+
</field>
89+
<field xml.attribute="true">
90+
<name>priority</name>
91+
<required>false</required>
92+
<version>2.0.0+</version>
93+
<type>int</type>
94+
<defaultValue>0</defaultValue>
95+
<description>If specified, identifies a within phase prioritization of executions.</description>
8096
</field>
8197
<field>
8298
<name>executions</name>
83-
<version>1.0.0</version>
99+
<version>1.0.0+</version>
84100
<description>The goals to execute within the phase.</description>
85101
<association>
86102
<type>Execution</type>
@@ -89,26 +105,51 @@ under the License.
89105
</field>
90106
<field>
91107
<name>configuration</name>
92-
<version>1.0.0</version>
108+
<version>1.0.0+</version>
93109
<type>DOM</type>
94110
<description>Configuration to pass to all goals run in this phase.</description>
95111
</field>
96112
</fields>
113+
<codeSegments>
114+
<codeSegment>
115+
<version>2.0.0+</version>
116+
<code><![CDATA[
117+
/**
118+
* Get the effective ID of this phase, e.g.,
119+
* {@code generate-sources} or {@code after:integration-test[1000]}.
120+
*
121+
* @return String
122+
*/
123+
public String getEffectiveId() {
124+
if (executionPoint == null) {
125+
if (priority == 0) {
126+
return id;
127+
}
128+
return id + '[' + priority + ']';
129+
}
130+
if (priority == 0) {
131+
return executionPoint + ':' + id;
132+
}
133+
return executionPoint + ':' + id + '[' + priority + ']';
134+
}
135+
]]></code>
136+
</codeSegment>
137+
</codeSegments>
97138
</class>
98139
<class>
99140
<name>Execution</name>
100-
<version>1.0.0</version>
141+
<version>1.0.0+</version>
101142
<description>A set of goals to execute.</description>
102143
<fields>
103144
<field>
104145
<name>configuration</name>
105-
<version>1.0.0</version>
146+
<version>1.0.0+</version>
106147
<type>DOM</type>
107148
<description>Configuration to pass to the goals.</description>
108149
</field>
109150
<field>
110151
<name>goals</name>
111-
<version>1.0.0</version>
152+
<version>1.0.0+</version>
112153
<description>The goals to execute.</description>
113154
<association>
114155
<type>String</type>

0 commit comments

Comments
 (0)