Skip to content

Commit fa6a873

Browse files
authored
[MNG-8535] Full std stream support for executor (#2082)
The std stream support was incomplete in maven-executor. Also some unrelated fixes. --- https://issues.apache.org/jira/browse/MNG-8535
1 parent 3bb7327 commit fa6a873

File tree

31 files changed

+747
-367
lines changed

31 files changed

+747
-367
lines changed

api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ public interface InvokerRequest {
5454
*/
5555
boolean parsingFailed();
5656

57+
/**
58+
* Returns {@code true} if this call happens in "embedded" mode.
59+
*
60+
* @see ParserRequest#embedded()
61+
*/
62+
default boolean embedded() {
63+
return parserRequest().embedded();
64+
}
65+
5766
/**
5867
* Returns the current working directory for the Maven execution.
5968
* This is typically the directory from which Maven was invoked.
@@ -138,23 +147,29 @@ default Lookup lookup() {
138147
* @return an {@link Optional} containing the input stream, or empty if not applicable
139148
*/
140149
@Nonnull
141-
Optional<InputStream> in();
150+
default Optional<InputStream> stdIn() {
151+
return Optional.ofNullable(parserRequest().stdIn());
152+
}
142153

143154
/**
144155
* Returns the output stream for the Maven execution, if running in embedded mode.
145156
*
146157
* @return an {@link Optional} containing the output stream, or empty if not applicable
147158
*/
148159
@Nonnull
149-
Optional<OutputStream> out();
160+
default Optional<OutputStream> stdOut() {
161+
return Optional.ofNullable(parserRequest().stdOut());
162+
}
150163

151164
/**
152165
* Returns the error stream for the Maven execution, if running in embedded mode.
153166
*
154167
* @return an {@link Optional} containing the error stream, or empty if not applicable
155168
*/
156169
@Nonnull
157-
Optional<OutputStream> err();
170+
default Optional<OutputStream> stdErr() {
171+
return Optional.ofNullable(parserRequest().stdErr());
172+
}
158173

159174
/**
160175
* Returns a list of core extensions, if configured in the .mvn/extensions.xml file.

api/maven-api-cli/src/main/java/org/apache/maven/api/cli/ParserRequest.java

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -125,30 +125,37 @@ public interface ParserRequest {
125125

126126
/**
127127
* Returns the input stream to be used for the Maven execution.
128-
* If not set, System.in will be used by default.
128+
* If not set, {@link System#in} will be used by default.
129129
*
130130
* @return the input stream, or null if not set
131131
*/
132132
@Nullable
133-
InputStream in();
133+
InputStream stdIn();
134134

135135
/**
136136
* Returns the output stream to be used for the Maven execution.
137-
* If not set, System.out will be used by default.
137+
* If not set, {@link System#out} will be used by default.
138138
*
139139
* @return the output stream, or null if not set
140140
*/
141141
@Nullable
142-
OutputStream out();
142+
OutputStream stdOut();
143143

144144
/**
145145
* Returns the error stream to be used for the Maven execution.
146-
* If not set, System.err will be used by default.
146+
* If not set, {@link System#err} will be used by default.
147147
*
148148
* @return the error stream, or null if not set
149149
*/
150150
@Nullable
151-
OutputStream err();
151+
OutputStream stdErr();
152+
153+
/**
154+
* Returns {@code true} if this call happens in "embedded" mode, for example by another application that
155+
* embeds Maven. When running in "embedded" mode, Maven will not try to grab system terminal and will use
156+
* provided {@link #stdIn()} or {@link InputStream#nullInputStream()} as standard in stream.
157+
*/
158+
boolean embedded();
152159

153160
/**
154161
* Creates a new Builder instance for constructing a Maven ParserRequest.
@@ -251,9 +258,10 @@ class Builder {
251258
private Path cwd;
252259
private Path mavenHome;
253260
private Path userHome;
254-
private InputStream in;
255-
private OutputStream out;
256-
private OutputStream err;
261+
private InputStream stdIn;
262+
private OutputStream stdOut;
263+
private OutputStream stdErr;
264+
private boolean embedded = false;
257265

258266
private Builder(
259267
String command, String commandName, List<String> args, MessageBuilderFactory messageBuilderFactory) {
@@ -284,18 +292,23 @@ public Builder userHome(Path userHome) {
284292
return this;
285293
}
286294

287-
public Builder in(InputStream in) {
288-
this.in = in;
295+
public Builder stdIn(InputStream stdIn) {
296+
this.stdIn = stdIn;
289297
return this;
290298
}
291299

292-
public Builder out(OutputStream out) {
293-
this.out = out;
300+
public Builder stdOut(OutputStream stdOut) {
301+
this.stdOut = stdOut;
294302
return this;
295303
}
296304

297-
public Builder err(OutputStream err) {
298-
this.err = err;
305+
public Builder stdErr(OutputStream stdErr) {
306+
this.stdErr = stdErr;
307+
return this;
308+
}
309+
310+
public Builder embedded(boolean embedded) {
311+
this.embedded = embedded;
299312
return this;
300313
}
301314

@@ -310,9 +323,10 @@ public ParserRequest build() {
310323
cwd,
311324
mavenHome,
312325
userHome,
313-
in,
314-
out,
315-
err);
326+
stdIn,
327+
stdOut,
328+
stdErr,
329+
embedded);
316330
}
317331

318332
@SuppressWarnings("ParameterNumber")
@@ -326,9 +340,10 @@ private static class ParserRequestImpl implements ParserRequest {
326340
private final Path cwd;
327341
private final Path mavenHome;
328342
private final Path userHome;
329-
private final InputStream in;
330-
private final OutputStream out;
331-
private final OutputStream err;
343+
private final InputStream stdIn;
344+
private final OutputStream stdOut;
345+
private final OutputStream stdErr;
346+
private final boolean embedded;
332347

333348
private ParserRequestImpl(
334349
String command,
@@ -340,9 +355,10 @@ private ParserRequestImpl(
340355
Path cwd,
341356
Path mavenHome,
342357
Path userHome,
343-
InputStream in,
344-
OutputStream out,
345-
OutputStream err) {
358+
InputStream stdIn,
359+
OutputStream stdOut,
360+
OutputStream stdErr,
361+
boolean embedded) {
346362
this.command = requireNonNull(command, "command");
347363
this.commandName = requireNonNull(commandName, "commandName");
348364
this.args = List.copyOf(requireNonNull(args, "args"));
@@ -352,9 +368,10 @@ private ParserRequestImpl(
352368
this.cwd = cwd;
353369
this.mavenHome = mavenHome;
354370
this.userHome = userHome;
355-
this.in = in;
356-
this.out = out;
357-
this.err = err;
371+
this.stdIn = stdIn;
372+
this.stdOut = stdOut;
373+
this.stdErr = stdErr;
374+
this.embedded = embedded;
358375
}
359376

360377
@Override
@@ -403,18 +420,23 @@ public Path userHome() {
403420
}
404421

405422
@Override
406-
public InputStream in() {
407-
return in;
423+
public InputStream stdIn() {
424+
return stdIn;
425+
}
426+
427+
@Override
428+
public OutputStream stdOut() {
429+
return stdOut;
408430
}
409431

410432
@Override
411-
public OutputStream out() {
412-
return out;
433+
public OutputStream stdErr() {
434+
return stdErr;
413435
}
414436

415437
@Override
416-
public OutputStream err() {
417-
return err;
438+
public boolean embedded() {
439+
return embedded;
418440
}
419441
}
420442

api/maven-api-core/src/test/java/org/apache/maven/api/services/SourcesTest.java

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

2121
import java.io.IOException;
22+
import java.io.InputStream;
2223
import java.nio.file.Files;
2324
import java.nio.file.Path;
2425
import java.nio.file.Paths;
@@ -121,9 +122,10 @@ void testStreamReading() throws IOException {
121122
Files.writeString(testFile, content);
122123

123124
Source source = Sources.fromPath(testFile);
124-
String readContent = new String(source.openStream().readAllBytes());
125-
126-
assertEquals(content, readContent);
125+
try (InputStream inputStream = source.openStream()) {
126+
String readContent = new String(inputStream.readAllBytes());
127+
assertEquals(content, readContent);
128+
}
127129
}
128130

129131
@Test

compat/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ protected File projectFile(String groupId, String artifactId) {
4949
// ----------------------------------------------------------------------
5050

5151
protected File getLocalRepositoryPath() {
52-
return getTestFile("src/test/resources/inheritance-repo/" + getTestSeries());
52+
return getTestFile("target/test-classes/inheritance-repo/" + getTestSeries());
5353
}
5454

5555
@Override

impl/maven-cli/pom.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,31 @@ under the License.
114114
<artifactId>maven-resolver-transport-jdk</artifactId>
115115
<scope>test</scope>
116116
</dependency>
117+
<dependency>
118+
<groupId>org.jline</groupId>
119+
<artifactId>jline-native</artifactId>
120+
<scope>test</scope>
121+
</dependency>
117122
</dependencies>
118123

119124
<build>
120125
<plugins>
126+
<plugin>
127+
<groupId>org.apache.maven.plugins</groupId>
128+
<artifactId>maven-dependency-plugin</artifactId>
129+
<executions>
130+
<execution>
131+
<id>unpack-jline-native</id>
132+
<goals>
133+
<goal>unpack-dependencies</goal>
134+
</goals>
135+
<configuration>
136+
<includeArtifactIds>jline-native</includeArtifactIds>
137+
<includes>org/jline/nativ/**</includes>
138+
</configuration>
139+
</execution>
140+
</executions>
141+
</plugin>
121142
<plugin>
122143
<groupId>org.codehaus.modello</groupId>
123144
<artifactId>modello-maven-plugin</artifactId>

impl/maven-cli/src/main/java/org/apache/maven/cling/ClingSupport.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919
package org.apache.maven.cling;
2020

2121
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.io.OutputStream;
2224

25+
import org.apache.maven.api.annotations.Nullable;
2326
import org.apache.maven.api.cli.Invoker;
2427
import org.apache.maven.api.cli.InvokerException;
25-
import org.apache.maven.api.cli.InvokerRequest;
28+
import org.apache.maven.api.cli.Parser;
29+
import org.apache.maven.api.cli.ParserRequest;
30+
import org.apache.maven.api.services.MessageBuilderFactory;
2631
import org.apache.maven.cling.invoker.logging.SystemLogger;
32+
import org.apache.maven.jline.JLineMessageBuilderFactory;
2733
import org.codehaus.plexus.classworlds.ClassWorld;
2834

2935
import static java.util.Objects.requireNonNull;
@@ -59,14 +65,26 @@ private ClingSupport(ClassWorld classWorld, boolean classWorldManaged) {
5965
/**
6066
* The main entry point.
6167
*/
62-
public int run(String[] args) throws IOException {
68+
public int run(
69+
String[] args,
70+
@Nullable InputStream stdIn,
71+
@Nullable OutputStream stdOut,
72+
@Nullable OutputStream stdErr,
73+
boolean embedded)
74+
throws IOException {
6375
try (Invoker invoker = createInvoker()) {
64-
return invoker.invoke(parseArguments(args));
76+
return invoker.invoke(createParser()
77+
.parseInvocation(createParserRequestBuilder(args)
78+
.stdIn(stdIn)
79+
.stdOut(stdOut)
80+
.stdErr(stdErr)
81+
.embedded(embedded)
82+
.build()));
6583
} catch (InvokerException.ExitException e) {
6684
return e.getExitCode();
6785
} catch (Exception e) {
6886
// last resort; as ideally we should get ExitException only
69-
new SystemLogger().error(e.getMessage(), e);
87+
new SystemLogger(stdErr).error(e.getMessage(), e);
7088
return 1;
7189
} finally {
7290
if (classWorldManaged) {
@@ -75,7 +93,13 @@ public int run(String[] args) throws IOException {
7593
}
7694
}
7795

96+
protected MessageBuilderFactory createMessageBuilderFactory() {
97+
return new JLineMessageBuilderFactory();
98+
}
99+
78100
protected abstract Invoker createInvoker();
79101

80-
protected abstract InvokerRequest parseArguments(String[] args);
102+
protected abstract Parser createParser();
103+
104+
protected abstract ParserRequest.Builder createParserRequestBuilder(String[] args);
81105
}

0 commit comments

Comments
 (0)