Skip to content

Commit

Permalink
Selective execution fixes (#4106)
Browse files Browse the repository at this point in the history
Not enough to turn on selective execution in Mill's CI yet, but it's
steps in that direction.

* Make `BuildInfo#resources` a cached task, which is more correct (since
it doesn't add any source files) and seems to remove some noise in
changed `inputTaskHashes`
* Fix handling of `defaultCommandName` in `selective.resolve` and add a
unit test
* Nicely format `mill-selective-execution.json` for easy debugging
* Bump mill-vcs-version to pull in
lefou/mill-vcs-version#165, so we can stabilize
`build.millVersion`
  • Loading branch information
lihaoyi authored Dec 12, 2024
1 parent 28b61e8 commit e46008d
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .config/mill-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.12.3-41-d21946
0.12.3-51-24ba0d
4 changes: 2 additions & 2 deletions contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ trait BuildInfo extends JavaModule {
def buildInfoMembers: T[Seq[BuildInfo.Value]] = Seq.empty[BuildInfo.Value]

def resources: T[Seq[PathRef]] =
if (buildInfoStaticCompiled) super.resources
else Task.Sources { super.resources() ++ Seq(buildInfoResources()) }
if (buildInfoStaticCompiled) Task { super.resources() }
else Task { super.resources() ++ Seq(buildInfoResources()) }

def buildInfoResources = Task {
val p = new java.util.Properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ object foo extends Module {
fooHelper(fooTask().path)
}
}
object bar extends Module {

object bar extends mill.define.TaskModule {
def barTask = Task.Source(millSourcePath / "bar.txt")

def barHelper(p: os.Path) = {
Expand All @@ -23,4 +24,6 @@ object bar extends Module {
System.out.println("Computing barCommand")
barHelper(barTask().path)
}

def defaultCommandName(): String = "barCommand"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ object SelectiveExecutionTests extends UtestIntegrationTestSuite {
eval(("selective.prepare", "{foo.fooCommand,bar.barCommand}"), check = true)
modifyFile(workspacePath / "bar/bar.txt", _ + "!")

val plan = eval(("selective.resolve", "{foo.fooCommand,bar.barCommand}"), check = true)
assert(plan.out == "bar.barCommand")
val resolve = eval(("selective.resolve", "{foo.fooCommand,bar.barCommand}"), check = true)
assert(resolve.out == "bar.barCommand")

val cached =
eval(
Expand All @@ -30,6 +30,23 @@ object SelectiveExecutionTests extends UtestIntegrationTestSuite {
assert(!cached.out.contains("Computing fooCommand"))
assert(cached.out.contains("Computing barCommand"))
}
test("default-command") - integrationTest { tester =>
import tester._

eval(("selective.prepare", "bar"), check = true)

val resolve = eval(("selective.resolve", "bar"), check = true)
assert(resolve.out == "")

modifyFile(workspacePath / "bar/bar.txt", _ + "!")
val resolve2 = eval(("selective.resolve", "bar"), check = true)
assert(resolve2.out != "")

val cached = eval(("selective.run", "bar"), check = true, stderr = os.Inherit)

assert(!cached.out.contains("Computing fooCommand"))
assert(cached.out.contains("Computing barCommand"))
}
test("changed-code") - integrationTest { tester =>
import tester._

Expand Down
5 changes: 3 additions & 2 deletions main/src/mill/main/SelectiveExecution.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ private[mill] object SelectiveExecution {
computeHashCodeSignatures(terminals, newHashes.methodCodeHashSignatures)
)

val changedRootTasks = (changedInputNames ++ changedCodeNames).map(namesToTasks(_): Task[_])
val changedRootTasks = (changedInputNames ++ changedCodeNames)
.flatMap(namesToTasks.get(_): Option[Task[_]])

val allNodes = breadthFirst(terminals.map(_.task: Task[_]))(_.inputs)
val downstreamEdgeMap = allNodes
Expand Down Expand Up @@ -133,7 +134,7 @@ private[mill] object SelectiveExecution {
def saveMetadata(evaluator: Evaluator, metadata: SelectiveExecution.Metadata): Unit = {
os.write.over(
evaluator.outPath / OutFiles.millSelectiveExecution,
upickle.default.write(metadata)
upickle.default.write(metadata, indent = 2)
)
}

Expand Down
4 changes: 2 additions & 2 deletions main/src/mill/main/SelectiveExecutionModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ trait SelectiveExecutionModule extends mill.define.Module {
def resolve(evaluator: Evaluator, tasks: String*): Command[Array[String]] =
Task.Command(exclusive = true) {
val result = for {
resolved <- Resolve.Segments.resolve(evaluator.rootModule, tasks, SelectMode.Multi)
resolved <- Resolve.Tasks.resolve(evaluator.rootModule, tasks, SelectMode.Multi)
diffed <- SelectiveExecution.diffMetadata(evaluator, tasks)
} yield resolved.map(_.render).toSet.intersect(diffed).toArray.sorted
} yield resolved.map(_.ctx.segments.render).toSet.intersect(diffed).toArray.sorted

result match {
case Left(err) => Result.Failure(err)
Expand Down
2 changes: 1 addition & 1 deletion mill-build/build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mill.scalalib._

object `package` extends MillBuildRootModule {
override def ivyDeps = Agg(
ivy"de.tototec::de.tobiasroeser.mill.vcs.version::0.4.0",
ivy"de.tototec::de.tobiasroeser.mill.vcs.version::0.4.1",
ivy"com.github.lolgab::mill-mima::0.1.1",
ivy"net.sourceforge.htmlcleaner:htmlcleaner:2.29",
// TODO: implement empty version for ivy deps as we do in import parser
Expand Down

0 comments on commit e46008d

Please sign in to comment.