From e5eb6487ad781654a2221168692c85f8b877edfd Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 28 Aug 2024 14:00:33 +0200 Subject: [PATCH] Make serial command execution at the evaluation end optional (#3429) Introduced a new `serialCommandExec` parameter in `Evaluator.evaluate` and added required binary compatibility shims. Fix https://github.com/com-lihaoyi/mill/issues/3359 Pull request: https://github.com/com-lihaoyi/mill/pull/3429 --- main/eval/src/mill/eval/Evaluator.scala | 23 +++++++++++++++++++-- main/eval/src/mill/eval/EvaluatorCore.scala | 10 +++++---- main/eval/src/mill/eval/EvaluatorImpl.scala | 15 +++++++++++++- main/src/mill/main/RunScript.scala | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/main/eval/src/mill/eval/Evaluator.scala b/main/eval/src/mill/eval/Evaluator.scala index 0ff9e0814a6..5a70a0414d0 100644 --- a/main/eval/src/mill/eval/Evaluator.scala +++ b/main/eval/src/mill/eval/Evaluator.scala @@ -6,6 +6,7 @@ import mill.define.{BaseModule, BaseModuleTree, Segments, Task} import mill.eval.Evaluator.{Results, formatFailing} import mill.util.{ColorLogger, MultiBiMap} +import scala.annotation.nowarn import scala.jdk.CollectionConverters._ import scala.reflect.ClassTag import scala.util.DynamicVariable @@ -24,12 +25,30 @@ trait Evaluator { def pathsResolver: EvaluatorPathsResolver def workerCache: collection.Map[Segments, (Int, Val)] def disableCallgraphInvalidation: Boolean = false + + @deprecated( + "Binary compatibility shim. Use overload with parameter serialCommandExec=false instead", + "Mill 0.12.0-RC1" + ) + def evaluate( + goals: Agg[Task[_]], + reporter: Int => Option[CompileProblemReporter], + testReporter: TestReporter, + logger: ColorLogger + ): Evaluator.Results = evaluate(goals, reporter, testReporter, logger, serialCommandExec = false) + def evaluate( goals: Agg[Task[_]], reporter: Int => Option[CompileProblemReporter] = _ => Option.empty[CompileProblemReporter], testReporter: TestReporter = DummyTestReporter, - logger: ColorLogger = baseLogger - ): Evaluator.Results + logger: ColorLogger = baseLogger, + serialCommandExec: Boolean = false + ): Evaluator.Results = { + // TODO: cleanup once we break bin-compat in Mill 0.13 + // this method should be abstract, but to preserve bin-compat, we default-implement + // by delegating to an binary pre-existing overload, by ignoring the new parameters + evaluate(goals, reporter, testReporter, logger): @nowarn("cat=deprecation") + } def withBaseLogger(newBaseLogger: ColorLogger): Evaluator def withFailFast(newFailFast: Boolean): Evaluator diff --git a/main/eval/src/mill/eval/EvaluatorCore.scala b/main/eval/src/mill/eval/EvaluatorCore.scala index 34d5927eaa9..8a85cf7bbac 100644 --- a/main/eval/src/mill/eval/EvaluatorCore.scala +++ b/main/eval/src/mill/eval/EvaluatorCore.scala @@ -29,7 +29,8 @@ private[mill] trait EvaluatorCore extends GroupEvaluator { goals: Agg[Task[_]], reporter: Int => Option[CompileProblemReporter] = _ => Option.empty[CompileProblemReporter], testReporter: TestReporter = DummyTestReporter, - logger: ColorLogger = baseLogger + logger: ColorLogger = baseLogger, + serialCommandExec: Boolean = false ): Evaluator.Results = { os.makeDir.all(outPath) @@ -42,7 +43,7 @@ private[mill] trait EvaluatorCore extends GroupEvaluator { if (effectiveThreadCount == 1) "" else s"[#${if (effectiveThreadCount > 9) f"$threadId%02d" else threadId}] " - try evaluate0(goals, logger, reporter, testReporter, ec, contextLoggerMsg) + try evaluate0(goals, logger, reporter, testReporter, ec, contextLoggerMsg, serialCommandExec) finally ec.close() } } @@ -68,7 +69,8 @@ private[mill] trait EvaluatorCore extends GroupEvaluator { reporter: Int => Option[CompileProblemReporter] = _ => Option.empty[CompileProblemReporter], testReporter: TestReporter = DummyTestReporter, ec: ExecutionContext with AutoCloseable, - contextLoggerMsg0: Int => String + contextLoggerMsg0: Int => String, + serialCommandExec: Boolean ): Evaluator.Results = { os.makeDir.all(outPath) val chromeProfileLogger = new ChromeProfileLogger(outPath / millChromeProfile) @@ -170,7 +172,7 @@ private[mill] trait EvaluatorCore extends GroupEvaluator { val tasksTransitive = tasksTransitive0.toSet val (tasks, leafCommands) = terminals0.partition { case Terminal.Labelled(t, _) if tasksTransitive.contains(t) => true - case _ => false + case _ => !serialCommandExec } // Run all non-command tasks according to the threads diff --git a/main/eval/src/mill/eval/EvaluatorImpl.scala b/main/eval/src/mill/eval/EvaluatorImpl.scala index 56ca20c862a..a3877bdaaf0 100644 --- a/main/eval/src/mill/eval/EvaluatorImpl.scala +++ b/main/eval/src/mill/eval/EvaluatorImpl.scala @@ -1,9 +1,10 @@ package mill.eval -import mill.api.Val +import mill.api.{CompileProblemReporter, Strict, TestReporter, Val} import mill.api.Strict.Agg import mill.define._ import mill.util._ + import scala.collection.mutable import scala.reflect.ClassTag @@ -43,6 +44,18 @@ private[mill] case class EvaluatorImpl( Plan.plan(goals) } + override def evaluate( + goals: Strict.Agg[Task[_]], + reporter: Int => Option[CompileProblemReporter], + testReporter: TestReporter, + logger: ColorLogger, + serialCommandExec: Boolean + ): Evaluator.Results = { + // TODO: cleanup once we break bin-compat in Mill 0.13 + // disambiguate override hierarchy + super.evaluate(goals, reporter, testReporter, logger, serialCommandExec) + } + override def evalOrThrow(exceptionFactory: Evaluator.Results => Throwable) : Evaluator.EvalOrThrow = new EvalOrThrow(this, exceptionFactory) diff --git a/main/src/mill/main/RunScript.scala b/main/src/mill/main/RunScript.scala index aa377e3386e..6b30e460fdb 100644 --- a/main/src/mill/main/RunScript.scala +++ b/main/src/mill/main/RunScript.scala @@ -35,7 +35,7 @@ object RunScript { evaluator: Evaluator, targets: Agg[Task[Any]] ): (Seq[Watchable], Either[String, Seq[(Any, Option[(TaskName, ujson.Value)])]]) = { - val evaluated: Results = evaluator.evaluate(targets) + val evaluated: Results = evaluator.evaluate(targets, serialCommandExec = true) val watched = evaluated.results .iterator