Skip to content

Commit

Permalink
Get rid of mill.eval.Terminal and inline underlying tasks (com-liha…
Browse files Browse the repository at this point in the history
…oyi#4488)

Follow up from com-lihaoyi#4477; after
removing `Terminal.Labelled#segments`, it just becomes a thin wrapper
around `Task[T]`/`NamedTask[T]`. So this PR just inlines
`Task[T]`/`NamedTask[T]` everywhere that `Terminal` was previously used

At some point we may be able to narrow it further to just `Task`, but
investigating the feasibility of that can happen in a follow up
  • Loading branch information
lihaoyi authored Feb 6, 2025
1 parent ac00443 commit 1395302
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 126 deletions.
4 changes: 2 additions & 2 deletions example/fundamentals/libraries/4-mainargs/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def taskCallingCommand = Task {
// For example, here is a `customPlanCommand` command which uses this
// to traverse the module tree to find the tasks specified by the `tasks` strings,
// and plan out what would be necessary to run them
import mill.eval.{Evaluator, Terminal}
import mill.eval.Evaluator
import mill.resolve.{Resolve, SelectMode}

def customPlanCommand(evaluator: Evaluator, tasks: String*) = Task.Command {
Expand All @@ -94,7 +94,7 @@ def customPlanCommand(evaluator: Evaluator, tasks: String*) = Task.Command {
val plan = evaluator.plan(resolved)
.sortedGroups
.keys()
.map(_.render)
.map(_.toString)
.toArray

plan.foreach(println)
Expand Down
4 changes: 2 additions & 2 deletions main/eval/src/mill/eval/Evaluator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ object Evaluator {
def rawValues: Seq[Result[Val]]
def evaluated: Agg[Task[_]]
def transitive: Agg[Task[_]]
def failing: MultiBiMap[Terminal, Result.Failing[Val]]
def failing: MultiBiMap[Task[_], Result.Failing[Val]]
def results: collection.Map[Task[_], TaskResult[Val]]
def values: Seq[Val] = rawValues.collect { case Result.Success(v) => v }
}
Expand Down Expand Up @@ -111,7 +111,7 @@ object Evaluator {
case Result.Exception(Result.Failure(t, _), _) => t
case ex: Result.Exception => ex.toString
}
s"${k.render} ${fss.iterator.mkString(", ")}"
s"${k} ${fss.iterator.mkString(", ")}"
}).mkString("\n")
}

Expand Down
38 changes: 18 additions & 20 deletions main/eval/src/mill/eval/EvaluatorCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ private[mill] trait EvaluatorCore extends GroupEvaluator {
}

private def getFailing(
sortedGroups: MultiBiMap[Terminal, Task[_]],
sortedGroups: MultiBiMap[Task[_], Task[_]],
results: Map[Task[_], Evaluator.TaskResult[(Val, Int)]]
): MultiBiMap.Mutable[Terminal, Failing[Val]] = {
val failing = new MultiBiMap.Mutable[Terminal, Result.Failing[Val]]
): MultiBiMap.Mutable[Task[_], Failing[Val]] = {
val failing = new MultiBiMap.Mutable[Task[_], Result.Failing[Val]]
for ((k, vs) <- sortedGroups.items()) {
val failures = vs.items.flatMap(results.get).collect {
case Evaluator.TaskResult(f: Result.Failing[(Val, Int)], _) => f.map(_._1)
Expand Down Expand Up @@ -86,13 +86,13 @@ private[mill] trait EvaluatorCore extends GroupEvaluator {
val (classToTransitiveClasses, allTransitiveClassMethods) =
CodeSigUtils.precomputeMethodNamesPerClass(Plan.transitiveNamed(goals))

val uncached = new ConcurrentHashMap[Terminal, Unit]()
val changedValueHash = new ConcurrentHashMap[Terminal, Unit]()
val uncached = new ConcurrentHashMap[Task[_], Unit]()
val changedValueHash = new ConcurrentHashMap[Task[_], Unit]()

val futures = mutable.Map.empty[Terminal, Future[Option[GroupEvaluator.Results]]]
val futures = mutable.Map.empty[Task[_], Future[Option[GroupEvaluator.Results]]]

def evaluateTerminals(
terminals: Seq[Terminal],
terminals: Seq[Task[_]],
forkExecutionContext: mill.api.Ctx.Fork.Impl,
exclusive: Boolean
) = {
Expand All @@ -107,12 +107,12 @@ private[mill] trait EvaluatorCore extends GroupEvaluator {
val deps = interGroupDeps(terminal)

val group = plan.sortedGroups.lookupKey(terminal)
val exclusiveDeps = deps.filter(d => d.task.isExclusiveCommand)
val exclusiveDeps = deps.filter(d => d.isExclusiveCommand)

if (!terminal.task.isExclusiveCommand && exclusiveDeps.nonEmpty) {
if (!terminal.isExclusiveCommand && exclusiveDeps.nonEmpty) {
val failure = Result.Failure(
s"Non-exclusive task ${terminal.render} cannot depend on exclusive task " +
exclusiveDeps.map(_.render).mkString(", ")
s"Non-exclusive task ${terminal} cannot depend on exclusive task " +
exclusiveDeps.mkString(", ")
)
val taskResults = group
.map(t => (t, TaskResult[(Val, Int)](failure, () => failure)))
Expand Down Expand Up @@ -148,9 +148,7 @@ private[mill] trait EvaluatorCore extends GroupEvaluator {
} yield upstreamResults(item).map(_._1)
val logRun = inputResults.forall(_.result.isInstanceOf[Result.Success[_]])

val tickerPrefix = terminal.render.collect {
case targetLabel if logRun && logger.enableTicker => targetLabel
}
val tickerPrefix = if (logRun && logger.enableTicker) terminal.toString else ""

val contextLogger = new PrefixLogger(
logger0 = logger,
Expand Down Expand Up @@ -205,13 +203,13 @@ private[mill] trait EvaluatorCore extends GroupEvaluator {
}

val tasks0 = terminals0.filter {
case Terminal.Labelled(c: Command[_]) => false
case c: Command[_] => false
case _ => true
}

val tasksTransitive = Plan.transitiveTargets(Agg.from(tasks0.map(_.task))).toSet
val tasksTransitive = Plan.transitiveTargets(Agg.from(tasks0)).toSet
val (tasks, leafExclusiveCommands) = terminals0.partition {
case Terminal.Labelled(t) => tasksTransitive.contains(t) || !t.isExclusiveCommand
case t: NamedTask[_] => tasksTransitive.contains(t) || !t.isExclusiveCommand
case _ => !serialCommandExec
}

Expand Down Expand Up @@ -261,8 +259,8 @@ private[mill] trait EvaluatorCore extends GroupEvaluator {
}

private[mill] object EvaluatorCore {
def findInterGroupDeps(sortedGroups: MultiBiMap[Terminal, Task[_]])
: Map[Terminal, Seq[Terminal]] = {
def findInterGroupDeps(sortedGroups: MultiBiMap[Task[_], Task[_]])
: Map[Task[_], Seq[Task[_]]] = {
sortedGroups
.items()
.map { case (terminal, group) =>
Expand All @@ -279,7 +277,7 @@ private[mill] object EvaluatorCore {
rawValues: Seq[Result[Val]],
evaluated: Agg[Task[_]],
transitive: Agg[Task[_]],
failing: MultiBiMap[Terminal, Result.Failing[Val]],
failing: MultiBiMap[Task[_], Result.Failing[Val]],
results: Map[Task[_], TaskResult[Val]]
) extends Evaluator.Results
}
21 changes: 11 additions & 10 deletions main/eval/src/mill/eval/EvaluatorLogs.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package mill.eval

import mill.define.InputImpl
import mill.define.{InputImpl, Task}
import mill.main.client.OutFiles
import mill.util.SpanningForest

import java.util.concurrent.ConcurrentHashMap
import scala.jdk.CollectionConverters.EnumerationHasAsScala

private[mill] object EvaluatorLogs {
def logDependencyTree(
interGroupDeps: Map[Terminal, Seq[Terminal]],
indexToTerminal: Array[Terminal],
interGroupDeps: Map[Task[_], Seq[Task[_]]],
indexToTerminal: Array[Task[_]],
outPath: os.Path
): Unit = {
val (vertexToIndex, edgeIndices) =
Expand All @@ -19,15 +20,15 @@ private[mill] object EvaluatorLogs {
outPath / OutFiles.millDependencyTree,
edgeIndices,
indexToTerminal.indices.toSet,
indexToTerminal(_).render
indexToTerminal(_).toString
)
}
def logInvalidationTree(
interGroupDeps: Map[Terminal, Seq[Terminal]],
indexToTerminal: Array[Terminal],
interGroupDeps: Map[Task[_], Seq[Task[_]]],
indexToTerminal: Array[Task[_]],
outPath: os.Path,
uncached: ConcurrentHashMap[Terminal, Unit],
changedValueHash: ConcurrentHashMap[Terminal, Unit]
uncached: ConcurrentHashMap[Task[_], Unit],
changedValueHash: ConcurrentHashMap[Task[_], Unit]
): Unit = {
val reverseInterGroupDeps = SpanningForest.reverseEdges(interGroupDeps)

Expand All @@ -54,13 +55,13 @@ private[mill] object EvaluatorLogs {
// from the invalidation tree, because most of them are un-interesting and the
// user really only cares about (a) inputs that cause downstream tasks to invalidate
// or (b) non-input tasks that were invalidated alone (e.g. due to a codesig change)
!uncachedTask.task.isInstanceOf[InputImpl[_]] || edgeSourceIndices(uncachedIndex)
!uncachedTask.isInstanceOf[InputImpl[_]] || edgeSourceIndices(uncachedIndex)
) {
uncachedIndex
}
}
.toSet,
indexToTerminal(_).render
indexToTerminal(_).toString
)
}
}
Loading

0 comments on commit 1395302

Please sign in to comment.