summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-12-04 21:55:01 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-12-04 21:55:15 -0800
commit422d41498d43ad9b437b2d4460f61849e78bb6fa (patch)
tree167ebadc8dab617bbc6388d1ff4d13b5b08115d1 /core
parente9f3c71f670f93c95f0ae47860e663b768885067 (diff)
downloadmill-422d41498d43ad9b437b2d4460f61849e78bb6fa.tar.gz
mill-422d41498d43ad9b437b2d4460f61849e78bb6fa.tar.bz2
mill-422d41498d43ad9b437b2d4460f61849e78bb6fa.zip
- Make `T.ctx()` available implicitly
- Convert `ScalaModule.{compile,assembly}` to use the new implicit `T.ctx()` - Add a `log: PrintStream` to the `T.ctx()`, in preparation for per-task logging
Diffstat (limited to 'core')
-rw-r--r--core/src/main/scala/mill/define/Applicative.scala13
-rw-r--r--core/src/main/scala/mill/define/Task.scala49
-rw-r--r--core/src/main/scala/mill/eval/Evaluator.scala8
-rw-r--r--core/src/main/scala/mill/modules/Jvm.scala16
-rw-r--r--core/src/main/scala/mill/util/Args.scala9
-rw-r--r--core/src/main/scala/mill/util/Ctx.scala34
-rw-r--r--core/src/test/examples/javac/build.sc4
-rw-r--r--core/src/test/scala/mill/define/ApplicativeTests.scala5
-rw-r--r--core/src/test/scala/mill/util/TestUtil.scala2
9 files changed, 87 insertions, 53 deletions
diff --git a/core/src/main/scala/mill/define/Applicative.scala b/core/src/main/scala/mill/define/Applicative.scala
index 4973dfd0..f8193742 100644
--- a/core/src/main/scala/mill/define/Applicative.scala
+++ b/core/src/main/scala/mill/define/Applicative.scala
@@ -1,9 +1,7 @@
package mill.define
-import mill.util.Args
-import scala.annotation.compileTimeOnly
-import scala.collection.mutable
+import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.reflect.macros.blackbox.Context
/**
@@ -20,11 +18,11 @@ object Applicative {
@compileTimeOnly("Target#apply() can only be used with a T{...} block")
def apply(): T = ???
}
+ class ImplicitStub extends StaticAnnotation
type Id[+T] = T
trait Applyer[W[_], T[_], Z[_], Ctx]{
- @compileTimeOnly("Target.ctx() can only be used with a T{...} block")
- def ctx(): Ctx = ???
+ def ctx()(implicit c: Ctx) = c
def underlying[A](v: W[A]): T[_]
def mapCtx[A, B](a: T[A])(f: (A, Ctx) => Z[B]): T[B]
@@ -92,8 +90,9 @@ object Applicative {
c.internal.setFlag(tempSym, (1L << 44).asInstanceOf[c.universe.FlagSet])
bound.append((q"${c.prefix}.underlying($fun)", c.internal.valDef(tempSym)))
tempIdent
- case (t @ q"$prefix.ctx()", api)
- if prefix.tpe.baseClasses.exists(_.fullName == "mill.define.Applicative.Applyer") =>
+ case (t, api)
+ if t.symbol != null
+ && t.symbol.annotations.exists(_.tree.tpe =:= typeOf[ImplicitStub]) =>
val tempIdent = Ident(ctxSym)
c.internal.setType(tempIdent, t.tpe)
diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala
index c54634db..451cc1d4 100644
--- a/core/src/main/scala/mill/define/Task.scala
+++ b/core/src/main/scala/mill/define/Task.scala
@@ -2,7 +2,7 @@ package mill.define
import mill.define.Applicative.Applyable
import mill.eval.{PathRef, Result}
-import mill.util.Args
+import mill.util.Ctx
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
@@ -16,7 +16,7 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[T]{
/**
* Evaluate this target
*/
- def evaluate(args: Args): Result[T]
+ def evaluate(args: Ctx): Result[T]
/**
* Even if this target's inputs did not change, does it need to re-evaluate
@@ -34,7 +34,8 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[T]{
trait Target[+T] extends Task[T]{
override def asTarget = Some(this)
}
-object Target extends Applicative.Applyer[Task, Task, Result, Args]{
+
+object Target extends Applicative.Applyer[Task, Task, Result, Ctx]{
implicit def apply[T](t: T): Target[T] = macro targetImpl[T]
@@ -48,7 +49,7 @@ object Target extends Applicative.Applyer[Task, Task, Result, Args]{
def command[T](t: Task[T]): Command[T] = new Command(t)
- def task[T](t: Result[T]): Task[T] = macro Applicative.impl[Task, T, Args]
+ 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]
@@ -57,7 +58,7 @@ object Target extends Applicative.Applyer[Task, Task, Result, Args]{
c.Expr[Persistent[T]](
mill.define.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[Persistent[T]]}(${Applicative.impl[Task, T, Args](c)(t).tree})"
+ q"new ${weakTypeOf[Persistent[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree})"
)
)
}
@@ -65,7 +66,7 @@ object Target extends Applicative.Applyer[Task, Task, Result, Args]{
import c.universe._
c.Expr[Command[T]](
- q"new ${weakTypeOf[Command[T]]}(${Applicative.impl[Task, T, Args](c)(t).tree})"
+ q"new ${weakTypeOf[Command[T]]}(${Applicative.impl[Task, T, Ctx](c)(t).tree})"
)
}
@@ -81,50 +82,50 @@ object Target extends Applicative.Applyer[Task, Task, Result, Args]{
import c.universe._
c.Expr[Target[T]](
mill.define.Cacher.wrapCached(c)(
- q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Args](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())"
)
)
}
def underlying[A](v: Task[A]) = v
- def mapCtx[A, B](t: Task[A])(f: (A, Args) => Result[B]) = t.mapDest(f)
+ def mapCtx[A, B](t: Task[A])(f: (A, Ctx) => Result[B]) = t.mapDest(f)
def zip() = new Task.Task0(())
def zip[A](a: Task[A]) = a.map(Tuple1(_))
def zip[A, B](a: Task[A], b: Task[B]) = a.zip(b)
def zip[A, B, C](a: Task[A], b: Task[B], c: Task[C]) = new Task[(A, B, C)]{
val inputs = Seq(a, b, c)
- def evaluate(args: Args) = (args[A](0), args[B](1), args[C](2))
+ def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2))
}
def zip[A, B, C, D](a: Task[A], b: Task[B], c: Task[C], d: Task[D]) = new Task[(A, B, C, D)]{
val inputs = Seq(a, b, c, d)
- def evaluate(args: Args) = (args[A](0), args[B](1), args[C](2), args[D](3))
+ def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3))
}
def zip[A, B, C, D, E](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E]) = new Task[(A, B, C, D, E)]{
val inputs = Seq(a, b, c, d, e)
- def evaluate(args: Args) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4))
+ def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4))
}
def zip[A, B, C, D, E, F](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F]) = new Task[(A, B, C, D, E, F)]{
val inputs = Seq(a, b, c, d, e, f)
- def evaluate(args: Args) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5))
+ def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5))
}
def zip[A, B, C, D, E, F, G](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F], g: Task[G]) = new Task[(A, B, C, D, E, F, G)]{
val inputs = Seq(a, b, c, d, e, f, g)
- def evaluate(args: Args) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6))
+ def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6))
}
}
class TargetImpl[+T](t: Task[T], enclosing: String) extends Target[T] {
val inputs = Seq(t)
- def evaluate(args: Args) = args[T](0)
+ 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] {
val inputs = Seq(t)
- def evaluate(args: Args) = args[T](0)
+ 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: Args) = args[T](0)
+ def evaluate(args: Ctx) = args[T](0)
override def flushDest = false
override def asPersistent = Some(this)
}
@@ -133,7 +134,7 @@ object Source{
}
class Source(path: ammonite.ops.Path) extends Task[PathRef]{
def handle = PathRef(path)
- def evaluate(args: Args) = handle
+ def evaluate(args: Ctx) = handle
override def sideHash = handle.hashCode()
val inputs = Nil
}
@@ -151,7 +152,7 @@ object Task {
class Task0[T](t: T) extends Task[T]{
lazy val t0 = t
val inputs = Nil
- def evaluate(args: Args) = t0
+ def evaluate(args: Ctx) = t0
}
@@ -159,7 +160,7 @@ object Task {
abstract class Ops[+T]{ this: Task[T] =>
def map[V](f: T => V) = new Task.Mapped(this, f)
- def mapDest[V](f: (T, Args) => Result[V]) = new Task.MappedDest(this, f)
+ def mapDest[V](f: (T, Ctx) => Result[V]) = new Task.MappedDest(this, f)
def filter(f: T => Boolean) = this
def withFilter(f: T => Boolean) = this
@@ -172,22 +173,22 @@ object Task {
}
class Traverse[+T](inputs0: Seq[Task[T]]) extends Task[Seq[T]]{
val inputs = inputs0
- def evaluate(args: Args) = {
+ def evaluate(args: Ctx) = {
for (i <- 0 until args.length)
yield args(i).asInstanceOf[T]
}
}
class Mapped[+T, +V](source: Task[T], f: T => V) extends Task[V]{
- def evaluate(args: Args) = f(args(0))
+ def evaluate(args: Ctx) = f(args(0))
val inputs = List(source)
}
- class MappedDest[+T, +V](source: Task[T], f: (T, Args) => Result[V]) extends Task[V]{
- def evaluate(args: Args) = f(args(0), args)
+ class MappedDest[+T, +V](source: Task[T], f: (T, Ctx) => Result[V]) extends Task[V]{
+ def evaluate(args: Ctx) = f(args(0), args)
val inputs = List(source)
}
class Zipped[+T, +V](source1: Task[T], source2: Task[V]) extends Task[(T, V)]{
- def evaluate(args: Args) = (args(0), args(1))
+ def evaluate(args: Ctx) = (args(0), args(1))
val inputs = List(source1, source2)
}
diff --git a/core/src/main/scala/mill/eval/Evaluator.scala b/core/src/main/scala/mill/eval/Evaluator.scala
index db74445c..b769c025 100644
--- a/core/src/main/scala/mill/eval/Evaluator.scala
+++ b/core/src/main/scala/mill/eval/Evaluator.scala
@@ -6,7 +6,7 @@ import mill.define.{Graph, Target, Task}
import mill.discover.Mirror
import mill.discover.Mirror.LabelledTarget
import mill.util
-import mill.util.{Args, MultiBiMap, OSet}
+import mill.util.{Ctx, MultiBiMap, OSet}
import scala.collection.mutable
class Evaluator(workspacePath: Path,
@@ -163,7 +163,11 @@ class Evaluator(workspacePath: Path,
val res =
if (targetInputValues.length != target.inputs.length) Result.Skipped
else {
- val args = new Args(targetInputValues.toArray[Any], targetDestPath.orNull)
+ val args = new Ctx(
+ targetInputValues.toArray[Any],
+ targetDestPath.orNull,
+ System.out
+ )
target.evaluate(args)
}
diff --git a/core/src/main/scala/mill/modules/Jvm.scala b/core/src/main/scala/mill/modules/Jvm.scala
index 69dfcda8..74eecba4 100644
--- a/core/src/main/scala/mill/modules/Jvm.scala
+++ b/core/src/main/scala/mill/modules/Jvm.scala
@@ -7,7 +7,7 @@ import java.util.jar.{JarEntry, JarFile, JarOutputStream}
import ammonite.ops._
import mill.define.Task
import mill.eval.PathRef
-import mill.util.Args
+import mill.util.Ctx
import scala.collection.mutable
@@ -65,14 +65,14 @@ object Jvm {
}
- def createAssembly(outputPath: Path,
- inputPaths: Seq[Path],
+ def createAssembly(inputPaths: Seq[Path],
mainClass: Option[String] = None,
- prependShellScript: String = ""): Option[Path] = {
+ prependShellScript: String = "")
+ (implicit ctx: Ctx.DestCtx): PathRef = {
+ val outputPath = ctx.dest
rm(outputPath)
- if(inputPaths.isEmpty) None
- else {
+ if(inputPaths.nonEmpty) {
mkdir(outputPath/up)
val output = new FileOutputStream(outputPath.toIO)
@@ -125,14 +125,14 @@ object Jvm {
output.close()
}
- Some(outputPath)
}
+ PathRef(outputPath)
}
def jarUp(roots: Task[PathRef]*) = new Task[PathRef]{
val inputs = roots
- def evaluate(args: Args) = {
+ def evaluate(args: Ctx) = {
createJar(args.dest, args.args.map(_.asInstanceOf[PathRef].path))
PathRef(args.dest)
}
diff --git a/core/src/main/scala/mill/util/Args.scala b/core/src/main/scala/mill/util/Args.scala
deleted file mode 100644
index 4ac49df5..00000000
--- a/core/src/main/scala/mill/util/Args.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package mill.util
-
-class Args(val args: IndexedSeq[_], val dest: ammonite.ops.Path){
- def length = args.length
- def apply[T](index: Int): T = {
- if (index >= 0 && index < args.length) args(index).asInstanceOf[T]
- else throw new IndexOutOfBoundsException(s"Index $index outside of range 0 - ${args.length}")
- }
-}
diff --git a/core/src/main/scala/mill/util/Ctx.scala b/core/src/main/scala/mill/util/Ctx.scala
new file mode 100644
index 00000000..f583feaf
--- /dev/null
+++ b/core/src/main/scala/mill/util/Ctx.scala
@@ -0,0 +1,34 @@
+package mill.util
+
+import java.io.PrintStream
+
+import ammonite.ops.Path
+import mill.define.Applicative.ImplicitStub
+import mill.util.Ctx.{ArgCtx, DestCtx, LogCtx}
+
+import scala.annotation.compileTimeOnly
+
+object Ctx{
+ @compileTimeOnly("Target.ctx() can only be used with a T{...} block")
+ @ImplicitStub
+ implicit def taskCtx: Ctx = ???
+
+ trait DestCtx{
+ def dest: Path
+ }
+ trait LogCtx{
+ def log: PrintStream
+ }
+ trait ArgCtx{
+ def args: IndexedSeq[_]
+ }
+}
+class Ctx(val args: IndexedSeq[_],
+ val dest: Path,
+ val log: PrintStream) extends DestCtx with LogCtx with ArgCtx{
+ def length = args.length
+ def apply[T](index: Int): T = {
+ if (index >= 0 && index < args.length) args(index).asInstanceOf[T]
+ else throw new IndexOutOfBoundsException(s"Index $index outside of range 0 - ${args.length}")
+ }
+}
diff --git a/core/src/test/examples/javac/build.sc b/core/src/test/examples/javac/build.sc
index a54e2110..e4f7ea01 100644
--- a/core/src/test/examples/javac/build.sc
+++ b/core/src/test/examples/javac/build.sc
@@ -8,7 +8,7 @@ object Foo {
import ammonite.ops.{ls, pwd, read}
import mill.discover.Discovered
- import mill.util.Args
+ import mill.util.Ctx
val workspacePath = pwd / 'target / 'workspace / 'javac
val javacSrcPath = pwd / 'src / 'test / 'examples / 'javac
@@ -45,7 +45,7 @@ object Foo {
val inputs = roots
- def evaluate(args: Args): PathRef = {
+ def evaluate(args: Ctx): PathRef = {
val output = new java.util.jar.JarOutputStream(new FileOutputStream(args.dest.toIO))
for {
diff --git a/core/src/test/scala/mill/define/ApplicativeTests.scala b/core/src/test/scala/mill/define/ApplicativeTests.scala
index 7e31b08e..7e325184 100644
--- a/core/src/test/scala/mill/define/ApplicativeTests.scala
+++ b/core/src/test/scala/mill/define/ApplicativeTests.scala
@@ -1,7 +1,9 @@
package mill.define
+import mill.define.Applicative.ImplicitStub
import utest._
+import scala.annotation.compileTimeOnly
import scala.language.experimental.macros
@@ -44,6 +46,9 @@ object ApplicativeTests extends TestSuite {
value
}
}
+ @compileTimeOnly("Target.ctx() can only be used with a T{...} block")
+ @ImplicitStub
+ implicit def taskCtx: String = ???
val tests = Tests{
diff --git a/core/src/test/scala/mill/util/TestUtil.scala b/core/src/test/scala/mill/util/TestUtil.scala
index be6bb8e9..a456b22b 100644
--- a/core/src/test/scala/mill/util/TestUtil.scala
+++ b/core/src/test/scala/mill/util/TestUtil.scala
@@ -21,7 +21,7 @@ object TestUtil {
var counter = 0
var failure = Option.empty[String]
var exception = Option.empty[Throwable]
- override def evaluate(args: Args) = {
+ override def evaluate(args: Ctx) = {
failure.map(Result.Failure) orElse
exception.map(Result.Exception) getOrElse
Result.Success(counter + args.args.map(_.asInstanceOf[Int]).sum)