summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-03-04 17:34:13 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-03-04 17:56:48 -0800
commite0e537b937fc411188af2ae7ab417b6f4a9dabbe (patch)
tree703c840477359f296fc7329b16fda39bd183b21b
parentc3e5d9313763cf31149b0a810a772790ac5bd9e2 (diff)
downloadmill-e0e537b937fc411188af2ae7ab417b6f4a9dabbe.tar.gz
mill-e0e537b937fc411188af2ae7ab417b6f4a9dabbe.tar.bz2
mill-e0e537b937fc411188af2ae7ab417b6f4a9dabbe.zip
Introduced the `mill plan foo.bar` command, which shows you what the execution plan of running the `foo.bar` task looks like without actually evaluating it.
-rw-r--r--core/src/mill/eval/Evaluator.scala82
-rw-r--r--main/src/mill/main/MainModule.scala16
-rw-r--r--readme.md5
3 files changed, 64 insertions, 39 deletions
diff --git a/core/src/mill/eval/Evaluator.scala b/core/src/mill/eval/Evaluator.scala
index 4bc11338..7ae68751 100644
--- a/core/src/mill/eval/Evaluator.scala
+++ b/core/src/mill/eval/Evaluator.scala
@@ -36,45 +36,7 @@ case class Evaluator[T](outPath: Path,
def evaluate(goals: Agg[Task[_]]): Evaluator.Results = {
mkdir(outPath)
- val transitive = Graph.transitiveTargets(goals)
- val topoSorted = Graph.topoSorted(transitive)
- val sortedGroups = Graph.groupAroundImportantTargets(topoSorted){
- case t: NamedTask[Any] =>
- val segments = t.ctx.segments
- val finalTaskOverrides = t match{
- case t: Target[_] =>
- rootModule.millInternal.segmentsToTargets.get(segments).fold(0)(_.ctx.overrides)
-
- case c: mill.define.Command[_] =>
- def findMatching(cls: Class[_]): Option[Seq[(Int, EntryPoint[_])]] = {
- rootModule.millDiscover.value.get(cls) match{
- case Some(v) => Some(v)
- case None =>
- cls.getSuperclass match{
- case null => None
- case superCls => findMatching(superCls)
- }
- }
- }
-
- findMatching(c.cls) match{
- case Some(v) =>
- v.find(_._2.name == c.ctx.segment.pathSegments.head).get._1
- // For now we don't properly support overrides for external modules
- // that do not appear in the Evaluator's main Discovered listing
- case None => 0
- }
-
- case c: mill.define.Worker[_] => 0
- }
-
- val additional =
- if (finalTaskOverrides == t.ctx.overrides) Nil
- else Seq(Segment.Label("overriden")) ++ t.ctx.enclosing.split("\\.|#| ").map(Segment.Label)
-
- Right(Labelled(t, segments ++ additional))
- case t if goals.contains(t) => Left(t)
- }
+ val (sortedGroups, transitive) = Evaluator.plan(rootModule, goals)
val evaluated = new Agg.Mutable[Task[_]]
val results = mutable.LinkedHashMap.empty[Task[_], Result[(Any, Int)]]
@@ -379,4 +341,46 @@ object Evaluator{
results: collection.Map[Task[_], Result[Any]]){
def values = rawValues.collect{case Result.Success(v) => v}
}
+ def plan(rootModule: BaseModule, goals: Agg[Task[_]]) = {
+ val transitive = Graph.transitiveTargets(goals)
+ val topoSorted = Graph.topoSorted(transitive)
+ val sortedGroups = Graph.groupAroundImportantTargets(topoSorted){
+ case t: NamedTask[Any] =>
+ val segments = t.ctx.segments
+ val finalTaskOverrides = t match{
+ case t: Target[_] =>
+ rootModule.millInternal.segmentsToTargets.get(segments).fold(0)(_.ctx.overrides)
+
+ case c: mill.define.Command[_] =>
+ def findMatching(cls: Class[_]): Option[Seq[(Int, EntryPoint[_])]] = {
+ rootModule.millDiscover.value.get(cls) match{
+ case Some(v) => Some(v)
+ case None =>
+ cls.getSuperclass match{
+ case null => None
+ case superCls => findMatching(superCls)
+ }
+ }
+ }
+
+ findMatching(c.cls) match{
+ case Some(v) =>
+ v.find(_._2.name == c.ctx.segment.pathSegments.head).get._1
+ // For now we don't properly support overrides for external modules
+ // that do not appear in the Evaluator's main Discovered listing
+ case None => 0
+ }
+
+ case c: mill.define.Worker[_] => 0
+ }
+
+ val additional =
+ if (finalTaskOverrides == t.ctx.overrides) Nil
+ else Seq(Segment.Label("overriden")) ++ t.ctx.enclosing.split("\\.|#| ").map(Segment.Label)
+
+ Right(Labelled(t, segments ++ additional))
+ case t if goals.contains(t) => Left(t)
+ }
+ (sortedGroups, transitive)
+ }
}
diff --git a/main/src/mill/main/MainModule.scala b/main/src/mill/main/MainModule.scala
index feafd35d..33eddbe4 100644
--- a/main/src/mill/main/MainModule.scala
+++ b/main/src/mill/main/MainModule.scala
@@ -46,6 +46,22 @@ trait MainModule extends mill.Module{
}
}
+ def plan(evaluator: Evaluator[Any], targets: String*) = mill.T.command{
+ val resolved = RunScript.resolveTasks(
+ mill.main.ResolveTasks, evaluator, targets, multiSelect = true
+ )
+
+ resolved match{
+ case Left(err) => Result.Failure(err)
+ case Right(rs) =>
+ val (sortedGroups, transitive) = Evaluator.plan(evaluator.rootModule, rs)
+ for(Right(r) <- sortedGroups.keys()){
+ println(r.segments.render)
+ }
+ Result.Success(())
+ }
+ }
+
def describe(evaluator: Evaluator[Any], targets: String*) = mill.T.command{
MainModule.resolveTasks(evaluator, targets, multiSelect = true){ tasks =>
for{
diff --git a/readme.md b/readme.md
index c67170dc..c535b00c 100644
--- a/readme.md
+++ b/readme.md
@@ -330,6 +330,11 @@ rm -rf out/
## Changelog
+### master
+
+- Introduced the `mill plan foo.bar` command, which shows you what the execution
+ plan of running the `foo.bar` task looks like without actually evaluating it.
+
### 0.1.4
- Speed up Mill client initialization by another 50-100ms