summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/scala/mill/Main.scala46
-rw-r--r--core/src/main/scala/mill/define/Applicative.scala8
-rw-r--r--core/src/main/scala/mill/define/Task.scala4
-rw-r--r--core/src/main/scala/mill/discover/Discovered.scala5
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/TestRunner.scala20
5 files changed, 61 insertions, 22 deletions
diff --git a/core/src/main/scala/mill/Main.scala b/core/src/main/scala/mill/Main.scala
index c4df0ee5..2c313e2d 100644
--- a/core/src/main/scala/mill/Main.scala
+++ b/core/src/main/scala/mill/Main.scala
@@ -6,21 +6,23 @@ import ammonite.ops._
import ammonite.util.{Colors, Res}
import mill.define.Task
import mill.discover._
-import mill.eval.Evaluator
+import mill.eval.{Evaluator, Result}
import mill.util.OSet
import ammonite.main.Scripts.pathScoptRead
import ammonite.repl.Repl
object Main {
- def apply[T: Discovered](args: Seq[String], obj: T, watch: Path => Unit) = {
+ def apply[T: Discovered](args: Seq[String], obj: T, watch: Path => Unit): Int = {
val Seq(selectorString, rest @_*) = args
val selector = selectorString.split('.')
val discovered = implicitly[Discovered[T]]
val consistencyErrors = Discovered.consistencyCheck(obj, discovered)
- if (consistencyErrors.nonEmpty) println("Failed Discovered.consistencyCheck: " + consistencyErrors)
- else {
+ if (consistencyErrors.nonEmpty) {
+ println("Failed Discovered.consistencyCheck: " + consistencyErrors)
+ 1
+ } else {
val mapping = Discovered.mapping(obj)(discovered)
val workspacePath = pwd / 'out
@@ -53,7 +55,25 @@ object Main {
case _ => // do nothing
}
- case None => println("Unknown selector: " + selector.mkString("."))
+ val failing = evaluated.failing.items
+ println(evaluated.failing.keyCount + " targets failed")
+
+ for((k, fs) <- failing){
+ val ks = k match{
+ case Left(t) => t.toString
+ case Right(t) => t.segments.mkString(".")
+ }
+ val fss = fs.map{
+ case Result.Exception(t) => t.toString
+ case Result.Failure(t) => t
+ }
+ println(ks + " " + fss.mkString(", "))
+ }
+
+ if (evaluated.failing.keyCount == 0) 0 else 1
+ case None =>
+ println("Unknown selector: " + selector.mkString("."))
+ 1
}
}
}
@@ -105,7 +125,11 @@ object Main {
if (config.help) {
val leftMargin = signature.map(ammonite.main.Cli.showArg(_).length).max + 2
System.err.println(ammonite.main.Cli.formatBlock(signature, leftMargin).mkString("\n"))
- } else new Main(config).run(leftover, startTime)
+ System.exit(0)
+ } else {
+ val res = new Main(config).run(leftover, startTime)
+ System.exit(res)
+ }
}
}
@@ -147,8 +171,9 @@ class Main(config: Main.Config){
case Res.Exit(_) => ???
}
- def run(leftover: List[String], startTime0: Long) = {
+ def run(leftover: List[String], startTime0: Long): Int = {
+ var exitCode = 0
var startTime = startTime0
val loop = config.watch
@@ -181,8 +206,12 @@ class Main(config: Main.Config){
interp,
Scripts.groupArgs(leftover)
)
+ res match{
+ case Res.Success(v: Int) => exitCode = v
+ case _ => exitCode = 1
+ }
- handleWatchRes(res, true)
+ handleWatchRes(res, false)
interp.watchedFiles
}
@@ -191,5 +220,6 @@ class Main(config: Main.Config){
watchAndWait(watchedFiles)
startTime = System.currentTimeMillis()
} while(loop)
+ exitCode
}
}
diff --git a/core/src/main/scala/mill/define/Applicative.scala b/core/src/main/scala/mill/define/Applicative.scala
index 512e5a12..5c626455 100644
--- a/core/src/main/scala/mill/define/Applicative.scala
+++ b/core/src/main/scala/mill/define/Applicative.scala
@@ -52,6 +52,10 @@ object Applicative {
def impl[M[_], T: c.WeakTypeTag, Ctx: c.WeakTypeTag](c: Context)
(t: c.Expr[T]): c.Expr[M[T]] = {
+ impl0(c)(t.tree)(implicitly[c.WeakTypeTag[T]], implicitly[c.WeakTypeTag[Ctx]])
+ }
+ def impl0[M[_], T: c.WeakTypeTag, Ctx: c.WeakTypeTag](c: Context)
+ (t: c.Tree): c.Expr[M[T]] = {
import c.universe._
def rec(t: Tree): Iterator[c.Tree] = Iterator(t) ++ t.children.flatMap(rec(_))
@@ -60,13 +64,13 @@ object Applicative {
// Derived from @olafurpg's
// https://gist.github.com/olafurpg/596d62f87bf3360a29488b725fbc7608
- val defs = rec(t.tree).filter(_.isDef).map(_.symbol).toSet
+ val defs = rec(t).filter(_.isDef).map(_.symbol).toSet
val ctxName = TermName(c.freshName("ctx"))
val ctxSym = c.internal.newTermSymbol(c.internal.enclosingOwner, ctxName)
c.internal.setInfo(ctxSym, weakTypeOf[Ctx])
- val transformed = c.internal.typingTransform(t.tree) {
+ val transformed = c.internal.typingTransform(t) {
case (t @ q"$fun.apply()", api) if t.symbol == targetApplySym =>
val localDefs = rec(fun).filter(_.isDef).map(_.symbol).toSet
diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala
index 471c530f..5aa97eff 100644
--- a/core/src/main/scala/mill/define/Task.scala
+++ b/core/src/main/scala/mill/define/Task.scala
@@ -36,6 +36,8 @@ trait Target[+T] extends Task[T]{
}
object Target extends Applicative.Applyer[Task, Task, Result, Args]{
+ implicit def apply[T](t: T): Target[T] = macro targetImpl[T]
+
implicit def apply[T](t: Result[T]): Target[T] = macro targetImpl[T]
def apply[T](t: Task[T]): Target[T] = macro targetTaskImpl[T]
@@ -79,7 +81,7 @@ 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.impl[Task, T, Args](c)(t).tree}, _root_.sourcecode.Enclosing())"
+ q"new ${weakTypeOf[TargetImpl[T]]}(${Applicative.impl0[Task, T, Args](c)(q"mill.eval.Result.Success($t)").tree}, _root_.sourcecode.Enclosing())"
)
)
}
diff --git a/core/src/main/scala/mill/discover/Discovered.scala b/core/src/main/scala/mill/discover/Discovered.scala
index 499a0736..9d46f196 100644
--- a/core/src/main/scala/mill/discover/Discovered.scala
+++ b/core/src/main/scala/mill/discover/Discovered.scala
@@ -17,10 +17,6 @@ class Discovered[T](val mirror: Mirror[T, T]){
h.labelled(obj, p)
}
- def mains = Mirror.traverse(mirror) { (h, p) =>
- h.commands.map(x => (p, x: EntryPoint[_]))
- }
-
}
object Discovered {
@@ -33,7 +29,6 @@ object Discovered {
}
-
def mapping[T: Discovered](t: T): Map[Target[_], LabelledTarget[_]] = {
implicitly[Discovered[T]].targets(t).map(x => x.target -> x).toMap
}
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/TestRunner.scala b/scalaplugin/src/main/scala/mill/scalaplugin/TestRunner.scala
index 93721e8f..d8577f9c 100644
--- a/scalaplugin/src/main/scala/mill/scalaplugin/TestRunner.scala
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/TestRunner.scala
@@ -8,6 +8,8 @@ import java.util.zip.ZipInputStream
import ammonite.ops.{Path, ls, pwd}
import sbt.testing._
+import scala.collection.mutable
+
object TestRunner {
def listClassFiles(base: Path): Iterator[String] = {
if (base.isDir) ls.rec(base).toIterator.filter(_.ext == "class").map(_.relativeTo(base).toString)
@@ -38,7 +40,7 @@ object TestRunner {
def apply(frameworkName: String,
entireClasspath: Seq[Path],
- testClassfilePath: Seq[Path]): Unit = {
+ testClassfilePath: Seq[Path]): mill.eval.Result[Unit] = {
val outerClassLoader = getClass.getClassLoader
val cl = new URLClassLoader(entireClasspath.map(_.toIO.toURI.toURL).toArray){
override def findClass(name: String) = {
@@ -64,10 +66,11 @@ object TestRunner {
new TaskDef(cls.getName.stripSuffix("$"), fingerprint, true, Array())
}
)
+ val events = mutable.Buffer.empty[Status]
for(t <- tasks){
t.execute(
new EventHandler {
- def handle(event: Event) = ()
+ def handle(event: Event) = events.append(event.status())
},
Array(
new Logger {
@@ -86,9 +89,14 @@ object TestRunner {
)
}
val doneMsg = runner.done()
- if (doneMsg.trim.nonEmpty){
- println(doneMsg)
- println(doneMsg)
- }
+ val msg =
+ if (doneMsg.trim.nonEmpty)doneMsg
+ else{
+ val grouped = events.groupBy(x => x).mapValues(_.length).filter(_._2 != 0).toList.sorted
+ grouped.map{case (k, v) => k + ": " + v}.mkString(",")
+ }
+ println(msg)
+ if (events.count(Set(Status.Error, Status.Failure)) == 0) mill.eval.Result.Success(())
+ else mill.eval.Result.Failure(msg)
}
}