From d6f56f899cbe8883c722d172b616d946e0a7a15c Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sun, 19 Nov 2023 19:13:55 +0800 Subject: [PATCH] Make `mill show` skip `-j` prefixes to ensure machine readability (#2884) This requires us add another method `Logger#rawOutputStream`, which the various implementations forward without decorating with prefixes or other things. We cannot just use `SystemStreams.original` because when running Mill in client/server mode we still need to use the `OutputStream` that gets forwarded from server to client, as the `SystemStreams.original.out` just ends up forwarded to `out/mill-worker-hash-1/stdout` files that aren't surfaced to users Tested manually with `./mill -i dev.run tmp -i -j 2 show foo` on an example build in the `tmp/` folder. Previously it would show the output of `show` with a prefix e.g. `[#0] "bar"`, after this PR it shows the output without any prefixes `"bar"` `Logger#rawOutputStream` has to be a non-abstract method for binary compatibility. This makes it a bit error prone since you can easily forget to override it where necessary. So I first made it abstract, made sure everyone overrides it, and then added the default case. Pull request: https://github.com/com-lihaoyi/mill/pull/2884 --- bsp/src/mill/bsp/BspContext.scala | 3 +++ main/api/src/mill/api/Logger.scala | 8 ++++++++ main/eval/src/mill/eval/GroupEvaluator.scala | 3 +++ main/src/mill/main/MainModule.scala | 2 +- main/util/src/mill/util/DummyLogger.scala | 1 + main/util/src/mill/util/FileLogger.scala | 2 ++ main/util/src/mill/util/MultiLogger.scala | 2 ++ main/util/src/mill/util/PrefixLogger.scala | 2 ++ main/util/src/mill/util/PrintLogger.scala | 2 ++ main/util/src/mill/util/ProxyLogger.scala | 4 ++++ 10 files changed, 28 insertions(+), 1 deletion(-) diff --git a/bsp/src/mill/bsp/BspContext.scala b/bsp/src/mill/bsp/BspContext.scala index 4755c765a13..25a7ab6dbfa 100644 --- a/bsp/src/mill/bsp/BspContext.scala +++ b/bsp/src/mill/bsp/BspContext.scala @@ -56,7 +56,10 @@ private[mill] class BspContext( override def error(s: String): Unit = streams.err.println(s) override def ticker(s: String): Unit = streams.err.println(s) override def debug(s: String): Unit = streams.err.println(s) + override def debugEnabled: Boolean = true + + override def rawOutputStream: PrintStream = systemStreams.out } BspWorker(os.pwd, home, log).flatMap { worker => diff --git a/main/api/src/mill/api/Logger.scala b/main/api/src/mill/api/Logger.scala index 9ca0750bae9..3c6967558e9 100644 --- a/main/api/src/mill/api/Logger.scala +++ b/main/api/src/mill/api/Logger.scala @@ -31,6 +31,14 @@ trait Logger { def errorStream: PrintStream = systemStreams.err def outputStream: PrintStream = systemStreams.out + + /** + * [[rawOutputStream]] is intended to be a version of [[outputStream]] + * without decoration: colors, prefixes, timestamps, etc. It is intended + * for the use of tasks like `show` which output data in a way that is + * easily readable by downstream programs. + */ + def rawOutputStream: PrintStream = systemStreams.out def inStream: InputStream = systemStreams.in def info(s: String): Unit diff --git a/main/eval/src/mill/eval/GroupEvaluator.scala b/main/eval/src/mill/eval/GroupEvaluator.scala index 8754b67a539..32101df6bd4 100644 --- a/main/eval/src/mill/eval/GroupEvaluator.scala +++ b/main/eval/src/mill/eval/GroupEvaluator.scala @@ -7,6 +7,7 @@ import mill.define._ import mill.eval.Evaluator.TaskResult import mill.util._ +import java.io.PrintStream import scala.collection.mutable import scala.reflect.NameTransformer.{encode, decode} import scala.util.DynamicVariable @@ -274,6 +275,8 @@ private[mill] trait GroupEvaluator { if (enableTicker) super.ticker(tickerPrefix.getOrElse("") + s) else () // do nothing } + + override def rawOutputStream: PrintStream = logger.rawOutputStream } // This is used to track the usage of `T.dest` in more than one Task // But it's not really clear what issue we try to prevent here diff --git a/main/src/mill/main/MainModule.scala b/main/src/mill/main/MainModule.scala index cb5cb7c90f2..113616cc9dc 100644 --- a/main/src/mill/main/MainModule.scala +++ b/main/src/mill/main/MainModule.scala @@ -50,7 +50,7 @@ object MainModule { case Right((watched, Right(res))) => val output = f(res) watched.foreach(watch0) - log.outputStream.println(output.render(indent = 2)) + log.rawOutputStream.println(output.render(indent = 2)) Result.Success(output) } } diff --git a/main/util/src/mill/util/DummyLogger.scala b/main/util/src/mill/util/DummyLogger.scala index 12a6c88defc..14685983ea5 100644 --- a/main/util/src/mill/util/DummyLogger.scala +++ b/main/util/src/mill/util/DummyLogger.scala @@ -12,6 +12,7 @@ object DummyLogger extends Logger { new PrintStream(_ => ()), new ByteArrayInputStream(Array()) ) + override def rawOutputStream = systemStreams.out def info(s: String) = () def error(s: String) = () diff --git a/main/util/src/mill/util/FileLogger.scala b/main/util/src/mill/util/FileLogger.scala index 475aa3320ad..d6c239d8c95 100644 --- a/main/util/src/mill/util/FileLogger.scala +++ b/main/util/src/mill/util/FileLogger.scala @@ -52,4 +52,6 @@ class FileLogger( if (outputStreamUsed) outputStream.close() } + + override def rawOutputStream: PrintStream = outputStream } diff --git a/main/util/src/mill/util/MultiLogger.scala b/main/util/src/mill/util/MultiLogger.scala index dd278718c3c..fae66c13a32 100644 --- a/main/util/src/mill/util/MultiLogger.scala +++ b/main/util/src/mill/util/MultiLogger.scala @@ -40,6 +40,8 @@ class MultiLogger( logger1.close() logger2.close() } + + override def rawOutputStream: PrintStream = systemStreams.out } class MultiStream(stream1: OutputStream, stream2: OutputStream) diff --git a/main/util/src/mill/util/PrefixLogger.scala b/main/util/src/mill/util/PrefixLogger.scala index 61d0cadc08a..a9aa641515e 100644 --- a/main/util/src/mill/util/PrefixLogger.scala +++ b/main/util/src/mill/util/PrefixLogger.scala @@ -36,6 +36,8 @@ class PrefixLogger( logger0.systemStreams.in ) + override def rawOutputStream = logger0.rawOutputStream + override def info(s: String): Unit = logger0.info(context + s) override def error(s: String): Unit = logger0.error(context + s) override def ticker(s: String): Unit = logger0.ticker(context + tickerContext + s) diff --git a/main/util/src/mill/util/PrintLogger.scala b/main/util/src/mill/util/PrintLogger.scala index a3823dafc09..ba1cc75c000 100644 --- a/main/util/src/mill/util/PrintLogger.scala +++ b/main/util/src/mill/util/PrintLogger.scala @@ -76,6 +76,8 @@ class PrintLogger( systemStreams.err.println(context + s) } } + + override def rawOutputStream: PrintStream = systemStreams.out } object PrintLogger { diff --git a/main/util/src/mill/util/ProxyLogger.scala b/main/util/src/mill/util/ProxyLogger.scala index beacdfd621b..7150bdece46 100644 --- a/main/util/src/mill/util/ProxyLogger.scala +++ b/main/util/src/mill/util/ProxyLogger.scala @@ -2,6 +2,8 @@ package mill.util import mill.api.Logger +import java.io.PrintStream + /** * A Logger that forwards all logging to another Logger. Intended to be * used as a base class for wrappers that modify logging behavior. @@ -19,4 +21,6 @@ class ProxyLogger(logger: Logger) extends Logger { override def debugEnabled: Boolean = logger.debugEnabled override def close() = logger.close() + + override def rawOutputStream: PrintStream = logger.rawOutputStream }