Skip to content

Commit e74bde0

Browse files
authored
[MNG-8403] Maven ITs use maven-executor (#1940)
The goal of this PR is manifold, but major one is to be able to use in ITs new options introduced in Maven4. Currently the "embedded" mode supports only Maven3 options, as Maven4 got new CLI entry point (CLIng), while verifier uses old MavenCli entry point, that is also deprecated. Finally, a full cleanup of (black) magic happened as well, keep ITs simple and clean. Changes: * dropped from ITs classpath maven-shared-util * dropped from ITs classpath maven-verifier, copied last master Verifier to maven-it-helper and modified * enhancements to new maven-executor to make it fully replace maven-verifier * ITs are now using new infra and are using new CLIng "entry point" as well (so far ITs used deprecated maven-embedder/MavenCLI class). --- https://issues.apache.org/jira/browse/MNG-8403
1 parent 73e30c5 commit e74bde0

28 files changed

+2227
-278
lines changed

.github/workflows/maven.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
5353
- name: Set up Maven
5454
shell: bash
55-
run: mvn --errors --batch-mode --show-version org.apache.maven.plugins:maven-wrapper-plugin:3.3.2:wrapper "-Dmaven=4.0.0-beta-4"
55+
run: mvn --errors --batch-mode --show-version org.apache.maven.plugins:maven-wrapper-plugin:3.3.2:wrapper "-Dmaven=4.0.0-rc-1"
5656

5757
- name: Build Maven distributions
5858
shell: bash

impl/maven-executor/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ under the License.
3535

3636
<properties>
3737
<maven3version>3.9.9</maven3version>
38-
<maven4version>4.0.0-beta-5</maven4version>
38+
<maven4version>4.0.0-rc-1</maven4version>
3939
</properties>
4040

4141
<dependencies>
@@ -50,6 +50,11 @@ under the License.
5050
<artifactId>junit-jupiter-api</artifactId>
5151
<scope>test</scope>
5252
</dependency>
53+
<dependency>
54+
<groupId>org.junit.jupiter</groupId>
55+
<artifactId>junit-jupiter-params</artifactId>
56+
<scope>test</scope>
57+
</dependency>
5358
</dependencies>
5459

5560
<build>

impl/maven-executor/src/main/java/org/apache/maven/api/cli/Executor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public interface Executor extends AutoCloseable {
3434
boolean IS_WINDOWS = System.getProperty("os.name", "unknown").startsWith("Windows");
3535

3636
/**
37-
* Maven version string returned when the actual version of Maven cannot be determinet.
37+
* Maven version string returned when the actual version of Maven cannot be determined.
3838
*/
3939
String UNKNOWN_VERSION = "unknown";
4040

@@ -50,7 +50,7 @@ public interface Executor extends AutoCloseable {
5050
int execute(@Nonnull ExecutorRequest executorRequest) throws ExecutorException;
5151

5252
/**
53-
* Returns the Maven version that provided {@link ExecutorRequest} point at (would use). Please not, that this
53+
* Returns the Maven version that provided {@link ExecutorRequest} point at (would use). Please note, that this
5454
* operation, depending on underlying implementation may be costly. If caller use this method often, it is
5555
* caller responsibility to properly cache returned values (key can be {@link ExecutorRequest#installationDirectory()}.
5656
*

impl/maven-executor/src/main/java/org/apache/maven/api/cli/ExecutorRequest.java

Lines changed: 177 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@
1919
package org.apache.maven.api.cli;
2020

2121
import java.io.IOException;
22+
import java.io.OutputStream;
2223
import java.nio.file.Path;
2324
import java.nio.file.Paths;
2425
import java.util.ArrayList;
26+
import java.util.HashMap;
2527
import java.util.List;
28+
import java.util.Map;
2629
import java.util.Optional;
2730

2831
import org.apache.maven.api.annotations.Experimental;
@@ -35,14 +38,19 @@
3538
/**
3639
* Represents a request to execute Maven with command-line arguments.
3740
* This interface encapsulates all the necessary information needed to execute
38-
* Maven command with arguments. The arguments were not parsed, they are just passed over
41+
* Maven command with arguments. The arguments are not parsed, they are just passed over
3942
* to executed tool.
4043
*
4144
* @since 4.0.0
4245
*/
4346
@Immutable
4447
@Experimental
4548
public interface ExecutorRequest {
49+
/**
50+
* The Maven command.
51+
*/
52+
String MVN = "mvn";
53+
4654
/**
4755
* The command to execute, ie "mvn".
4856
*/
@@ -82,18 +90,53 @@ public interface ExecutorRequest {
8290
@Nonnull
8391
Path userHomeDirectory();
8492

93+
/**
94+
* Returns the map of Java System Properties to set before executing process.
95+
*
96+
* @return an Optional containing the map of Java System Properties, or empty if not specified
97+
*/
98+
@Nonnull
99+
Optional<Map<String, String>> jvmSystemProperties();
100+
101+
/**
102+
* Returns the map of environment variables to set before executing process.
103+
* This property is used ONLY by executors that spawn a new JVM.
104+
*
105+
* @return an Optional containing the map of environment variables, or empty if not specified
106+
*/
107+
@Nonnull
108+
Optional<Map<String, String>> environmentVariables();
109+
85110
/**
86111
* Returns the list of extra JVM arguments to be passed to the forked process.
87112
* These arguments allow for customization of the JVM environment in which tool will run.
88-
* This property is used ONLY by executors and invokers that spawn a new JVM.
113+
* This property is used ONLY by executors that spawn a new JVM.
89114
*
90115
* @return an Optional containing the list of extra JVM arguments, or empty if not specified
91116
*/
92117
@Nonnull
93118
Optional<List<String>> jvmArguments();
94119

95120
/**
96-
* Returns {@link Builder} for this instance.
121+
* Optional consumer for STD out of the Maven. If given, this consumer will get all output from the std out of
122+
* Maven. Note: whether consumer gets to consume anything depends on invocation arguments passed in
123+
* {@link #arguments()}, as if log file is set, not much will go to stdout.
124+
*
125+
* @return an Optional containing the stdout consumer, or empty if not specified.
126+
*/
127+
Optional<OutputStream> stdoutConsumer();
128+
129+
/**
130+
* Optional consumer for STD err of the Maven. If given, this consumer will get all output from the std err of
131+
* Maven. Note: whether consumer gets to consume anything depends on invocation arguments passed in
132+
* {@link #arguments()}, as if log file is set, not much will go to stderr.
133+
*
134+
* @return an Optional containing the stderr consumer, or empty if not specified.
135+
*/
136+
Optional<OutputStream> stderrConsumer();
137+
138+
/**
139+
* Returns {@link Builder} created from this instance.
97140
*/
98141
@Nonnull
99142
default Builder toBuilder() {
@@ -103,28 +146,29 @@ default Builder toBuilder() {
103146
cwd(),
104147
installationDirectory(),
105148
userHomeDirectory(),
106-
jvmArguments().orElse(null));
107-
}
108-
109-
/**
110-
* Returns new empty builder.
111-
*/
112-
@Nonnull
113-
static Builder empyBuilder() {
114-
return new Builder();
149+
jvmSystemProperties().orElse(null),
150+
environmentVariables().orElse(null),
151+
jvmArguments().orElse(null),
152+
stdoutConsumer().orElse(null),
153+
stderrConsumer().orElse(null));
115154
}
116155

117156
/**
118-
* Returns new builder pre-set to run Maven. The discovery of maven home is attempted.
157+
* Returns new builder pre-set to run Maven. The discovery of maven home is attempted, user cwd and home are
158+
* also discovered by standard means.
119159
*/
120160
@Nonnull
121161
static Builder mavenBuilder(@Nullable Path installationDirectory) {
122162
return new Builder(
123-
"mvn",
163+
MVN,
124164
null,
125165
getCanonicalPath(Paths.get(System.getProperty("user.dir"))),
126166
installationDirectory != null ? getCanonicalPath(installationDirectory) : discoverMavenHome(),
127167
getCanonicalPath(Paths.get(System.getProperty("user.home"))),
168+
null,
169+
null,
170+
null,
171+
null,
128172
null);
129173
}
130174

@@ -134,23 +178,36 @@ class Builder {
134178
private Path cwd;
135179
private Path installationDirectory;
136180
private Path userHomeDirectory;
181+
private Map<String, String> jvmSystemProperties;
182+
private Map<String, String> environmentVariables;
137183
private List<String> jvmArguments;
184+
private OutputStream stdoutConsumer;
185+
private OutputStream stderrConsumer;
138186

139187
private Builder() {}
140188

189+
@SuppressWarnings("ParameterNumber")
141190
private Builder(
142191
String command,
143192
List<String> arguments,
144193
Path cwd,
145194
Path installationDirectory,
146195
Path userHomeDirectory,
147-
List<String> jvmArguments) {
196+
Map<String, String> jvmSystemProperties,
197+
Map<String, String> environmentVariables,
198+
List<String> jvmArguments,
199+
OutputStream stdoutConsumer,
200+
OutputStream stderrConsumer) {
148201
this.command = command;
149202
this.arguments = arguments;
150203
this.cwd = cwd;
151204
this.installationDirectory = installationDirectory;
152205
this.userHomeDirectory = userHomeDirectory;
206+
this.jvmSystemProperties = jvmSystemProperties;
207+
this.environmentVariables = environmentVariables;
153208
this.jvmArguments = jvmArguments;
209+
this.stdoutConsumer = stdoutConsumer;
210+
this.stderrConsumer = stderrConsumer;
154211
}
155212

156213
@Nonnull
@@ -176,19 +233,54 @@ public Builder argument(String argument) {
176233

177234
@Nonnull
178235
public Builder cwd(Path cwd) {
179-
this.cwd = requireNonNull(cwd, "cwd");
236+
this.cwd = getCanonicalPath(requireNonNull(cwd, "cwd"));
180237
return this;
181238
}
182239

183240
@Nonnull
184241
public Builder installationDirectory(Path installationDirectory) {
185-
this.installationDirectory = requireNonNull(installationDirectory, "installationDirectory");
242+
this.installationDirectory =
243+
getCanonicalPath(requireNonNull(installationDirectory, "installationDirectory"));
186244
return this;
187245
}
188246

189247
@Nonnull
190248
public Builder userHomeDirectory(Path userHomeDirectory) {
191-
this.userHomeDirectory = requireNonNull(userHomeDirectory, "userHomeDirectory");
249+
this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory, "userHomeDirectory"));
250+
return this;
251+
}
252+
253+
@Nonnull
254+
public Builder jvmSystemProperties(Map<String, String> jvmSystemProperties) {
255+
this.jvmSystemProperties = jvmSystemProperties;
256+
return this;
257+
}
258+
259+
@Nonnull
260+
public Builder jvmSystemProperty(String key, String value) {
261+
requireNonNull(key, "env key");
262+
requireNonNull(value, "env value");
263+
if (jvmSystemProperties == null) {
264+
this.jvmSystemProperties = new HashMap<>();
265+
}
266+
this.jvmSystemProperties.put(key, value);
267+
return this;
268+
}
269+
270+
@Nonnull
271+
public Builder environmentVariables(Map<String, String> environmentVariables) {
272+
this.environmentVariables = environmentVariables;
273+
return this;
274+
}
275+
276+
@Nonnull
277+
public Builder environmentVariable(String key, String value) {
278+
requireNonNull(key, "env key");
279+
requireNonNull(value, "env value");
280+
if (environmentVariables == null) {
281+
this.environmentVariables = new HashMap<>();
282+
}
283+
this.environmentVariables.put(key, value);
192284
return this;
193285
}
194286

@@ -207,9 +299,31 @@ public Builder jvmArgument(String jvmArgument) {
207299
return this;
208300
}
209301

302+
@Nonnull
303+
public Builder stdoutConsumer(OutputStream stdoutConsumer) {
304+
this.stdoutConsumer = stdoutConsumer;
305+
return this;
306+
}
307+
308+
@Nonnull
309+
public Builder stderrConsumer(OutputStream stderrConsumer) {
310+
this.stderrConsumer = stderrConsumer;
311+
return this;
312+
}
313+
210314
@Nonnull
211315
public ExecutorRequest build() {
212-
return new Impl(command, arguments, cwd, installationDirectory, userHomeDirectory, jvmArguments);
316+
return new Impl(
317+
command,
318+
arguments,
319+
cwd,
320+
installationDirectory,
321+
userHomeDirectory,
322+
jvmSystemProperties,
323+
environmentVariables,
324+
jvmArguments,
325+
stdoutConsumer,
326+
stderrConsumer);
213327
}
214328

215329
private static class Impl implements ExecutorRequest {
@@ -218,21 +332,34 @@ private static class Impl implements ExecutorRequest {
218332
private final Path cwd;
219333
private final Path installationDirectory;
220334
private final Path userHomeDirectory;
335+
private final Map<String, String> jvmSystemProperties;
336+
private final Map<String, String> environmentVariables;
221337
private final List<String> jvmArguments;
338+
private final OutputStream stdoutConsumer;
339+
private final OutputStream stderrConsumer;
222340

341+
@SuppressWarnings("ParameterNumber")
223342
private Impl(
224343
String command,
225344
List<String> arguments,
226345
Path cwd,
227346
Path installationDirectory,
228347
Path userHomeDirectory,
229-
List<String> jvmArguments) {
348+
Map<String, String> jvmSystemProperties,
349+
Map<String, String> environmentVariables,
350+
List<String> jvmArguments,
351+
OutputStream stdoutConsumer,
352+
OutputStream stderrConsumer) {
230353
this.command = requireNonNull(command);
231354
this.arguments = arguments == null ? List.of() : List.copyOf(arguments);
232-
this.cwd = requireNonNull(cwd);
233-
this.installationDirectory = requireNonNull(installationDirectory);
234-
this.userHomeDirectory = requireNonNull(userHomeDirectory);
355+
this.cwd = getCanonicalPath(requireNonNull(cwd));
356+
this.installationDirectory = getCanonicalPath(requireNonNull(installationDirectory));
357+
this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory));
358+
this.jvmSystemProperties = jvmSystemProperties != null ? Map.copyOf(jvmSystemProperties) : null;
359+
this.environmentVariables = environmentVariables != null ? Map.copyOf(environmentVariables) : null;
235360
this.jvmArguments = jvmArguments != null ? List.copyOf(jvmArguments) : null;
361+
this.stdoutConsumer = stdoutConsumer;
362+
this.stderrConsumer = stderrConsumer;
236363
}
237364

238365
@Override
@@ -260,20 +387,44 @@ public Path userHomeDirectory() {
260387
return userHomeDirectory;
261388
}
262389

390+
@Override
391+
public Optional<Map<String, String>> jvmSystemProperties() {
392+
return Optional.ofNullable(jvmSystemProperties);
393+
}
394+
395+
@Override
396+
public Optional<Map<String, String>> environmentVariables() {
397+
return Optional.ofNullable(environmentVariables);
398+
}
399+
263400
@Override
264401
public Optional<List<String>> jvmArguments() {
265402
return Optional.ofNullable(jvmArguments);
266403
}
267404

405+
@Override
406+
public Optional<OutputStream> stdoutConsumer() {
407+
return Optional.ofNullable(stdoutConsumer);
408+
}
409+
410+
@Override
411+
public Optional<OutputStream> stderrConsumer() {
412+
return Optional.ofNullable(stderrConsumer);
413+
}
414+
268415
@Override
269416
public String toString() {
270-
return "ExecutionRequest{" + "command='"
417+
return "Impl{" + "command='"
271418
+ command + '\'' + ", arguments="
272419
+ arguments + ", cwd="
273420
+ cwd + ", installationDirectory="
274421
+ installationDirectory + ", userHomeDirectory="
275-
+ userHomeDirectory + ", jvmArguments="
276-
+ jvmArguments + '}';
422+
+ userHomeDirectory + ", jvmSystemProperties="
423+
+ jvmSystemProperties + ", environmentVariables="
424+
+ environmentVariables + ", jvmArguments="
425+
+ jvmArguments + ", stdoutConsumer="
426+
+ stdoutConsumer + ", stderrConsumer="
427+
+ stderrConsumer + '}';
277428
}
278429
}
279430
}

0 commit comments

Comments
 (0)