summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.sbt5
-rwxr-xr-xbuild.sc5
-rw-r--r--core/src/main/scala/mill/define/Task.scala60
-rw-r--r--core/src/main/scala/mill/discover/Discovered.scala9
-rw-r--r--core/src/main/scala/mill/eval/Evaluator.scala31
-rw-r--r--core/src/test/scala/mill/discover/DiscoveredTests.scala5
-rw-r--r--core/src/test/scala/mill/eval/EvaluationTests.scala7
-rw-r--r--core/src/test/scala/mill/util/TestGraphs.scala8
-rw-r--r--core/src/test/scala/mill/util/TestUtil.scala5
9 files changed, 94 insertions, 41 deletions
diff --git a/build.sbt b/build.sbt
index 716559bd..ab6e8384 100644
--- a/build.sbt
+++ b/build.sbt
@@ -30,8 +30,9 @@ val pluginSettings = Seq(
)
lazy val ammoniteRunner = project.settings(
+ scalaVersion := "2.12.4",
libraryDependencies +=
- "com.lihaoyi" % "ammonite" % "1.0.3" cross CrossVersion.full
+ "com.lihaoyi" % "ammonite" % "1.0.3-21-05b5d32" cross CrossVersion.full
)
@@ -89,7 +90,7 @@ lazy val core = project
"org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided",
"com.lihaoyi" %% "sourcecode" % "0.1.4",
"com.lihaoyi" %% "pprint" % "0.5.3",
- "com.lihaoyi" % "ammonite" % "1.0.3-20-75e58ac" cross CrossVersion.full,
+ "com.lihaoyi" % "ammonite" % "1.0.3-21-05b5d32" cross CrossVersion.full,
"org.scala-sbt" %% "zinc" % "1.0.5",
"org.scala-sbt" % "test-interface" % "1.0"
),
diff --git a/build.sc b/build.sc
index a9e63b43..4bfb8745 100755
--- a/build.sc
+++ b/build.sc
@@ -65,7 +65,7 @@ object Core extends MillModule {
def ivyDeps = Seq(
Dep("com.lihaoyi", "sourcecode", "0.1.4"),
Dep("com.lihaoyi", "pprint", "0.5.3"),
- Dep.Point("com.lihaoyi", "ammonite", "1.0.3-20-75e58ac"),
+ Dep.Point("com.lihaoyi", "ammonite", "1.0.3-21-05b5d32"),
Dep("com.typesafe.play", "play-json", "2.6.6"),
Dep("org.scala-sbt", "zinc", "1.0.5"),
Dep.Java("org.scala-sbt", "test-interface", "1.0")
@@ -80,7 +80,8 @@ object Core extends MillModule {
}
def allSources = super.allSources() ++ Seq(generatedSources())
- val test = new Tests{
+ val test = new Tests
+ class Tests extends super.Tests{
def generatedSources = T{
mkdir(T.ctx().dest)
shared.generateTests(T.ctx().dest)
diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala
index bb877d08..4ccb93b6 100644
--- a/core/src/main/scala/mill/define/Task.scala
+++ b/core/src/main/scala/mill/define/Task.scala
@@ -1,9 +1,11 @@
package mill.define
+import ammonite.main.Router.Overrides
import mill.define.Applicative.Applyable
import mill.eval.{PathRef, Result}
import mill.util.Ctx
-import upickle.default.{Reader => R, Writer => W, ReadWriter => RW}
+import upickle.default.{ReadWriter => RW, Reader => R, Writer => W}
+
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
@@ -35,6 +37,7 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[Task, T]{
trait NamedTask[+T] extends Task[T]{
def owner: Task.Module
def name: String
+ def overrides: Int
}
trait Target[+T] extends NamedTask[T]{
override def asTarget = Some(this)
@@ -49,7 +52,8 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: W[T],
e: sourcecode.Enclosing,
n: sourcecode.Name,
- cl: Caller[mill.define.Task.Module]): Target[T] = macro targetImpl[T]
+ cl: Caller[mill.define.Task.Module],
+ o: Overrides): Target[T] = macro targetImpl[T]
def targetImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[T])
@@ -57,11 +61,12 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: c.Expr[W[T]],
e: c.Expr[sourcecode.Enclosing],
n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[mill.define.Task.Module]]): c.Expr[Target[T]] = {
+ cl: c.Expr[Caller[mill.define.Task.Module]],
+ o: c.Expr[Overrides]): c.Expr[Target[T]] = {
import c.universe._
c.Expr[Target[T]](
mill.plugin.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Ctx](c)(q"mill.eval.Result.Success($t)").tree}, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read))"
+ q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Ctx](c)(q"mill.eval.Result.Success($t)").tree}, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read), $o.value)"
)
)
}
@@ -71,7 +76,8 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: W[T],
e: sourcecode.Enclosing,
n: sourcecode.Name,
- cl: Caller[mill.define.Task.Module]): Target[T] = macro targetResultImpl[T]
+ cl: Caller[mill.define.Task.Module],
+ o: Overrides): Target[T] = macro targetResultImpl[T]
def targetResultImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[Result[T]])
@@ -79,11 +85,12 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: c.Expr[W[T]],
e: c.Expr[sourcecode.Enclosing],
n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[mill.define.Task.Module]]): c.Expr[Target[T]] = {
+ cl: c.Expr[Caller[mill.define.Task.Module]],
+ o: c.Expr[Overrides]): c.Expr[Target[T]] = {
import c.universe._
c.Expr[Target[T]](
mill.plugin.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Ctx](c)(t.tree).tree}, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read))"
+ q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Ctx](c)(t.tree).tree}, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read), $o.value)"
)
)
}
@@ -93,7 +100,8 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: W[T],
e: sourcecode.Enclosing,
n: sourcecode.Name,
- cl: Caller[mill.define.Task.Module]): Target[T] = macro targetTaskImpl[T]
+ cl: Caller[mill.define.Task.Module],
+ o: Overrides): Target[T] = macro targetTaskImpl[T]
def targetTaskImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[Task[T]])
@@ -101,11 +109,12 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: c.Expr[W[T]],
e: c.Expr[sourcecode.Enclosing],
n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[mill.define.Task.Module]]): c.Expr[Target[T]] = {
+ cl: c.Expr[Caller[mill.define.Task.Module]],
+ o: c.Expr[Overrides]): c.Expr[Target[T]] = {
import c.universe._
c.Expr[Target[T]](
mill.plugin.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[TargetImpl[T]]}($t, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read))"
+ q"new ${weakTypeOf[TargetImpl[T]]}($t, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read), $o.value)"
)
)
}
@@ -113,24 +122,27 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
def command[T](t: Result[T])
(implicit w: W[T],
n: sourcecode.Name,
- cl: Caller[mill.define.Task.Module]): Command[T] = macro commandImpl[T]
+ cl: Caller[mill.define.Task.Module],
+ o: Overrides): Command[T] = macro commandImpl[T]
def source(path: ammonite.ops.Path) = new Source(path)
def command[T](t: Task[T])
(implicit c: Caller[Task.Module],
n: sourcecode.Name,
- w: W[T]): Command[T] = new Command(t, c.value, n.value, w)
+ w: W[T],
+ o: Overrides): Command[T] = new Command(t, c.value, n.value, w, o.value)
def commandImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[T])
(w: c.Expr[W[T]],
n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[mill.define.Task.Module]]): c.Expr[Command[T]] = {
+ cl: c.Expr[Caller[mill.define.Task.Module]],
+ o: c.Expr[Overrides]): c.Expr[Command[T]] = {
import c.universe._
c.Expr[Command[T]](
- q"new ${weakTypeOf[Command[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree}, $cl.value, $n.value, $w)"
+ q"new ${weakTypeOf[Command[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree}, $cl.value, $n.value, $w, $o.value)"
)
}
@@ -140,7 +152,8 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: W[T],
e: sourcecode.Enclosing,
n: sourcecode.Name,
- cl: Caller[mill.define.Task.Module]): Target[T] = macro persistentImpl[T]
+ cl: Caller[mill.define.Task.Module],
+ o: Overrides): Target[T] = macro persistentImpl[T]
def persistentImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[T])
@@ -148,12 +161,13 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
w: c.Expr[W[T]],
e: c.Expr[sourcecode.Enclosing],
n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[mill.define.Task.Module]]): c.Expr[Persistent[T]] = {
+ cl: c.Expr[Caller[mill.define.Task.Module]],
+ o: c.Expr[Overrides]): c.Expr[Persistent[T]] = {
import c.universe._
c.Expr[Persistent[T]](
mill.plugin.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[Persistent[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree}, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read))"
+ q"new ${weakTypeOf[Persistent[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree}, $e.value, $cl.value, $n.value, upickle.default.ReadWriter($w.write, $r.read), $o.value)"
)
)
}
@@ -170,6 +184,7 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
def zip[A](a: Task[A]) = a.map(Tuple1(_))
def zip[A, B](a: Task[A], b: Task[B]) = a.zip(b)
}
+
case class Caller[A](value: A)
object Caller {
def apply[T]()(implicit c: Caller[T]) = c.value
@@ -184,7 +199,8 @@ class TargetImpl[+T](t: Task[T],
val enclosing: String,
val owner: Task.Module,
val name: String,
- val readWrite: RW[_]) extends Target[T] {
+ val readWrite: RW[_],
+ val overrides: Int) extends Target[T] {
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
override def toString = enclosing + "@" + Integer.toHexString(System.identityHashCode(this))
@@ -192,7 +208,8 @@ class TargetImpl[+T](t: Task[T],
class Command[+T](t: Task[T],
val owner: Task.Module,
val name: String,
- val writer: W[_]) extends NamedTask[T] {
+ val writer: W[_],
+ val overrides: Int) extends NamedTask[T] {
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
override def asCommand = Some(this)
@@ -201,8 +218,9 @@ class Persistent[+T](t: Task[T],
enclosing: String,
owner: Task.Module,
name: String,
- readWrite: RW[_])
- extends TargetImpl[T](t, enclosing, owner, name, readWrite) {
+ readWrite: RW[_],
+ overrides: Int)
+ extends TargetImpl[T](t, enclosing, owner, name, readWrite, overrides) {
override def flushDest = false
override def asPersistent = Some(this)
}
diff --git a/core/src/main/scala/mill/discover/Discovered.scala b/core/src/main/scala/mill/discover/Discovered.scala
index 6e819d75..cef0d193 100644
--- a/core/src/main/scala/mill/discover/Discovered.scala
+++ b/core/src/main/scala/mill/discover/Discovered.scala
@@ -3,6 +3,7 @@ package mill.discover
import mill.define.Task.Module
import mill.define.{Cross, Target, Task}
import ammonite.main.Router
+import ammonite.main.Router.EntryPoint
import mill.discover.Mirror.{Segment, TargetPoint}
import mill.util.Ctx.Loader
@@ -30,18 +31,24 @@ object Discovered {
)
Seq(resolvedNode -> segmentsRev.reverse)
}.toMap
+
val targets = Mirror.traverse(base, mirror){ (mirror, segmentsRev) =>
val resolvedNode = mirror.node(
base,
segmentsRev.reverse.map{case Mirror.Segment.Cross(vs) => vs.toList case _ => Nil}.toList
)
for(target <- mirror.targets) yield {
-
target.asInstanceOf[TargetPoint[Any, Any]].run(resolvedNode) -> (segmentsRev.reverse :+ Segment.Label(target.label))
}
}.toMap
+ val segmentsToCommands = Mirror.traverse[T, T, (Seq[Segment], EntryPoint[_])](base, mirror){ (mirror, segmentsRev) =>
+ for(command <- mirror.commands)
+ yield (segmentsRev.reverse :+ Segment.Label(command.name)) -> command
+ }.toMap
+
+ val segmentsToTargets = targets.map(_.swap)
}
def consistencyCheck[T](mapping: Discovered.Mapping[T]) = {
diff --git a/core/src/main/scala/mill/eval/Evaluator.scala b/core/src/main/scala/mill/eval/Evaluator.scala
index 110747a1..ed8145b2 100644
--- a/core/src/main/scala/mill/eval/Evaluator.scala
+++ b/core/src/main/scala/mill/eval/Evaluator.scala
@@ -11,9 +11,13 @@ import mill.util
import mill.util._
import scala.collection.mutable
-case class Labelled[T](target: Task[T],
- format: Option[upickle.default.ReadWriter[T]],
- segments: Seq[Segment])
+case class Labelled[T](target: NamedTask[T],
+ segments: Seq[Segment]){
+ def format = target match{
+ case t: Target[Any] => Some(t.readWrite.asInstanceOf[upickle.default.ReadWriter[Any]])
+ case _ => None
+ }
+}
class Evaluator[T](val workspacePath: Path,
val mapping: Discovered.Mapping[T],
log: Logger,
@@ -29,15 +33,18 @@ class Evaluator[T](val workspacePath: Path,
val transitive = Graph.transitiveTargets(goals)
val topoSorted = Graph.topoSorted(transitive)
val sortedGroups = Graph.groupAroundImportantTargets(topoSorted){
- case t: NamedTask[Any] if mapping.modules.contains(t.owner) =>
- Right(Labelled(
- t,
- t match{
- case t: Target[Any] => Some(t.readWrite.asInstanceOf[upickle.default.ReadWriter[Any]])
- case _ => None
- },
- mapping.modules(t.owner) :+ Segment.Label(t.name)
- ))
+ case t: NamedTask[Any] if mapping.modules.contains(t.owner) =>
+ val segments = mapping.modules(t.owner) :+ Segment.Label(t.name)
+ val finalTaskOverrides = t match{
+ case t: Target[_] => mapping.segmentsToTargets(segments).overrides
+ case c: mill.define.Command[_] => mapping.segmentsToCommands(segments).overrides
+ }
+ val delta = finalTaskOverrides - t.overrides
+ val additional =
+ if (delta == 0) Seq(segments.last)
+ else Seq(Segment.Label(segments.last.asInstanceOf[Segment.Label].value + "-override-" + delta))
+
+ Right(Labelled(t, segments.init ++ additional))
case t if goals.contains(t) => Left(t)
}
diff --git a/core/src/test/scala/mill/discover/DiscoveredTests.scala b/core/src/test/scala/mill/discover/DiscoveredTests.scala
index b2d14080..8501f4cc 100644
--- a/core/src/test/scala/mill/discover/DiscoveredTests.scala
+++ b/core/src/test/scala/mill/discover/DiscoveredTests.scala
@@ -68,11 +68,12 @@ object DiscoveredTests extends TestSuite{
val outerCommands = discovered.mirror.commands
assertMatch(outerCommands){case Seq(
- EntryPoint("hello", Nil, None, false, _),
+ EntryPoint("hello", Nil, None, false, _, _),
EntryPoint("echoPair",
List(ArgSig("prefix", "String", None, None), ArgSig("suffix", "String", None, None)),
None,
false,
+ _,
_
)
) =>}
@@ -82,7 +83,7 @@ object DiscoveredTests extends TestSuite{
.flatMap(_._2.commands.asInstanceOf[Seq[EntryPoint[_]]])
assertMatch(innerCommands){case Seq(
- EntryPoint("inner", _, None, false, _),
+ EntryPoint("inner", _, None, false, _, _),
) =>}
}
diff --git a/core/src/test/scala/mill/eval/EvaluationTests.scala b/core/src/test/scala/mill/eval/EvaluationTests.scala
index 2b40724a..75a6cc52 100644
--- a/core/src/test/scala/mill/eval/EvaluationTests.scala
+++ b/core/src/test/scala/mill/eval/EvaluationTests.scala
@@ -196,6 +196,13 @@ object EvaluationTests extends TestSuite{
checker(task2, 4, OSet(), extraEvaled = -1, secondRunNoOp = false)
}
+ 'overrideSuperTask - {
+ import canOverrideSuper._
+
+ val checker = new Checker(mapping(canOverrideSuper))
+ checker(foo, Seq("base", "object"), OSet(foo), extraEvaled = -1)
+ }
+
'tasksAreUncached - {
// Make sure the tasks `left` and `middle` re-compute every time, while
// the target `right` does not
diff --git a/core/src/test/scala/mill/util/TestGraphs.scala b/core/src/test/scala/mill/util/TestGraphs.scala
index 46ca9ff9..0f2c769f 100644
--- a/core/src/test/scala/mill/util/TestGraphs.scala
+++ b/core/src/test/scala/mill/util/TestGraphs.scala
@@ -167,6 +167,14 @@ object TestGraphs{
}
+ trait BaseModule extends Module {
+ def foo = T{ Seq("base") }
+ }
+
+ object canOverrideSuper extends BaseModule {
+ override def foo = T{ super.foo() ++ Seq("object") }
+ }
+
trait TraitWithModule extends Module{ outer =>
object TraitModule extends Module{
def testFramework = T{ "mill.UTestFramework" }
diff --git a/core/src/test/scala/mill/util/TestUtil.scala b/core/src/test/scala/mill/util/TestUtil.scala
index 8adbc87a..0457431b 100644
--- a/core/src/test/scala/mill/util/TestUtil.scala
+++ b/core/src/test/scala/mill/util/TestUtil.scala
@@ -1,5 +1,6 @@
package mill.util
+import ammonite.main.Router.Overrides
import mill.define.{Caller, Target, Task}
import mill.eval.Result
import utest.assert
@@ -38,8 +39,10 @@ object TestUtil {
val pure: Boolean)
(implicit enclosing0: sourcecode.Enclosing,
owner0: Caller[mill.Module],
- name0: sourcecode.Name)
+ name0: sourcecode.Name,
+ o: Overrides)
extends Test(inputs) with Target[Int]{
+ val overrides = o.value
val enclosing = enclosing0.value
val owner = owner0.value
val name = name0.value