Skip to content

Commit

Permalink
Make serial command execution at the evaluation end optional (#3429)
Browse files Browse the repository at this point in the history
Introduced a new `serialCommandExec` parameter in `Evaluator.evaluate`
and added required binary compatibility shims.

Fix #3359

Pull request: #3429
  • Loading branch information
lefou authored Aug 28, 2024
1 parent 12194ac commit e5eb648
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
23 changes: 21 additions & 2 deletions main/eval/src/mill/eval/Evaluator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 6 additions & 4 deletions main/eval/src/mill/eval/EvaluatorCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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()
}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
15 changes: 14 additions & 1 deletion main/eval/src/mill/eval/EvaluatorImpl.scala
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion main/src/mill/main/RunScript.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e5eb648

Please sign in to comment.