From ee49cb34141a8f2c7e1a2a6253af7d3756464700 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 2 Sep 2021 14:37:19 +0200 Subject: [PATCH] Provide a way to remove decoration on the standard out/err streams, fixes #356 --- .../org/mvndaemon/mvnd/common/Message.java | 19 ++++++ .../mvnd/common/logging/TerminalOutput.java | 12 ++++ .../org/apache/maven/cli/DaemonMavenCli.java | 6 +- .../org/mvndaemon/mvnd/daemon/Server.java | 3 + .../org/mvndaemon/mvnd/it/RawStreamsTest.java | 62 +++++++++++++++++++ .../src/test/projects/raw-streams/pom.xml | 50 +++++++++++++++ 6 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 integration-tests/src/test/java/org/mvndaemon/mvnd/it/RawStreamsTest.java create mode 100644 integration-tests/src/test/projects/raw-streams/pom.xml diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/Message.java b/common/src/main/java/org/mvndaemon/mvnd/common/Message.java index 0b43ca8e..8444727b 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/Message.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/Message.java @@ -56,6 +56,8 @@ public abstract class Message { public static final int TRANSFER_SUCCEEDED = 22; public static final int TRANSFER_FAILED = 23; public static final int EXECUTION_FAILURE = 24; + public static final int PRINT_OUT = 25; + public static final int PRINT_ERR = 26; final int type; @@ -106,6 +108,9 @@ public abstract class Message { return TransferEvent.read(type, input); case EXECUTION_FAILURE: return ExecutionFailureEvent.read(input); + case PRINT_OUT: + case PRINT_ERR: + return StringMessage.read(type, input); } throw new IllegalStateException("Unexpected message type: " + type); } @@ -126,6 +131,8 @@ public abstract class Message { case PROMPT: case PROMPT_RESPONSE: case DISPLAY: + case PRINT_OUT: + case PRINT_ERR: return 2; case PROJECT_STARTED: return 3; @@ -703,6 +710,10 @@ public abstract class Message { return "BuildLogMessage"; case DISPLAY: return "Display"; + case PRINT_OUT: + return "PrintOut"; + case PRINT_ERR: + return "PrintErr"; default: throw new IllegalStateException("Unexpected type " + type); } @@ -1015,6 +1026,14 @@ public abstract class Message { return new StringMessage(DISPLAY, message); } + public static StringMessage out(String message) { + return new StringMessage(PRINT_OUT, message); + } + + public static StringMessage err(String message) { + return new StringMessage(PRINT_ERR, message); + } + public static StringMessage log(String message) { return new StringMessage(BUILD_LOG_MESSAGE, message); } diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/logging/TerminalOutput.java b/common/src/main/java/org/mvndaemon/mvnd/common/logging/TerminalOutput.java index 0e712168..39788640 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/logging/TerminalOutput.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/logging/TerminalOutput.java @@ -306,6 +306,18 @@ public class TerminalOutput implements ClientOutput { terminal.writer().printf("%s%n", d.getMessage()); break; } + case Message.PRINT_OUT: { + Message.StringMessage d = (Message.StringMessage) entry; + clearDisplay(); + System.out.printf("%s%n", d.getMessage()); + break; + } + case Message.PRINT_ERR: { + Message.StringMessage d = (Message.StringMessage) entry; + clearDisplay(); + System.err.printf("%s%n", d.getMessage()); + break; + } case Message.PROMPT: { Message.Prompt prompt = (Message.Prompt) entry; if (dumb) { diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java index 4511553e..be553278 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java @@ -152,6 +152,8 @@ public class DaemonMavenCli { public static final String RESUME = "r"; + public static final String RAW_STREAMS = "raw-streams"; + private final Slf4jLoggerManager plexusLoggerManager; private final ILoggerFactory slf4jLoggerFactory; @@ -323,6 +325,8 @@ public class DaemonMavenCli { CLIManager cliManager = new CLIManager(); cliManager.options.addOption(Option.builder(RESUME).longOpt("resume").desc("Resume reactor from " + "the last failed project, using the resume.properties file in the build directory").build()); + cliManager.options.addOption(Option.builder().longOpt(RAW_STREAMS).desc("Do not decorate output and " + + "error streams").build()); return cliManager; } @@ -409,7 +413,7 @@ public class DaemonMavenCli { // Ignore // } - } else { + } else if (!cliRequest.commandLine.hasOption(RAW_STREAMS)) { ch.qos.logback.classic.Logger stdout = (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stdout"); ch.qos.logback.classic.Logger stderr = (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stderr"); stdout.setLevel(ch.qos.logback.classic.Level.INFO); diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java b/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java index 2c2fb0bb..1d6974f3 100644 --- a/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java +++ b/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java @@ -58,6 +58,7 @@ import org.mvndaemon.mvnd.common.SocketFamily; import org.mvndaemon.mvnd.daemon.DaemonExpiration.DaemonExpirationResult; import org.mvndaemon.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy; import org.mvndaemon.mvnd.logging.smart.BuildEventListener; +import org.mvndaemon.mvnd.logging.smart.LoggingOutputStream; import org.mvndaemon.mvnd.logging.smart.ProjectBuildLogAppender; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -567,6 +568,8 @@ public class Server implements AutoCloseable, Runnable { } } }); + System.setOut(new LoggingOutputStream(s -> sendQueue.add(Message.out(s))).printStream()); + System.setErr(new LoggingOutputStream(s -> sendQueue.add(Message.err(s))).printStream()); int exitCode = cli.main( buildRequest.getArgs(), buildRequest.getWorkingDir(), diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/RawStreamsTest.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/RawStreamsTest.java new file mode 100644 index 00000000..4a38e494 --- /dev/null +++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/RawStreamsTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2019-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mvndaemon.mvnd.it; + +import java.io.IOException; +import javax.inject.Inject; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mvndaemon.mvnd.assertj.TestClientOutput; +import org.mvndaemon.mvnd.client.Client; +import org.mvndaemon.mvnd.client.DaemonParameters; +import org.mvndaemon.mvnd.junit.MvndTest; +import org.mvndaemon.mvnd.junit.TestRegistry; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@MvndTest(projectDir = "src/test/projects/raw-streams") +public class RawStreamsTest { + + @Inject + Client client; + + @Inject + DaemonParameters parameters; + + @Inject + TestRegistry registry; + + @Test + void version() throws IOException, InterruptedException { + registry.killAll(); + assertDaemonRegistrySize(0); + + final TestClientOutput o = new TestClientOutput(); + client.execute(o, "validate", "--quiet", "--raw-streams").assertSuccess(); + String expected = "PrintOut{payload='Hello'}"; + o.getMessages().forEach(m -> System.out.println(m.toString())); + assertTrue(o.getMessages().stream() + .anyMatch(m -> m.toString().contains(expected)), "Output should contain " + expected); + assertDaemonRegistrySize(1); + } + + private void assertDaemonRegistrySize(int size) { + Assertions.assertThat(registry.getAll().size()) + .as("Daemon registry size should be " + size) + .isEqualTo(size); + } + +} diff --git a/integration-tests/src/test/projects/raw-streams/pom.xml b/integration-tests/src/test/projects/raw-streams/pom.xml new file mode 100644 index 00000000..b8ad56d5 --- /dev/null +++ b/integration-tests/src/test/projects/raw-streams/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + org.mvndaemon.mvnd.test.raw-streams + raw-streams + 0.0.1-SNAPSHOT + pom + + + + + org.codehaus.gmaven + groovy-maven-plugin + 2.1.1 + + + validate + + execute + + + + println 'Hello' + + + + + + + + + \ No newline at end of file