mirror of
https://github.com/apache/maven.git
synced 2025-03-08 17:49:15 +00:00
[MNG-8334] Fix output redirection (#1826)
This commit is contained in:
parent
867641c9ea
commit
3425b4dd08
@ -18,10 +18,10 @@
|
||||
*/
|
||||
package org.apache.maven.api.cli;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.maven.api.annotations.Experimental;
|
||||
import org.apache.maven.api.annotations.Nonnull;
|
||||
@ -202,14 +202,14 @@ public interface Options {
|
||||
/**
|
||||
* Emits warning messages if deprecated options are used.
|
||||
*
|
||||
* @param printWriter the PrintWriter to use for output
|
||||
* @param printWriter the string consumer to use for output
|
||||
*/
|
||||
default void warnAboutDeprecatedOptions(@Nonnull ParserRequest request, @Nonnull PrintWriter printWriter) {}
|
||||
default void warnAboutDeprecatedOptions(@Nonnull ParserRequest request, @Nonnull Consumer<String> printWriter) {}
|
||||
|
||||
/**
|
||||
* Displays help information for these options.
|
||||
*
|
||||
* @param printWriter the PrintWriter to use for output
|
||||
* @param printWriter the string consumer to use for output
|
||||
*/
|
||||
void displayHelp(@Nonnull ParserRequest request, @Nonnull PrintWriter printWriter);
|
||||
void displayHelp(@Nonnull ParserRequest request, @Nonnull Consumer<String> printWriter);
|
||||
}
|
||||
|
@ -111,8 +111,8 @@ public R parse(ParserRequest parserRequest) throws ParserException, IOException
|
||||
List<O> parsedOptions = parseCliOptions(context);
|
||||
|
||||
// warn about deprecated options
|
||||
parsedOptions.forEach(o -> o.warnAboutDeprecatedOptions(
|
||||
parserRequest, new PrintWriter(parserRequest.out() != null ? parserRequest.out() : System.out, true)));
|
||||
PrintWriter printWriter = new PrintWriter(parserRequest.out() != null ? parserRequest.out() : System.out, true);
|
||||
parsedOptions.forEach(o -> o.warnAboutDeprecatedOptions(parserRequest, printWriter::println));
|
||||
|
||||
// assemble options if needed
|
||||
context.options = assembleOptions(parsedOptions);
|
||||
|
@ -19,10 +19,12 @@
|
||||
package org.apache.maven.cling.invoker;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
@ -89,7 +91,7 @@ public Optional<Boolean> quiet() {
|
||||
|
||||
@Override
|
||||
public Optional<Boolean> verbose() {
|
||||
if (commandLine.hasOption(CLIManager.VERBOSE) || commandLine.hasOption(CLIManager.DEBUG)) {
|
||||
if (commandLine.hasOption(CLIManager.VERBOSE)) {
|
||||
return Optional.of(Boolean.TRUE);
|
||||
}
|
||||
return Optional.empty();
|
||||
@ -210,11 +212,11 @@ public Optional<Boolean> help() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warnAboutDeprecatedOptions(ParserRequest request, PrintWriter printWriter) {
|
||||
public void warnAboutDeprecatedOptions(ParserRequest request, Consumer<String> printWriter) {
|
||||
if (cliManager.getUsedDeprecatedOptions().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
printWriter.println("Detected deprecated option use in " + source);
|
||||
printWriter.accept("Detected deprecated option use in " + source);
|
||||
for (Option option : cliManager.getUsedDeprecatedOptions()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("The option -").append(option.getOpt());
|
||||
@ -231,12 +233,12 @@ public void warnAboutDeprecatedOptions(ParserRequest request, PrintWriter printW
|
||||
.append(" ")
|
||||
.append(option.getDeprecated().getSince());
|
||||
}
|
||||
printWriter.println(sb);
|
||||
printWriter.accept(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayHelp(ParserRequest request, PrintWriter printStream) {
|
||||
public void displayHelp(ParserRequest request, Consumer<String> printStream) {
|
||||
cliManager.displayHelp(request.command(), printStream);
|
||||
}
|
||||
|
||||
@ -429,7 +431,7 @@ public Set<Option> getUsedDeprecatedOptions() {
|
||||
return usedDeprecatedOptions;
|
||||
}
|
||||
|
||||
public void displayHelp(String command, PrintWriter pw) {
|
||||
public void displayHelp(String command, Consumer<String> pw) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
|
||||
int width = MessageUtils.getTerminalWidth();
|
||||
@ -437,10 +439,12 @@ public void displayHelp(String command, PrintWriter pw) {
|
||||
width = HelpFormatter.DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.accept("");
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw2 = new PrintWriter(sw);
|
||||
formatter.printHelp(
|
||||
pw,
|
||||
pw2,
|
||||
width,
|
||||
commandLineSyntax(command),
|
||||
System.lineSeparator() + "Options:",
|
||||
@ -449,8 +453,10 @@ public void displayHelp(String command, PrintWriter pw) {
|
||||
HelpFormatter.DEFAULT_DESC_PAD,
|
||||
System.lineSeparator(),
|
||||
false);
|
||||
|
||||
pw.flush();
|
||||
pw2.flush();
|
||||
for (String s : sw.toString().split(System.lineSeparator())) {
|
||||
pw.accept(s);
|
||||
}
|
||||
}
|
||||
|
||||
protected String commandLineSyntax(String command) {
|
||||
|
@ -18,12 +18,12 @@
|
||||
*/
|
||||
package org.apache.maven.cling.invoker;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.maven.api.cli.Options;
|
||||
@ -138,10 +138,10 @@ public Optional<Boolean> help() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warnAboutDeprecatedOptions(ParserRequest request, PrintWriter printWriter) {}
|
||||
public void warnAboutDeprecatedOptions(ParserRequest request, Consumer<String> printWriter) {}
|
||||
|
||||
@Override
|
||||
public void displayHelp(ParserRequest request, PrintWriter printWriter) {
|
||||
public void displayHelp(ParserRequest request, Consumer<String> printWriter) {
|
||||
options.get(0).displayHelp(request, printWriter);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.maven.api.Constants;
|
||||
@ -71,16 +72,11 @@
|
||||
import org.apache.maven.cling.invoker.mvn.ProtoSession;
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.internal.impl.SettingsUtilsV4;
|
||||
import org.apache.maven.jline.FastTerminal;
|
||||
import org.apache.maven.jline.MessageUtils;
|
||||
import org.apache.maven.logging.BuildEventListener;
|
||||
import org.apache.maven.logging.LoggingOutputStream;
|
||||
import org.apache.maven.logging.ProjectBuildLogAppender;
|
||||
import org.apache.maven.logging.SimpleBuildEventListener;
|
||||
import org.apache.maven.logging.api.LogLevelRecorder;
|
||||
import org.apache.maven.slf4j.MavenSimpleLogger;
|
||||
import org.eclipse.aether.transfer.TransferListener;
|
||||
import org.jline.jansi.AnsiConsole;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
@ -152,8 +148,9 @@ protected LookupInvokerContext(LookupInvoker<O, R, C> invoker, R invokerRequest)
|
||||
public ILoggerFactory loggerFactory;
|
||||
public Slf4jConfiguration slf4jConfiguration;
|
||||
public Slf4jConfiguration.Level loggerLevel;
|
||||
public Boolean coloredOutput;
|
||||
public Terminal terminal;
|
||||
public BuildEventListener buildEventListener;
|
||||
public Consumer<String> writer;
|
||||
public ClassLoader currentThreadContextClassLoader;
|
||||
public ContainerCapsule containerCapsule;
|
||||
public Lookup lookup;
|
||||
@ -281,9 +278,9 @@ protected void configureLogging(C context) throws Exception {
|
||||
.orElse(userProperties.getOrDefault(
|
||||
Constants.MAVEN_STYLE_COLOR_PROPERTY, userProperties.getOrDefault("style.color", "auto")));
|
||||
if ("always".equals(styleColor) || "yes".equals(styleColor) || "force".equals(styleColor)) {
|
||||
MessageUtils.setColorEnabled(true);
|
||||
context.coloredOutput = true;
|
||||
} else if ("never".equals(styleColor) || "no".equals(styleColor) || "none".equals(styleColor)) {
|
||||
MessageUtils.setColorEnabled(false);
|
||||
context.coloredOutput = false;
|
||||
} else if (!"auto".equals(styleColor) && !"tty".equals(styleColor) && !"if-tty".equals(styleColor)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid color configuration value '" + styleColor + "'. Supported are 'auto', 'always', 'never'.");
|
||||
@ -291,7 +288,7 @@ protected void configureLogging(C context) throws Exception {
|
||||
boolean isBatchMode = !mavenOptions.forceInteractive().orElse(false)
|
||||
&& mavenOptions.nonInteractive().orElse(false);
|
||||
if (isBatchMode || mavenOptions.logFile().isPresent()) {
|
||||
MessageUtils.setColorEnabled(false);
|
||||
context.coloredOutput = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,31 +309,32 @@ protected void configureLogging(C context) throws Exception {
|
||||
// so boot it asynchronously
|
||||
context.terminal = createTerminal(context);
|
||||
context.closeables.add(MessageUtils::systemUninstall);
|
||||
|
||||
// Create the build log appender
|
||||
ProjectBuildLogAppender projectBuildLogAppender =
|
||||
new ProjectBuildLogAppender(determineBuildEventListener(context));
|
||||
context.closeables.add(projectBuildLogAppender);
|
||||
MessageUtils.registerShutdownHook(); // safety belt
|
||||
if (context.coloredOutput != null) {
|
||||
MessageUtils.setColorEnabled(context.coloredOutput);
|
||||
}
|
||||
}
|
||||
|
||||
protected Terminal createTerminal(C context) {
|
||||
return new FastTerminal(
|
||||
() -> TerminalBuilder.builder()
|
||||
.name("Maven")
|
||||
.streams(
|
||||
context.invokerRequest.in().orElse(null),
|
||||
context.invokerRequest.out().orElse(null))
|
||||
.dumb(true)
|
||||
.build(),
|
||||
MessageUtils.systemInstall(
|
||||
builder -> {
|
||||
builder.streams(
|
||||
context.invokerRequest.in().orElse(null),
|
||||
context.invokerRequest.out().orElse(null));
|
||||
builder.systemOutput(TerminalBuilder.SystemOutput.ForcedSysOut);
|
||||
// The exec builder suffers from https://github.com/jline/jline3/issues/1098
|
||||
// We could re-enable it when fixed to provide support for non-standard architectures,
|
||||
// for which JLine does not provide any native library.
|
||||
builder.exec(false);
|
||||
if (context.coloredOutput != null) {
|
||||
builder.color(context.coloredOutput);
|
||||
}
|
||||
},
|
||||
terminal -> doConfigureWithTerminal(context, terminal));
|
||||
return MessageUtils.getTerminal();
|
||||
}
|
||||
|
||||
protected void doConfigureWithTerminal(C context, Terminal terminal) {
|
||||
MessageUtils.systemInstall(terminal);
|
||||
AnsiConsole.setTerminal(terminal);
|
||||
AnsiConsole.systemInstall();
|
||||
MessageUtils.registerShutdownHook(); // safety belt
|
||||
|
||||
O options = context.invokerRequest.options();
|
||||
if (options.rawStreams().isEmpty() || !options.rawStreams().get()) {
|
||||
MavenSimpleLogger stdout = (MavenSimpleLogger) context.loggerFactory.getLogger("stdout");
|
||||
@ -349,34 +347,33 @@ protected void doConfigureWithTerminal(C context, Terminal terminal) {
|
||||
}
|
||||
}
|
||||
|
||||
protected BuildEventListener determineBuildEventListener(C context) {
|
||||
if (context.buildEventListener == null) {
|
||||
context.buildEventListener = doDetermineBuildEventListener(context);
|
||||
protected Consumer<String> determineWriter(C context) {
|
||||
if (context.writer == null) {
|
||||
context.writer = doDetermineWriter(context);
|
||||
}
|
||||
return context.buildEventListener;
|
||||
return context.writer;
|
||||
}
|
||||
|
||||
protected BuildEventListener doDetermineBuildEventListener(C context) {
|
||||
BuildEventListener bel;
|
||||
protected Consumer<String> doDetermineWriter(C context) {
|
||||
O options = context.invokerRequest.options();
|
||||
if (options.logFile().isPresent()) {
|
||||
Path logFile = context.cwdResolver.apply(options.logFile().get());
|
||||
try {
|
||||
PrintWriter printWriter = new PrintWriter(Files.newBufferedWriter(logFile));
|
||||
bel = new SimpleBuildEventListener(printWriter::println);
|
||||
context.closeables.add(printWriter);
|
||||
return printWriter::println;
|
||||
} catch (IOException e) {
|
||||
throw new MavenException("Unable to redirect logging to " + logFile, e);
|
||||
}
|
||||
} else {
|
||||
// Given the terminal creation has been offloaded to a different thread,
|
||||
// do not pass directory the terminal writer
|
||||
bel = new SimpleBuildEventListener(msg -> {
|
||||
// do not pass directly the terminal writer
|
||||
return msg -> {
|
||||
PrintWriter pw = context.terminal.writer();
|
||||
pw.println(msg);
|
||||
pw.flush();
|
||||
});
|
||||
};
|
||||
}
|
||||
return bel;
|
||||
}
|
||||
|
||||
protected void activateLogging(C context) throws Exception {
|
||||
@ -412,19 +409,18 @@ protected void activateLogging(C context) throws Exception {
|
||||
}
|
||||
|
||||
protected void helpOrVersionAndMayExit(C context) throws Exception {
|
||||
Consumer<String> writer = determineWriter(context);
|
||||
R invokerRequest = context.invokerRequest;
|
||||
if (invokerRequest.options().help().isPresent()) {
|
||||
invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), context.terminal.writer());
|
||||
context.terminal.writer().flush();
|
||||
invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), writer);
|
||||
throw new ExitException(0);
|
||||
}
|
||||
if (invokerRequest.options().showVersionAndExit().isPresent()) {
|
||||
if (invokerRequest.options().quiet().orElse(false)) {
|
||||
context.terminal.writer().println(CLIReportingUtils.showVersionMinimal());
|
||||
writer.accept(CLIReportingUtils.showVersionMinimal());
|
||||
} else {
|
||||
context.terminal.writer().println(CLIReportingUtils.showVersion());
|
||||
writer.accept(CLIReportingUtils.showVersion());
|
||||
}
|
||||
context.terminal.writer().flush();
|
||||
throw new ExitException(0);
|
||||
}
|
||||
}
|
||||
@ -432,7 +428,7 @@ protected void helpOrVersionAndMayExit(C context) throws Exception {
|
||||
protected void preCommands(C context) throws Exception {
|
||||
Options mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.verbose().orElse(false) || mavenOptions.showVersion().orElse(false)) {
|
||||
context.terminal.writer().println(CLIReportingUtils.showVersion());
|
||||
determineWriter(context).accept(CLIReportingUtils.showVersion());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -63,8 +64,11 @@
|
||||
import org.apache.maven.execution.ProjectActivation;
|
||||
import org.apache.maven.jline.MessageUtils;
|
||||
import org.apache.maven.lifecycle.LifecycleExecutionException;
|
||||
import org.apache.maven.logging.BuildEventListener;
|
||||
import org.apache.maven.logging.LoggingExecutionListener;
|
||||
import org.apache.maven.logging.MavenTransferListener;
|
||||
import org.apache.maven.logging.ProjectBuildLogAppender;
|
||||
import org.apache.maven.logging.SimpleBuildEventListener;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.codehaus.plexus.PlexusContainer;
|
||||
import org.eclipse.aether.DefaultRepositoryCache;
|
||||
@ -89,6 +93,7 @@ protected MavenContext(DefaultMavenInvoker<O, R, C> invoker, R invokerRequest) {
|
||||
super(invoker, invokerRequest);
|
||||
}
|
||||
|
||||
public BuildEventListener buildEventListener;
|
||||
public MavenExecutionRequest mavenExecutionRequest;
|
||||
public EventSpyDispatcher eventSpyDispatcher;
|
||||
public MavenExecutionRequestPopulator mavenExecutionRequestPopulator;
|
||||
@ -161,6 +166,27 @@ protected void postCommands(C context) throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureLogging(C context) throws Exception {
|
||||
super.configureLogging(context);
|
||||
// Create the build log appender
|
||||
ProjectBuildLogAppender projectBuildLogAppender =
|
||||
new ProjectBuildLogAppender(determineBuildEventListener(context));
|
||||
context.closeables.add(projectBuildLogAppender);
|
||||
}
|
||||
|
||||
protected BuildEventListener determineBuildEventListener(C context) {
|
||||
if (context.buildEventListener == null) {
|
||||
context.buildEventListener = doDetermineBuildEventListener(context);
|
||||
}
|
||||
return context.buildEventListener;
|
||||
}
|
||||
|
||||
protected BuildEventListener doDetermineBuildEventListener(C context) {
|
||||
Consumer<String> writer = determineWriter(context);
|
||||
return new SimpleBuildEventListener(writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void customizeSettingsRequest(C context, SettingsBuilderRequest settingsBuilderRequest) {
|
||||
if (context.eventSpyDispatcher != null) {
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.maven.jline;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.maven.api.services.MessageBuilder;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
import org.jline.jansi.AnsiConsole;
|
||||
@ -41,11 +43,26 @@ public static void systemInstall(Terminal terminal) {
|
||||
}
|
||||
|
||||
public static void systemInstall() {
|
||||
systemInstall(null, null);
|
||||
}
|
||||
|
||||
public static void systemInstall(Consumer<TerminalBuilder> builderConsumer, Consumer<Terminal> terminalConsumer) {
|
||||
MessageUtils.terminal = new FastTerminal(
|
||||
() -> TerminalBuilder.builder().name("Maven").dumb(true).build(), terminal -> {
|
||||
() -> {
|
||||
TerminalBuilder builder =
|
||||
TerminalBuilder.builder().name("Maven").dumb(true);
|
||||
if (builderConsumer != null) {
|
||||
builderConsumer.accept(builder);
|
||||
}
|
||||
return builder.build();
|
||||
},
|
||||
terminal -> {
|
||||
MessageUtils.reader = createReader(terminal);
|
||||
AnsiConsole.setTerminal(terminal);
|
||||
AnsiConsole.systemInstall();
|
||||
if (terminalConsumer != null) {
|
||||
terminalConsumer.accept(terminal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user