From 9f2f37602b6e93f5e2900439d0c66efd29a30862 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 28 Dec 2017 10:46:19 -0800 Subject: First pass at generating CLI output when you run `Target`s, based on their return values, converted to JSON --- core/src/main/scala/mill/Main.scala | 14 +++++++++-- core/src/main/scala/mill/main/MainRunner.scala | 27 +++++++++++++++----- core/src/main/scala/mill/main/RunScript.scala | 35 +++++++++++++++++++------- 3 files changed, 59 insertions(+), 17 deletions(-) (limited to 'core') diff --git a/core/src/main/scala/mill/Main.scala b/core/src/main/scala/mill/Main.scala index 97499db6..470d9cbc 100644 --- a/core/src/main/scala/mill/Main.scala +++ b/core/src/main/scala/mill/Main.scala @@ -12,6 +12,7 @@ object Main { import ammonite.main.Cli var repl = false + var show = false val replCliArg = Cli.Arg[Cli.Config, Unit]( "repl", None, @@ -21,9 +22,18 @@ object Main { x } ) + val showCliArg = Cli.Arg[Cli.Config, Unit]( + "show", + None, + "Display the json-formatted value of the given target, if any", + (x, _) => { + show = true + x + } + ) Cli.groupArgs( args.toList, - Cli.ammoniteArgSignature :+ replCliArg, + Cli.ammoniteArgSignature :+ replCliArg :+ showCliArg, Cli.Config() ) match{ case Left(msg) => @@ -41,7 +51,7 @@ object Main { welcomeBanner = None ) - val runner = new mill.main.MainRunner(config) + val runner = new mill.main.MainRunner(config, show) if (repl){ runner.printInfo("Loading...") runner.runRepl() diff --git a/core/src/main/scala/mill/main/MainRunner.scala b/core/src/main/scala/mill/main/MainRunner.scala index 28d0a284..f354e838 100644 --- a/core/src/main/scala/mill/main/MainRunner.scala +++ b/core/src/main/scala/mill/main/MainRunner.scala @@ -4,13 +4,15 @@ import ammonite.ops.Path import ammonite.util.{Imports, Name, Res, Util} import mill.discover.Discovered import mill.eval.Evaluator +import upickle.Js /** * Customized version of [[ammonite.MainRunner]], allowing us to run Mill * `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) +class MainRunner(config: ammonite.main.Cli.Config, + show: Boolean) extends ammonite.MainRunner( config, System.out, System.err, System.in, System.out, System.err @@ -31,9 +33,9 @@ class MainRunner(config: ammonite.main.Cli.Config) ) result match{ case Res.Success(data) => - val (eval, evaluationWatches) = data + val (eval, evaluationWatches, res) = data lastEvaluator = Some((interpWatched, eval)) - (result, interpWatched ++ evaluationWatches) + (Res.Success(res.flatMap(_._2)), interpWatched ++ evaluationWatches) case _ => (result, interpWatched) } @@ -42,12 +44,25 @@ class MainRunner(config: ammonite.main.Cli.Config) } } ) + + override def handleWatchRes[T](res: Res[T], printing: Boolean) = { + res match{ + case Res.Success(value) => + if (show){ + for(json <- value.asInstanceOf[Seq[Js.Value]]){ + System.out.println(json) + } + } + + true + + case _ => super.handleWatchRes(res, printing) + } + + } override def initMain(isRepl: Boolean) = { super.initMain(isRepl).copy(scriptCodeWrapper = mill.main.MainRunner.CustomCodeWrapper) } - override def handleWatchRes[T](res: Res[T], printing: Boolean) = { - super.handleWatchRes(res, printing = false) - } } object MainRunner{ diff --git a/core/src/main/scala/mill/main/RunScript.scala b/core/src/main/scala/mill/main/RunScript.scala index ad6ad327..f58cf5c0 100644 --- a/core/src/main/scala/mill/main/RunScript.scala +++ b/core/src/main/scala/mill/main/RunScript.scala @@ -11,6 +11,7 @@ import mill.define.Task import mill.discover.{Discovered, Mirror} import mill.eval.{Evaluator, Result} import mill.util.{OSet, PrintLogger} +import upickle.Js import scala.collection.mutable @@ -26,7 +27,7 @@ object RunScript{ interp: ammonite.interp.Interpreter, scriptArgs: Seq[String], lastEvaluator: Option[(Seq[(Path, Long)], Evaluator[_])]) - : Res[(Evaluator[_], Seq[(Path, Long)])] = { + : Res[(Evaluator[_], Seq[(Path, Long)], Seq[(Any, Option[Js.Value])])] = { val log = new PrintLogger(true) for{ @@ -41,12 +42,12 @@ object RunScript{ yield new Evaluator(pwd / 'out, mapping, log) } evaluationWatches = mutable.Buffer.empty[(Path, Long)] - _ <- Res(evaluateTarget( + res <- Res(evaluateTarget( evaluator, scriptArgs, p => evaluationWatches.append((p, Interpreter.pathSignature(p))) )) - } yield (evaluator, evaluationWatches) + } yield (evaluator, evaluationWatches, res) } def watchedSigUnchanged(sig: Seq[(Path, Long)]) = { @@ -106,13 +107,16 @@ object RunScript{ case Mirror.Segment.Cross(x) => x.toList.map(_.toString) case _ => Nil } - target <- mill.main.Resolve.resolve(sel, evaluator.mapping.mirror, evaluator.mapping.base, rest, crossSelectors, Nil) - _ <- evaluate(evaluator, target, watch).toLeft(()) - } yield () + target <- mill.main.Resolve.resolve( + sel, evaluator.mapping.mirror, evaluator.mapping.base, + rest, crossSelectors, Nil + ) + res <- evaluate(evaluator, target, watch) + } yield res } def evaluate(evaluator: Evaluator[_], target: Task[Any], - watch: Path => Unit): Option[String] = { + watch: Path => Unit): Either[String, Seq[(Any, Option[upickle.Js.Value])]] = { val evaluated = evaluator.evaluate(OSet(target)) evaluated.transitive.foreach { case t: define.Source => watch(t.handle.path) @@ -133,8 +137,21 @@ object RunScript{ }).mkString("\n") evaluated.failing.keyCount match { - case 0 => None - case n => Some(s"$n targets failed\n$errorStr") + case 0 => + val json = for(t <- Seq(target)) yield { + t match { + case t: mill.define.Target[_] => + for (labelled <- evaluator.labeling.get(t)) yield { + val jsonFile = Evaluator.resolveDestPaths(evaluator.workspacePath, labelled)._2 + val metadata = upickle.json.read(jsonFile.toIO) + metadata(1) + } + case _ => None + } + } + + Right(evaluated.values.zip(json)) + case n => Left(s"$n targets failed\n$errorStr") } } -- cgit v1.2.3