summaryrefslogtreecommitdiff
path: root/core/src/main/scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-12-29 00:48:11 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-12-29 00:48:11 -0800
commit7250a28ac4c14f57cfdbaff1339bfcefca5f0525 (patch)
tree1c8b14679851fd2cb052e4c7fc4422f65097c5a1 /core/src/main/scala
parentd44acfa600ddb0b91197285528de6a60f6266fb5 (diff)
downloadmill-7250a28ac4c14f57cfdbaff1339bfcefca5f0525.tar.gz
mill-7250a28ac4c14f57cfdbaff1339bfcefca5f0525.tar.bz2
mill-7250a28ac4c14f57cfdbaff1339bfcefca5f0525.zip
WIP Migrating `Target` name/pickler generation from the `Mirror` discovery into the `Target` definitions themselves. Haven't deleted the old/unused `Mirror` data structures yet...
Diffstat (limited to 'core/src/main/scala')
-rw-r--r--core/src/main/scala/mill/define/Task.scala73
-rw-r--r--core/src/main/scala/mill/discover/Discovered.scala4
-rw-r--r--core/src/main/scala/mill/discover/Mirror.scala3
-rw-r--r--core/src/main/scala/mill/eval/Evaluator.scala55
-rw-r--r--core/src/main/scala/mill/main/RunScript.scala5
5 files changed, 99 insertions, 41 deletions
diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala
index 4dc5f692..a5007d45 100644
--- a/core/src/main/scala/mill/define/Task.scala
+++ b/core/src/main/scala/mill/define/Task.scala
@@ -3,7 +3,7 @@ package mill.define
import mill.define.Applicative.Applyable
import mill.eval.{PathRef, Result}
import mill.util.Ctx
-
+import upickle.default.{Reader => R, Writer => W, ReadWriter => RW}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
@@ -32,34 +32,42 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[Task, T]{
def self = this
}
-trait Target[+T] extends Task[T]{
+trait NamedTask[+T] extends Task[T]{
+ def owner: Task.Module
+ def name: String
+}
+trait Target[+T] extends NamedTask[T]{
override def asTarget = Some(this)
+ def enclosing: String
+ def readWrite: RW[_]
}
object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Result, Ctx] {
- implicit def apply[T](t: T): Target[T] = macro targetImpl[T]
+ implicit def apply[T](t: T)(implicit r: R[T], w: W[T]): Target[T] = macro targetImpl[T]
- implicit def apply[T](t: Result[T]): Target[T] = macro targetResultImpl[T]
+ implicit def apply[T](t: Result[T])(implicit r: R[T], w: W[T]): Target[T] = macro targetResultImpl[T]
- def apply[T](t: Task[T]): Target[T] = macro targetTaskImpl[T]
+ def apply[T](t: Task[T])(implicit r: R[T], w: W[T]): Target[T] = macro targetTaskImpl[T]
def command[T](t: Result[T]): Command[T] = macro commandImpl[T]
def source(path: ammonite.ops.Path) = new Source(path)
- def command[T](t: Task[T]): Command[T] = new Command(t)
+ def command[T](t: Task[T])(implicit c: Caller[Task.Module], n: sourcecode.Name): Command[T] = new Command(t, c.value, n.value)
def task[T](t: Result[T]): Task[T] = macro Applicative.impl[Task, T, Ctx]
def task[T](t: Task[T]): Task[T] = t
- def persistent[T](t: Result[T]): Target[T] = macro persistentImpl[T]
- def persistentImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[Persistent[T]] = {
+ def persistent[T](t: Result[T])(implicit r: R[T], w: W[T]): Target[T] = macro persistentImpl[T]
+ def persistentImpl[T: c.WeakTypeTag](c: Context)
+ (t: c.Expr[T])
+ (r: c.Expr[R[T]], w: c.Expr[W[T]]): 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})"
+ q"new ${weakTypeOf[Persistent[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree}, _root_.sourcecode.Enclosing(), _root_.mill.define.Caller[mill.define.Task.Module](), _root_.sourcecode.Name(), upickle.default.ReadWriter($w.write, $r.read))"
)
)
}
@@ -67,32 +75,38 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
import c.universe._
c.Expr[Command[T]](
- q"new ${weakTypeOf[Command[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree})"
+ q"new ${weakTypeOf[Command[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree}, _root_.mill.define.Caller[mill.define.Task.Module](), _root_.sourcecode.Name())"
)
}
- def targetTaskImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[Task[T]]): c.Expr[Target[T]] = {
+ def targetTaskImpl[T: c.WeakTypeTag](c: Context)
+ (t: c.Expr[Task[T]])
+ (r: c.Expr[R[T]], w: c.Expr[W[T]]): c.Expr[Target[T]] = {
import c.universe._
c.Expr[Target[T]](
mill.plugin.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[TargetImpl[T]]}($t, _root_.sourcecode.Enclosing())"
+ q"new ${weakTypeOf[TargetImpl[T]]}($t, _root_.sourcecode.Enclosing(), _root_.mill.define.Caller[mill.define.Task.Module](), _root_.sourcecode.Name(), upickle.default.ReadWriter($w.write, $r.read))"
)
)
}
- def targetImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[Target[T]] = {
+ def targetImpl[T: c.WeakTypeTag](c: Context)
+ (t: c.Expr[T])
+ (r: c.Expr[R[T]], w: c.Expr[W[T]]): 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}, _root_.sourcecode.Enclosing())"
+ q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Ctx](c)(q"mill.eval.Result.Success($t)").tree}, _root_.sourcecode.Enclosing(), _root_.mill.define.Caller[mill.define.Task.Module](), _root_.sourcecode.Name(), upickle.default.ReadWriter($w.write, $r.read))"
)
)
}
- def targetResultImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[Result[T]]): c.Expr[Target[T]] = {
+ def targetResultImpl[T: c.WeakTypeTag](c: Context)
+ (t: c.Expr[Result[T]])
+ (r: c.Expr[R[T]], w: c.Expr[W[T]]): 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}, _root_.sourcecode.Enclosing())"
+ q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Ctx](c)(t.tree).tree}, _root_.sourcecode.Enclosing(), _root_.mill.define.Caller[mill.define.Task.Module](), _root_.sourcecode.Name(), upickle.default.ReadWriter($w.write, $r.read))"
)
)
}
@@ -109,19 +123,36 @@ 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)
}
-class TargetImpl[+T](t: Task[T], enclosing: String) extends Target[T] {
+case class Caller[A](value: A)
+object Caller {
+ def apply[T]()(implicit c: Caller[T]) = c.value
+ implicit def generate[T]: Caller[T] = macro impl[T]
+ def impl[T: c.WeakTypeTag](c: Context): c.Tree = {
+ import c.universe._
+ q"new _root_.mill.define.Caller[${weakTypeOf[T]}](this)"
+ }
+}
+
+class TargetImpl[+T](t: Task[T],
+ val enclosing: String,
+ val owner: Task.Module,
+ val name: String,
+ val readWrite: RW[_]) extends Target[T] {
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
override def toString = enclosing + "@" + Integer.toHexString(System.identityHashCode(this))
}
-class Command[+T](t: Task[T]) extends Task[T] {
+class Command[+T](t: Task[T], val owner: Task.Module, val name: String) extends NamedTask[T] {
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
override def asCommand = Some(this)
}
-class Persistent[+T](t: Task[T]) extends Target[T] {
- val inputs = Seq(t)
- def evaluate(args: Ctx) = args[T](0)
+class Persistent[+T](t: Task[T],
+ enclosing: String,
+ owner: Task.Module,
+ name: String,
+ readWrite: RW[_])
+ extends TargetImpl[T](t, enclosing, owner, name, readWrite) {
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 a8d91f1d..8824a341 100644
--- a/core/src/main/scala/mill/discover/Discovered.scala
+++ b/core/src/main/scala/mill/discover/Discovered.scala
@@ -19,7 +19,7 @@ class Discovered[T](val mirror: Mirror[T, T]){
}
def mapping(t: T) = {
Discovered.Mapping(
- targets(t).map(x => x.target -> x).toMap[Target[Any], LabelledTarget[_]],
+ targets(t).map(x => x.target -> x).toMap[Task[Any], LabelledTarget[_]],
mirror,
t
)
@@ -31,7 +31,7 @@ object Discovered {
// Magically injected by the `Evaluator`, rather than being constructed here
def make() = ???
}
- case class Mapping[T](value: Map[Target[Any], LabelledTarget[_]],
+ case class Mapping[T](value: Map[Task[Any], LabelledTarget[_]],
mirror: Mirror[T, T],
base: T)
diff --git a/core/src/main/scala/mill/discover/Mirror.scala b/core/src/main/scala/mill/discover/Mirror.scala
index 926d9669..7fa9736b 100644
--- a/core/src/main/scala/mill/discover/Mirror.scala
+++ b/core/src/main/scala/mill/discover/Mirror.scala
@@ -56,10 +56,11 @@ object Mirror{
rec(Nil, hierarchy)
}
+
/**
* A target after being materialized in a concrete build
*/
- case class LabelledTarget[V](target: Target[V],
+ case class LabelledTarget[V](target: Task[V],
format: upickle.default.ReadWriter[V],
segments: Seq[Segment])
diff --git a/core/src/main/scala/mill/eval/Evaluator.scala b/core/src/main/scala/mill/eval/Evaluator.scala
index 96ee1b6e..130dbcbc 100644
--- a/core/src/main/scala/mill/eval/Evaluator.scala
+++ b/core/src/main/scala/mill/eval/Evaluator.scala
@@ -4,30 +4,48 @@ import java.net.URLClassLoader
import ammonite.ops._
import ammonite.runtime.SpecialClassLoader
-import mill.define.{Graph, Target, Task, Worker}
+import mill.define._
import mill.discover.{Discovered, Mirror}
-import mill.discover.Mirror.LabelledTarget
-import mill.discover.Mirror.Segment.{Cross, Label}
+import mill.discover.Mirror.{LabelledTarget, Segment}
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])
class Evaluator[T](val workspacePath: Path,
val mapping: Discovered.Mapping[T],
log: Logger,
val classLoaderSig: Seq[(Path, Long)] = Evaluator.classLoaderSig){
- val labeling = mapping.value
+
+ val moduleMapping = Mirror.traverse(mapping.base, mapping.mirror){ (mirror, segmentsRev) =>
+ val resolvedNode = mirror.node(
+ mapping.base,
+ segmentsRev.reverse.map{case Mirror.Segment.Cross(vs) => vs.toList case _ => Nil}.toList
+ )
+ Seq(resolvedNode -> segmentsRev.reverse)
+ }.toMap
+
val workerCache = mutable.Map.empty[Ctx.Loader[_], Any]
workerCache(Discovered.Mapping) = mapping
def evaluate(goals: OSet[Task[_]]): Evaluator.Results = {
mkdir(workspacePath)
+ LabelledTarget
val transitive = Graph.transitiveTargets(goals)
val topoSorted = Graph.topoSorted(transitive)
val sortedGroups = Graph.groupAroundImportantTargets(topoSorted){
- case t: Target[_] if labeling.contains(t) || goals.contains(t) => Right(labeling(t))
+ case t: NamedTask[Any] if moduleMapping.contains(t.owner) =>
+ Right(Labelled(
+ t,
+ t match{
+ case t: Target[Any] => Some(t.readWrite.asInstanceOf[upickle.default.ReadWriter[Any]])
+ case _ => None
+ },
+ moduleMapping(t.owner) :+ Segment.Label(t.name)
+ ))
case t if goals.contains(t) => Left(t)
}
@@ -43,7 +61,7 @@ class Evaluator[T](val workspacePath: Path,
}
- val failing = new util.MultiBiMap.Mutable[Either[Task[_], LabelledTarget[_]], Result.Failing]
+ val failing = new util.MultiBiMap.Mutable[Either[Task[_], Labelled[_]], Result.Failing]
for((k, vs) <- sortedGroups.items()){
failing.addAll(k, vs.items.flatMap(results.get).collect{case f: Result.Failing => f})
}
@@ -51,8 +69,7 @@ class Evaluator[T](val workspacePath: Path,
}
-
- def evaluateGroupCached(terminal: Either[Task[_], LabelledTarget[_]],
+ def evaluateGroupCached(terminal: Either[Task[_], Labelled[_]],
group: OSet[Task[_]],
results: collection.Map[Task[_], Result[Any]]): (collection.Map[Task[_], Result[Any]], Seq[Task[_]]) = {
@@ -78,7 +95,7 @@ class Evaluator[T](val workspacePath: Path,
cached match{
case Some(terminalResult) =>
val newResults = mutable.LinkedHashMap.empty[Task[_], Result[Any]]
- newResults(labelledTarget.target) = labelledTarget.format.read(terminalResult)
+ newResults(labelledTarget.target) = labelledTarget.format.get.read(terminalResult)
(newResults, Nil)
case _ =>
@@ -100,10 +117,12 @@ class Evaluator[T](val workspacePath: Path,
case Result.Success(v) =>
val terminalResult = labelledTarget
.format
- .asInstanceOf[upickle.default.ReadWriter[Any]]
- .write(v)
+ .asInstanceOf[Option[upickle.default.ReadWriter[Any]]]
+ .map(_.write(v))
- write.over(metadataPath, upickle.default.write(inputsHash -> terminalResult, indent = 4))
+ for(t <- terminalResult){
+ write.over(metadataPath, upickle.default.write(inputsHash -> t, indent = 4))
+ }
case _ =>
// Wipe out any cached metadata.mill.json file that exists, so
// a following run won't look at the cached metadata file and
@@ -206,7 +225,13 @@ class Evaluator[T](val workspacePath: Path,
object Evaluator{
def resolveDestPaths(workspacePath: Path, t: LabelledTarget[_]): (Path, Path) = {
- val segmentStrings = t.segments.flatMap{
+ resolveDestPaths(workspacePath, t.segments)
+ }
+ def resolveDestPaths(workspacePath: Path, t: Labelled[_]): (Path, Path) = {
+ resolveDestPaths(workspacePath, t.segments)
+ }
+ def resolveDestPaths(workspacePath: Path, segments: Seq[Segment]): (Path, Path) = {
+ val segmentStrings = segments.flatMap{
case Mirror.Segment.Label(s) => Seq(s)
case Mirror.Segment.Cross(values) => values.map(_.toString)
}
@@ -225,7 +250,7 @@ object Evaluator{
case class Results(rawValues: Seq[Result[Any]],
evaluated: OSet[Task[_]],
transitive: OSet[Task[_]],
- failing: MultiBiMap[Either[Task[_], LabelledTarget[_]], Result.Failing]){
+ failing: MultiBiMap[Either[Task[_], Labelled[_]], Result.Failing]){
def values = rawValues.collect{case Result.Success(v) => v}
}
}
diff --git a/core/src/main/scala/mill/main/RunScript.scala b/core/src/main/scala/mill/main/RunScript.scala
index f58cf5c0..3d41be2c 100644
--- a/core/src/main/scala/mill/main/RunScript.scala
+++ b/core/src/main/scala/mill/main/RunScript.scala
@@ -8,6 +8,7 @@ import ammonite.util.Util.CodeSource
import ammonite.util.{Name, Res, Util}
import mill.define
import mill.define.Task
+import mill.discover.Mirror.Segment
import mill.discover.{Discovered, Mirror}
import mill.eval.{Evaluator, Result}
import mill.util.{OSet, PrintLogger}
@@ -141,8 +142,8 @@ object RunScript{
val json = for(t <- Seq(target)) yield {
t match {
case t: mill.define.Target[_] =>
- for (labelled <- evaluator.labeling.get(t)) yield {
- val jsonFile = Evaluator.resolveDestPaths(evaluator.workspacePath, labelled)._2
+ for (segments <- evaluator.moduleMapping.get(t.owner)) yield {
+ val jsonFile = Evaluator.resolveDestPaths(evaluator.workspacePath, segments :+ Segment.Label(t.name))._2
val metadata = upickle.json.read(jsonFile.toIO)
metadata(1)
}