Skip to content

Commit

Permalink
[MNG-8535] Full std stream support for executor
Browse files Browse the repository at this point in the history
The std stream support was incomplete in maven-executor

---

https://issues.apache.org/jira/browse/MNG-8535
  • Loading branch information
cstamas committed Feb 4, 2025
1 parent 8b3e640 commit 61efc04
Show file tree
Hide file tree
Showing 20 changed files with 381 additions and 235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ public interface InvokerRequest {
*/
boolean parsingFailed();

/**
* Returns {@code true} if this call happens in "embedded" mode.
*
* @see ParserRequest#embedded()
*/
default boolean embedded() {
return parserRequest().embedded();
}

/**
* Returns the current working directory for the Maven execution.
* This is typically the directory from which Maven was invoked.
Expand Down Expand Up @@ -138,23 +147,29 @@ default Lookup lookup() {
* @return an {@link Optional} containing the input stream, or empty if not applicable
*/
@Nonnull
Optional<InputStream> in();
default Optional<InputStream> stdIn() {
return Optional.ofNullable(parserRequest().stdIn());
}

/**
* Returns the output stream for the Maven execution, if running in embedded mode.
*
* @return an {@link Optional} containing the output stream, or empty if not applicable
*/
@Nonnull
Optional<OutputStream> out();
default Optional<OutputStream> stdOut() {
return Optional.ofNullable(parserRequest().stdOut());
}

/**
* Returns the error stream for the Maven execution, if running in embedded mode.
*
* @return an {@link Optional} containing the error stream, or empty if not applicable
*/
@Nonnull
Optional<OutputStream> err();
default Optional<OutputStream> stdErr() {
return Optional.ofNullable(parserRequest().stdErr());
}

/**
* Returns a list of core extensions, if configured in the .mvn/extensions.xml file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,30 +125,37 @@ public interface ParserRequest {

/**
* Returns the input stream to be used for the Maven execution.
* If not set, System.in will be used by default.
* If not set, {@link System#in} will be used by default.
*
* @return the input stream, or null if not set
*/
@Nullable
InputStream in();
InputStream stdIn();

/**
* Returns the output stream to be used for the Maven execution.
* If not set, System.out will be used by default.
* If not set, {@link System#out} will be used by default.
*
* @return the output stream, or null if not set
*/
@Nullable
OutputStream out();
OutputStream stdOut();

/**
* Returns the error stream to be used for the Maven execution.
* If not set, System.err will be used by default.
* If not set, {@link System#err} will be used by default.
*
* @return the error stream, or null if not set
*/
@Nullable
OutputStream err();
OutputStream stdErr();

/**
* Returns {@code true} if this call happens in "embedded" mode, for example by another application that
* embeds Maven. When running in "embedded" mode, Maven will not try to grab system terminal and will use
* provided {@link #stdIn()} or {@link InputStream#nullInputStream()} as standard in stream.
*/
boolean embedded();

/**
* Creates a new Builder instance for constructing a Maven ParserRequest.
Expand Down Expand Up @@ -251,9 +258,10 @@ class Builder {
private Path cwd;
private Path mavenHome;
private Path userHome;
private InputStream in;
private OutputStream out;
private OutputStream err;
private InputStream stdIn;
private OutputStream stdOut;
private OutputStream stdErr;
private boolean embedded = false;

private Builder(
String command, String commandName, List<String> args, MessageBuilderFactory messageBuilderFactory) {
Expand Down Expand Up @@ -284,18 +292,23 @@ public Builder userHome(Path userHome) {
return this;
}

public Builder in(InputStream in) {
this.in = in;
public Builder stdIn(InputStream stdIn) {
this.stdIn = stdIn;
return this;
}

public Builder out(OutputStream out) {
this.out = out;
public Builder stdOut(OutputStream stdOut) {
this.stdOut = stdOut;
return this;
}

public Builder err(OutputStream err) {
this.err = err;
public Builder stdErr(OutputStream stdErr) {
this.stdErr = stdErr;
return this;
}

public Builder embedded(boolean embedded) {
this.embedded = embedded;
return this;
}

Expand All @@ -310,9 +323,10 @@ public ParserRequest build() {
cwd,
mavenHome,
userHome,
in,
out,
err);
stdIn,
stdOut,
stdErr,
embedded);
}

@SuppressWarnings("ParameterNumber")
Expand All @@ -326,9 +340,10 @@ private static class ParserRequestImpl implements ParserRequest {
private final Path cwd;
private final Path mavenHome;
private final Path userHome;
private final InputStream in;
private final OutputStream out;
private final OutputStream err;
private final InputStream stdIn;
private final OutputStream stdOut;
private final OutputStream stdErr;
private final boolean embedded;

private ParserRequestImpl(
String command,
Expand All @@ -340,9 +355,10 @@ private ParserRequestImpl(
Path cwd,
Path mavenHome,
Path userHome,
InputStream in,
OutputStream out,
OutputStream err) {
InputStream stdIn,
OutputStream stdOut,
OutputStream stdErr,
boolean embedded) {
this.command = requireNonNull(command, "command");
this.commandName = requireNonNull(commandName, "commandName");
this.args = List.copyOf(requireNonNull(args, "args"));
Expand All @@ -352,9 +368,10 @@ private ParserRequestImpl(
this.cwd = cwd;
this.mavenHome = mavenHome;
this.userHome = userHome;
this.in = in;
this.out = out;
this.err = err;
this.stdIn = stdIn;
this.stdOut = stdOut;
this.stdErr = stdErr;
this.embedded = embedded;
}

@Override
Expand Down Expand Up @@ -403,18 +420,23 @@ public Path userHome() {
}

@Override
public InputStream in() {
return in;
public InputStream stdIn() {
return stdIn;
}

@Override
public OutputStream stdOut() {
return stdOut;
}

@Override
public OutputStream out() {
return out;
public OutputStream stdErr() {
return stdErr;
}

@Override
public OutputStream err() {
return err;
public boolean embedded() {
return embedded;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@
package org.apache.maven.cling;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.cli.Invoker;
import org.apache.maven.api.cli.InvokerException;
import org.apache.maven.api.cli.InvokerRequest;
import org.apache.maven.api.cli.Parser;
import org.apache.maven.api.cli.ParserRequest;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.cling.invoker.logging.SystemLogger;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.codehaus.plexus.classworlds.ClassWorld;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -59,14 +65,26 @@ private ClingSupport(ClassWorld classWorld, boolean classWorldManaged) {
/**
* The main entry point.
*/
public int run(String[] args) throws IOException {
public int run(
String[] args,
@Nullable InputStream stdIn,
@Nullable OutputStream stdOut,
@Nullable OutputStream stdErr,
boolean embedded)
throws IOException {
try (Invoker invoker = createInvoker()) {
return invoker.invoke(parseArguments(args));
return invoker.invoke(createParser()
.parseInvocation(createParserRequestBuilder(args)
.stdIn(stdIn)
.stdOut(stdOut)
.stdErr(stdErr)
.embedded(embedded)
.build()));
} catch (InvokerException.ExitException e) {
return e.getExitCode();
} catch (Exception e) {
// last resort; as ideally we should get ExitException only
new SystemLogger().error(e.getMessage(), e);
new SystemLogger(stdErr).error(e.getMessage(), e);
return 1;
} finally {
if (classWorldManaged) {
Expand All @@ -75,7 +93,13 @@ public int run(String[] args) throws IOException {
}
}

protected MessageBuilderFactory createMessageBuilderFactory() {
return new JLineMessageBuilderFactory();
}

protected abstract Invoker createInvoker();

protected abstract InvokerRequest parseArguments(String[] args);
protected abstract Parser createParser();

protected abstract ParserRequest.Builder createParserRequestBuilder(String[] args);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@
package org.apache.maven.cling;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.cli.Invoker;
import org.apache.maven.api.cli.InvokerRequest;
import org.apache.maven.api.cli.Parser;
import org.apache.maven.api.cli.ParserRequest;
import org.apache.maven.cling.invoker.ProtoLookup;
import org.apache.maven.cling.invoker.mvn.MavenInvoker;
import org.apache.maven.cling.invoker.mvn.MavenParser;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.codehaus.plexus.classworlds.ClassWorld;

/**
Expand All @@ -38,15 +40,28 @@ public class MavenCling extends ClingSupport {
* circumstances.
*/
public static void main(String[] args) throws IOException {
int exitCode = new MavenCling().run(args);
int exitCode = new MavenCling().run(args, null, null, null, false);
System.exit(exitCode);
}

/**
* ClassWorld Launcher "enhanced" entry point: returning exitCode and accepts Class World.
*/
public static int main(String[] args, ClassWorld world) throws IOException {
return new MavenCling(world).run(args);
return new MavenCling(world).run(args, null, null, null, false);
}

/**
* ClassWorld Launcher "embedded" entry point: returning exitCode and accepts Class World and streams.
*/
public static int main(
String[] args,
ClassWorld world,
@Nullable InputStream stdIn,
@Nullable OutputStream stdOut,
@Nullable OutputStream stdErr)
throws IOException {
return new MavenCling(world).run(args, stdIn, stdOut, stdErr, true);
}

public MavenCling() {
Expand All @@ -64,9 +79,12 @@ protected Invoker createInvoker() {
}

@Override
protected InvokerRequest parseArguments(String[] args) {
return new MavenParser()
.parseInvocation(ParserRequest.mvn(args, new JLineMessageBuilderFactory())
.build());
protected Parser createParser() {
return new MavenParser();
}

@Override
protected ParserRequest.Builder createParserRequestBuilder(String[] args) {
return ParserRequest.mvn(args, createMessageBuilderFactory());
}
}
Loading

0 comments on commit 61efc04

Please sign in to comment.