From cf7ef024e73b11baac860862bd5f2450611b85b9 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sun, 25 Feb 2018 19:14:08 -0800 Subject: Lazily create `dest` folders, `log` files and `OuterStack` traces only as necessary. Now we only create them if a Task asks for `T.ctx().dest` or logs something. The vast majority of tasks just do plumbing and neither log output nor create files in `dest`, and this avoids the unnecessary overhead of creating all those un-used files, folders & stack trace --- core/src/mill/eval/Evaluator.scala | 22 ++++++++++------------ core/src/mill/util/Logger.scala | 4 +++- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'core') diff --git a/core/src/mill/eval/Evaluator.scala b/core/src/mill/eval/Evaluator.scala index 42015c6f..b3fcde2c 100644 --- a/core/src/mill/eval/Evaluator.scala +++ b/core/src/mill/eval/Evaluator.scala @@ -147,7 +147,7 @@ case class Evaluator[T](outPath: Path, labelledNamedTask.segments ) - mkdir(paths.out) + if (!exists(paths.out)) mkdir(paths.out) val cached = for{ json <- scala.util.Try(upickle.json.read(paths.meta.toIO)).toOption cached <- scala.util.Try(upickle.default.readJs[Evaluator.Cached](json)).toOption @@ -257,7 +257,6 @@ case class Evaluator[T](outPath: Path, val multiLogger = resolveLogger(paths.map(_.log)) var usedDest = Option.empty[(Task[_], Array[StackTraceElement])] for (task <- nonEvaluatedTargets) { - val currentStack = new Exception().getStackTrace newEvaluated.append(task) val targetInputValues = task.inputs .map(x => newResults.getOrElse(x, results(x))) @@ -277,13 +276,12 @@ case class Evaluator[T](outPath: Path, inner ) case _ => - usedDest = Some(( - task, - new Exception().getStackTrace.dropRight(currentStack.length) - )) + + paths match{ case Some(dest) => - mkdir(dest.dest) + if (usedDest.isEmpty) mkdir(dest.dest) + usedDest = Some((task, new Exception().getStackTrace)) dest.dest case None => throw new Exception("No `dest` folder available here") @@ -302,11 +300,13 @@ case class Evaluator[T](outPath: Path, Console.withIn(multiLogger.inStream){ Console.withOut(multiLogger.outputStream){ Console.withErr(multiLogger.errorStream){ - task.evaluate(args) + try task.evaluate(args) + catch { case NonFatal(e) => + Result.Exception(e, new OuterStack(new Exception().getStackTrace)) + } } } } - }catch{ case NonFatal(e) => Result.Exception(e, new OuterStack(currentStack)) }finally{ System.setErr(err) System.setOut(out) @@ -329,9 +329,7 @@ case class Evaluator[T](outPath: Path, def resolveLogger(logPath: Option[Path]): Logger = logPath match{ case None => log - case Some(path) => - rm(path) - MultiLogger(log.colored, log, FileLogger(log.colored, path)) + case Some(path) => MultiLogger(log.colored, log, FileLogger(log.colored, path)) } } diff --git a/core/src/mill/util/Logger.scala b/core/src/mill/util/Logger.scala index 714b9add..dfa7964a 100644 --- a/core/src/mill/util/Logger.scala +++ b/core/src/mill/util/Logger.scala @@ -2,7 +2,7 @@ package mill.util import java.io._ -import ammonite.ops.Path +import ammonite.ops.{Path, rm} import ammonite.util.Colors @@ -124,11 +124,13 @@ case class FileLogger(colored: Boolean, file: Path) extends Logger { private[this] var outputStreamUsed: Boolean = false lazy val outputStream = { + if (!outputStreamUsed) rm(file) outputStreamUsed = true new PrintStream(new FileOutputStream(file.toIO.getAbsolutePath)) } lazy val errorStream = { + if (!outputStreamUsed) rm(file) outputStreamUsed = true new PrintStream(new FileOutputStream(file.toIO.getAbsolutePath)) } -- cgit v1.2.3