summaryrefslogtreecommitdiff
path: root/core/src/main/scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-01-05 21:59:02 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-01-05 22:03:35 -0800
commitdd16d55e95e5cc21c102fe49b4cf0e727261fedf (patch)
tree4c1209eb07adc094dd682aa05db5e5e57d0cb925 /core/src/main/scala
parentc5271eeb2492136a2dd70e4bdad948fb4976e580 (diff)
downloadmill-dd16d55e95e5cc21c102fe49b4cf0e727261fedf.tar.gz
mill-dd16d55e95e5cc21c102fe49b4cf0e727261fedf.tar.bz2
mill-dd16d55e95e5cc21c102fe49b4cf0e727261fedf.zip
Forward bulk output to `stderr` when `--show` is called, reserving `stdout` for the shown JSON blob
Diffstat (limited to 'core/src/main/scala')
-rw-r--r--core/src/main/scala/mill/Main.scala2
-rw-r--r--core/src/main/scala/mill/eval/Evaluator.scala4
-rw-r--r--core/src/main/scala/mill/main/MainRunner.scala29
-rw-r--r--core/src/main/scala/mill/main/ReplApplyHandler.scala1
-rw-r--r--core/src/main/scala/mill/main/RunScript.scala7
-rw-r--r--core/src/main/scala/mill/modules/Jvm.scala15
-rw-r--r--core/src/main/scala/mill/util/Logger.scala69
7 files changed, 92 insertions, 35 deletions
diff --git a/core/src/main/scala/mill/Main.scala b/core/src/main/scala/mill/Main.scala
index 479366b2..684040a7 100644
--- a/core/src/main/scala/mill/Main.scala
+++ b/core/src/main/scala/mill/Main.scala
@@ -60,7 +60,7 @@ object Main {
val runner = new mill.main.MainRunner(
config, show,
- System.out, System.err, System.in, System.out, System.err
+ System.out, System.err, System.in
)
if (repl){
runner.printInfo("Loading...")
diff --git a/core/src/main/scala/mill/eval/Evaluator.scala b/core/src/main/scala/mill/eval/Evaluator.scala
index 9149e532..17108307 100644
--- a/core/src/main/scala/mill/eval/Evaluator.scala
+++ b/core/src/main/scala/mill/eval/Evaluator.scala
@@ -219,10 +219,10 @@ class Evaluator[T](val workspacePath: Path,
val out = System.out
val err = System.err
try{
- System.setErr(multiLogger.outputStream)
+ System.setErr(multiLogger.errorStream)
System.setOut(multiLogger.outputStream)
Console.withOut(multiLogger.outputStream){
- Console.withErr(multiLogger.outputStream){
+ Console.withErr(multiLogger.errorStream){
target.evaluate(args)
}
}
diff --git a/core/src/main/scala/mill/main/MainRunner.scala b/core/src/main/scala/mill/main/MainRunner.scala
index 4a6be436..76e2d069 100644
--- a/core/src/main/scala/mill/main/MainRunner.scala
+++ b/core/src/main/scala/mill/main/MainRunner.scala
@@ -7,6 +7,7 @@ import ammonite.ops.Path
import ammonite.util._
import mill.discover.Discovered
import mill.eval.{Evaluator, PathRef}
+import mill.util.PrintLogger
import upickle.Js
/**
@@ -14,13 +15,15 @@ import upickle.Js
* `build.sc` scripts with mill-specific tweaks such as a custom
* `scriptCodeWrapper` or with a persistent evaluator between runs.
*/
-class MainRunner(config: ammonite.main.Cli.Config, show: Boolean,
+class MainRunner(config: ammonite.main.Cli.Config,
+ show: Boolean,
outprintStream: PrintStream,
errPrintStream: PrintStream,
- stdIn: InputStream,
- stdOut: OutputStream,
- stdErr: OutputStream)
- extends ammonite.MainRunner(config, outprintStream, errPrintStream, stdIn, stdOut, stdErr){
+ stdIn: InputStream)
+ extends ammonite.MainRunner(
+ config, outprintStream, errPrintStream,
+ stdIn, outprintStream, errPrintStream
+ ){
var lastEvaluator: Option[(Seq[(Path, Long)], Evaluator[_])] = None
override def runScript(scriptPath: Path, scriptArgs: List[String]) =
@@ -29,8 +32,18 @@ class MainRunner(config: ammonite.main.Cli.Config, show: Boolean,
printing = true,
mainCfg => {
val (result, interpWatched) = RunScript.runScript(
- mainCfg.wd, scriptPath, mainCfg.instantiateInterpreter(), scriptArgs, lastEvaluator,
- errPrintStream, errPrintStream, colors
+ mainCfg.wd,
+ scriptPath,
+ mainCfg.instantiateInterpreter(),
+ scriptArgs,
+ lastEvaluator,
+ new PrintLogger(
+ colors != ammonite.util.Colors.BlackWhite,
+ colors,
+ if (show) errPrintStream else outprintStream,
+ errPrintStream,
+ errPrintStream
+ )
)
result match{
@@ -50,7 +63,7 @@ class MainRunner(config: ammonite.main.Cli.Config, show: Boolean,
case Res.Success(value) =>
if (show){
for(json <- value.asInstanceOf[Seq[Js.Value]]){
- System.out.println(json)
+ outprintStream.println(json)
}
}
diff --git a/core/src/main/scala/mill/main/ReplApplyHandler.scala b/core/src/main/scala/mill/main/ReplApplyHandler.scala
index e68dfd93..1e88ee53 100644
--- a/core/src/main/scala/mill/main/ReplApplyHandler.scala
+++ b/core/src/main/scala/mill/main/ReplApplyHandler.scala
@@ -22,6 +22,7 @@ object ReplApplyHandler{
new mill.util.PrintLogger(
colors != ammonite.util.Colors.BlackWhite,
colors,
+ System.out,
System.err,
System.err
)
diff --git a/core/src/main/scala/mill/main/RunScript.scala b/core/src/main/scala/mill/main/RunScript.scala
index bd27039c..7e578fb0 100644
--- a/core/src/main/scala/mill/main/RunScript.scala
+++ b/core/src/main/scala/mill/main/RunScript.scala
@@ -12,7 +12,7 @@ import mill.define.Task
import mill.discover.Mirror.Segment
import mill.discover.{Discovered, Mirror}
import mill.eval.{Evaluator, PathRef, Result}
-import mill.util.{OSet, PrintLogger}
+import mill.util.{Logger, OSet, PrintLogger}
import upickle.Js
/**
@@ -26,12 +26,9 @@ object RunScript{
instantiateInterpreter: => Either[(Res.Failing, Seq[(Path, Long)]), ammonite.interp.Interpreter],
scriptArgs: Seq[String],
lastEvaluator: Option[(Seq[(Path, Long)], Evaluator[_])],
- infoStream: PrintStream,
- errStream: PrintStream,
- colors: ammonite.util.Colors)
+ log: Logger)
: (Res[(Evaluator[_], Seq[(Path, Long)], Either[String, Seq[Js.Value]])], Seq[(Path, Long)]) = {
- val log = new PrintLogger(colors != ammonite.util.Colors.BlackWhite, colors, infoStream, errStream)
val (evalRes, interpWatched) = lastEvaluator match{
case Some((prevInterpWatchedSig, prevEvaluator))
if watchedSigUnchanged(prevInterpWatchedSig) =>
diff --git a/core/src/main/scala/mill/modules/Jvm.scala b/core/src/main/scala/mill/modules/Jvm.scala
index 1bff3c9b..e6806923 100644
--- a/core/src/main/scala/mill/modules/Jvm.scala
+++ b/core/src/main/scala/mill/modules/Jvm.scala
@@ -60,7 +60,10 @@ object Jvm {
val stdout = proc.getInputStream
val stderr = proc.getErrorStream
- val sources = Seq(stdout -> (Left(_: Bytes)), stderr -> (Right(_: Bytes)))
+ val sources = Seq(
+ (stdout, Left(_: Bytes), ctx.log.outputStream),
+ (stderr, Right(_: Bytes),ctx.log.errorStream )
+ )
val chunks = mutable.Buffer.empty[Either[Bytes, Bytes]]
while(
// Process.isAlive doesn't exist on JDK 7 =/
@@ -69,13 +72,13 @@ object Jvm {
stderr.available() > 0
){
var readSomething = false
- for ((std, wrapper) <- sources){
- while (std.available() > 0){
+ for ((subStream, wrapper, parentStream) <- sources){
+ while (subStream.available() > 0){
readSomething = true
- val array = new Array[Byte](std.available())
- val actuallyRead = std.read(array)
+ val array = new Array[Byte](subStream.available())
+ val actuallyRead = subStream.read(array)
chunks.append(wrapper(new ammonite.ops.Bytes(array)))
- ctx.log.outputStream.write(array, 0, actuallyRead)
+ parentStream.write(array, 0, actuallyRead)
}
}
// if we did not read anything sleep briefly to avoid spinning
diff --git a/core/src/main/scala/mill/util/Logger.scala b/core/src/main/scala/mill/util/Logger.scala
index 5a843002..316e17ff 100644
--- a/core/src/main/scala/mill/util/Logger.scala
+++ b/core/src/main/scala/mill/util/Logger.scala
@@ -6,25 +6,38 @@ import ammonite.ops.Path
import ammonite.util.Colors
+/**
+ * The standard logging interface of the Mill build tool.
+ *
+ * Contains four primary logging methods, in order of increasing importance:
+ *
+ * - `ticker`: short-lived logging output where consecutive lines over-write
+ * each other; useful for information which is transient and disposable
+ *
+ * - `info`: miscellaneous logging output which isn't part of the main output
+ * a user is looking for, but useful to provide context on what Mill is doing
+ *
+ * - `error`: logging output which represents problems the user should care
+ * about
+ *
+ * Also contains the two forwarded stdout and stderr streams, for code executed
+ * by Mill to use directly. Typically these correspond to the stdout and stderr,
+ * but when `--show` is used both are forwarded to stderr and stdout is only
+ * used to display the final `--show` output for easy piping.
+ */
trait Logger {
def colored: Boolean
+ val errorStream: PrintStream
val outputStream: PrintStream
def info(s: String): Unit
def error(s: String): Unit
-
- /**
- * Like [[info]], but if two calls to [[ticker]] are made consecutively
- * without any calls to [[info]]/[[error]][[outputStream]] in between,
- * the second call to [[ticker]] over-writes the first one in the console.
- * This is useful for displaying loading bars, progress updates or all other
- * sorts of fast-changing information to the user
- */
def ticker(s: String): Unit
def close(): Unit = ()
}
object DummyLogger extends Logger {
def colored = false
+ object errorStream extends PrintStream(_ => ())
object outputStream extends PrintStream(_ => ())
def info(s: String) = ()
def error(s: String) = ()
@@ -33,36 +46,56 @@ object DummyLogger extends Logger {
case class PrintLogger(colored: Boolean,
colors: ammonite.util.Colors,
+ outStream: PrintStream,
infoStream: PrintStream,
- errorStream: PrintStream) extends Logger {
+ errStream: PrintStream) extends Logger {
var lastLineTicker = false
+ override val errorStream = new PrintStream(
+ new OutputStream {
+ override def write(b: Array[Byte]): Unit = {
+ lastLineTicker = false
+ errStream.write(b)
+ }
+
+ override def write(b: Array[Byte], off: Int, len: Int): Unit = {
+ lastLineTicker = false
+ errStream.write(b, off, len)
+ }
+
+ def write(b: Int) = {
+ lastLineTicker = false
+ errStream.write(b)
+ }
+ }
+ )
override val outputStream = new PrintStream(
new OutputStream {
override def write(b: Array[Byte]): Unit = {
lastLineTicker = false
- infoStream.write(b)
+ outStream.write(b)
}
override def write(b: Array[Byte], off: Int, len: Int): Unit = {
lastLineTicker = false
- infoStream.write(b, off, len)
+ outStream.write(b, off, len)
}
def write(b: Int) = {
lastLineTicker = false
- infoStream.write(b)
+ outStream.write(b)
}
}
)
+
def info(s: String) = {
lastLineTicker = false
infoStream.println(colors.info()(s))
}
def error(s: String) = {
lastLineTicker = false
- errorStream.println(colors.error()(s))
+ errStream.println(colors.error()(s))
}
def ticker(s: String) = {
if (lastLineTicker){
@@ -86,6 +119,11 @@ case class FileLogger(colored: Boolean, file: Path) extends Logger {
new PrintStream(new FileOutputStream(file.toIO.getAbsolutePath))
}
+ lazy val errorStream = {
+ outputStreamUsed = true
+ new PrintStream(new FileOutputStream(file.toIO.getAbsolutePath))
+ }
+
def info(s: String) = outputStream.println(s)
def error(s: String) = outputStream.println(s)
def ticker(s: String) = outputStream.println(s)
@@ -101,6 +139,11 @@ case class MultiLogger(colored: Boolean, streams: Logger*) extends Logger {
override def flush() = streams.foreach(_.outputStream.flush())
override def close() = streams.foreach(_.outputStream.close())
}
+ lazy val errorStream: PrintStream =
+ new PrintStream(b => streams.foreach(_.outputStream.write(b))) {
+ override def flush() = streams.foreach(_.outputStream.flush())
+ override def close() = streams.foreach(_.outputStream.close())
+ }
def info(s: String) = streams.foreach(_.info(s))
def error(s: String) = streams.foreach(_.error(s))