summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/mill/define/Task.scala12
-rw-r--r--core/src/mill/util/EnclosingClass.scala15
-rw-r--r--core/src/mill/util/ParseArgs.scala33
-rw-r--r--main/src/mill/main/MainModule.scala86
-rw-r--r--main/src/mill/main/MainScopts.scala35
-rw-r--r--main/src/mill/main/RunScript.scala23
6 files changed, 96 insertions, 108 deletions
diff --git a/core/src/mill/define/Task.scala b/core/src/mill/define/Task.scala
index 230089bf..33f94453 100644
--- a/core/src/mill/define/Task.scala
+++ b/core/src/mill/define/Task.scala
@@ -3,23 +3,13 @@ package mill.define
import ammonite.main.Router.Overrides
import mill.define.Applicative.Applyable
import mill.eval.{PathRef, Result}
+import mill.util.EnclosingClass
import sourcecode.Compat.Context
import upickle.default.{ReadWriter => RW, Reader => R, Writer => W}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
-case class EnclosingClass(value: Class[_])
-object EnclosingClass{
- def apply()(implicit c: EnclosingClass) = c.value
- implicit def generate: EnclosingClass = macro impl
- def impl(c: Context): c.Tree = {
- import c.universe._
- val cls = c.internal.enclosingOwner.owner.asType.asClass
-// q"new _root_.mill.define.EnclosingClass(classOf[$cls])"
- q"new _root_.mill.define.EnclosingClass(this.getClass)"
- }
-}
/**
* Models a single node in the Mill build graph, with a list of inputs and a
diff --git a/core/src/mill/util/EnclosingClass.scala b/core/src/mill/util/EnclosingClass.scala
new file mode 100644
index 00000000..a69cc525
--- /dev/null
+++ b/core/src/mill/util/EnclosingClass.scala
@@ -0,0 +1,15 @@
+package mill.util
+
+import sourcecode.Compat.Context
+import language.experimental.macros
+case class EnclosingClass(value: Class[_])
+object EnclosingClass{
+ def apply()(implicit c: EnclosingClass) = c.value
+ implicit def generate: EnclosingClass = macro impl
+ def impl(c: Context): c.Tree = {
+ import c.universe._
+ val cls = c.internal.enclosingOwner.owner.asType.asClass
+ // q"new _root_.mill.define.EnclosingClass(classOf[$cls])"
+ q"new _root_.mill.util.EnclosingClass(this.getClass)"
+ }
+}
diff --git a/core/src/mill/util/ParseArgs.scala b/core/src/mill/util/ParseArgs.scala
index 315edabc..9137923a 100644
--- a/core/src/mill/util/ParseArgs.scala
+++ b/core/src/mill/util/ParseArgs.scala
@@ -5,50 +5,38 @@ import mill.define.{Segment, Segments}
object ParseArgs {
- def apply(scriptArgs: Seq[String])
- : Either[String, (List[(Option[Segments], Segments)], Seq[String])] = {
- val (selectors, args, isMultiSelectors) = extractSelsAndArgs(scriptArgs)
+ def apply(scriptArgs: Seq[String],
+ multiSelect: Boolean): Either[String, (List[(Option[Segments], Segments)], Seq[String])] = {
+ val (selectors, args) = extractSelsAndArgs(scriptArgs, multiSelect)
for {
_ <- validateSelectors(selectors)
expandedSelectors <- EitherOps
.sequence(selectors.map(expandBraces))
.map(_.flatten)
- _ <- validateExpanded(expandedSelectors, isMultiSelectors)
selectors <- EitherOps.sequence(expandedSelectors.map(extractSegments))
} yield (selectors.toList, args)
}
- def extractSelsAndArgs(
- scriptArgs: Seq[String]): (Seq[String], Seq[String], Boolean) = {
- val multiFlags = Seq("--all", "--seq")
- val isMultiSelectors = scriptArgs.headOption.exists(multiFlags.contains)
+ def extractSelsAndArgs(scriptArgs: Seq[String],
+ multiSelect: Boolean): (Seq[String], Seq[String]) = {
- if (isMultiSelectors) {
+ if (multiSelect) {
val dd = scriptArgs.indexOf("--")
- val selectors = (if (dd == -1) scriptArgs
- else scriptArgs.take(dd)).filterNot(multiFlags.contains)
+ val selectors = if (dd == -1) scriptArgs else scriptArgs.take(dd)
val args = if (dd == -1) Seq.empty else scriptArgs.drop(dd + 1)
- (selectors, args, isMultiSelectors)
+ (selectors, args)
} else {
- (scriptArgs.take(1), scriptArgs.drop(1), isMultiSelectors)
+ (scriptArgs.take(1), scriptArgs.drop(1))
}
}
- private def validateSelectors(
- selectors: Seq[String]): Either[String, Unit] = {
+ private def validateSelectors(selectors: Seq[String]): Either[String, Unit] = {
if (selectors.isEmpty || selectors.exists(_.isEmpty))
Left("Selector cannot be empty")
else Right(())
}
- private def validateExpanded(expanded: Seq[String],
- isMulti: Boolean): Either[String, Unit] = {
- if (!isMulti && expanded.length > 1)
- Left("Please use --all flag to run multiple tasks")
- else Right(())
- }
-
def expandBraces(selectorString: String): Either[String, List[String]] = {
parseBraceExpansion(selectorString) match {
case f: Parsed.Failure => Left(s"Parsing exception ${f.msg}")
@@ -139,5 +127,4 @@ object ParseArgs {
}
query.parse(input)
}
-
}
diff --git a/main/src/mill/main/MainModule.scala b/main/src/mill/main/MainModule.scala
index bd8befb3..3ec99f12 100644
--- a/main/src/mill/main/MainModule.scala
+++ b/main/src/mill/main/MainModule.scala
@@ -6,56 +6,70 @@ import pprint.{Renderer, Truncated}
trait MainModule extends mill.Module{
implicit def millDiscover: mill.define.Discover[_]
- implicit def millScoptTargetReads[T] = new mill.main.Tasks.Scopt[T]()
+ implicit def millScoptTasksReads[T] = new mill.main.Tasks.Scopt[T]()
implicit def millScoptEvaluatorReads[T] = new mill.main.EvaluatorScopt[T]()
- def resolve(targets: mill.main.Tasks[Any]*) = mill.T.command{
- targets.flatMap(_.value).foreach(println)
+ def resolve(evaluator: mill.eval.Evaluator[Any], targets: String*) = mill.T.command{
+ RunScript.resolveTargets(evaluator, targets, multiSelect = true) match{
+ case Left(err) => mill.eval.Result.Failure(err)
+ case Right(tasks) => mill.eval.Result.Success(tasks.foreach(println))
+ }
}
- def describe(evaluator: mill.eval.Evaluator[Any],
- targets: mill.main.Tasks[Any]*) = mill.T.command{
- for{
- t <- targets
- target <- t.value
- tree = ReplApplyHandler.pprintTask(target, evaluator)
- val defaults = pprint.PPrinter()
- val renderer = new Renderer(
- defaults.defaultWidth,
- defaults.colorApplyPrefix,
- defaults.colorLiteral,
- defaults.defaultIndent
- )
- val rendered = renderer.rec(tree, 0, 0).iter
- val truncated = new Truncated(rendered, defaults.defaultWidth, defaults.defaultHeight)
- str <- truncated ++ Iterator("\n")
- } {
- print(str)
+
+ def describe(evaluator: mill.eval.Evaluator[Any], targets: String*) = mill.T.command{
+ RunScript.resolveTargets(evaluator, targets, multiSelect = true) match{
+ case Left(err) => mill.eval.Result.Failure(err)
+ case Right(tasks) =>
+ for{
+ task <- tasks
+ tree = ReplApplyHandler.pprintTask(task, evaluator)
+ val defaults = pprint.PPrinter()
+ val renderer = new Renderer(
+ defaults.defaultWidth,
+ defaults.colorApplyPrefix,
+ defaults.colorLiteral,
+ defaults.defaultIndent
+ )
+ val rendered = renderer.rec(tree, 0, 0).iter
+ val truncated = new Truncated(rendered, defaults.defaultWidth, defaults.defaultHeight)
+ str <- truncated ++ Iterator("\n")
+ } {
+ print(str)
+ }
+ mill.eval.Result.Success(())
}
}
+
def all(evaluator: mill.eval.Evaluator[Any],
- targets: mill.main.Tasks[Any]*) = mill.T.command{
- val (watched, res) = RunScript.evaluate(
- evaluator,
- mill.util.Strict.Agg.from(targets.flatMap(_.value))
- )
- Watched((), watched)
+ targets: String*) = mill.T.command{
+ RunScript.evaluateTarget(evaluator, targets, multiSelect = true) match{
+ case Left(err) => mill.eval.Result.Failure(err)
+ case Right((watched, Left(err))) => mill.eval.Result.Failure(err, Some(Watched((), watched)))
+ case Right((watched, Right(res))) => mill.eval.Result.Success(Watched((), watched))
+ }
}
+
def show(evaluator: mill.eval.Evaluator[Any],
- targets: mill.main.Tasks[Any]*) = mill.T.command{
- val (watched, res) = mill.main.RunScript.evaluate(
- // When using `show`, redirect all stdout of the evaluated tasks so the
- // printed JSON is the only thing printed to stdout.
+ targets: String*) = mill.T.command{
+ RunScript.evaluateTarget(
evaluator.copy(
+ // When using `show`, redirect all stdout of the evaluated tasks so the
+ // printed JSON is the only thing printed to stdout.
log = evaluator.log match{
case PrintLogger(c1, c2, o, i, e) => PrintLogger(c1, c2, e, i, e)
case l => l
}
),
- mill.util.Strict.Agg.from(targets.flatMap(_.value))
- )
- for(json <- res.right.get.flatMap(_._2)){
- println(json)
+ targets,
+ multiSelect = false
+ ) match{
+ case Left(err) => mill.eval.Result.Failure(err)
+ case Right((watched, Left(err))) => mill.eval.Result.Failure(err, Some(Watched((), watched)))
+ case Right((watched, Right(res))) =>
+ for(json <- res.flatMap(_._2)){
+ println(json)
+ }
+ mill.eval.Result.Success(Watched((), watched))
}
- Watched((), watched)
}
}
diff --git a/main/src/mill/main/MainScopts.scala b/main/src/mill/main/MainScopts.scala
index acf48d05..f8f99c88 100644
--- a/main/src/mill/main/MainScopts.scala
+++ b/main/src/mill/main/MainScopts.scala
@@ -1,43 +1,20 @@
package mill.main
-import mill.define.ExternalModule
-import mill.eval.{Evaluator, PathRef}
-import mill.util.ParseArgs
+import mill.eval.{Evaluator}
case class Tasks[T](value: Seq[mill.define.NamedTask[T]])
object Tasks{
- class Scopt[T]()
- extends scopt.Read[Tasks[T]] {
- def arity = 0
+ class Scopt[T]() extends scopt.Read[Tasks[T]] {
+ def arity = 1
def reads = s => {
- val rootModule = Evaluator.currentEvaluator.get.rootModule
- val d = rootModule.millDiscover
- val (expanded, leftover) = ParseArgs(Seq(s)).fold(e => throw new Exception(e), identity)
- val resolved = expanded.map {
- case (Some(scoping), segments) =>
- val moduleCls = rootModule.getClass.getClassLoader.loadClass(scoping.render + "$")
- val externalRootModule = moduleCls.getField("MODULE$").get(moduleCls).asInstanceOf[ExternalModule]
- val crossSelectors = segments.value.map {
- case mill.define.Segment.Cross(x) => x.toList.map(_.toString)
- case _ => Nil
- }
- mill.main.Resolve.resolve(segments.value.toList, externalRootModule, d, leftover, crossSelectors.toList, Nil)
- case (None, segments) =>
- val crossSelectors = segments.value.map {
- case mill.define.Segment.Cross(x) => x.toList.map(_.toString)
- case _ => Nil
- }
- mill.main.Resolve.resolve(segments.value.toList, rootModule, d, leftover, crossSelectors.toList, Nil)
- }
- mill.util.EitherOps.sequence(resolved) match {
- case Left(s) => throw new Exception(s)
- case Right(ts) => Tasks(ts.flatten).asInstanceOf[Tasks[T]]
+ RunScript.resolveTargets(Evaluator.currentEvaluator.get, Seq(s), multiSelect = false) match{
+ case Left(err) => throw new Exception(err)
+ case Right(tasks) => Tasks(tasks).asInstanceOf[Tasks[T]]
}
}
}
-
}
class EvaluatorScopt[T]()
diff --git a/main/src/mill/main/RunScript.scala b/main/src/mill/main/RunScript.scala
index bd21a821..5b5eb429 100644
--- a/main/src/mill/main/RunScript.scala
+++ b/main/src/mill/main/RunScript.scala
@@ -52,7 +52,7 @@ object RunScript{
val evaluated = for{
evaluator <- evalRes
- (evalWatches, res) <- Res(evaluateTarget(evaluator, scriptArgs))
+ (evalWatches, res) <- Res(evaluateTarget(evaluator, scriptArgs, multiSelect = false))
} yield {
val alreadyStale = evalWatches.exists(p => p.sig != new PathRef(p.path, p.quick).sig)
// If the file changed between the creation of the original
@@ -129,11 +129,13 @@ object RunScript{
} yield (module, discover)
}
- def evaluateTarget[T](evaluator: Evaluator[T], scriptArgs: Seq[String]) = {
+ def resolveTargets[T](evaluator: Evaluator[T],
+ scriptArgs: Seq[String],
+ multiSelect: Boolean) = {
for {
- parsed <- ParseArgs(scriptArgs)
+ parsed <- ParseArgs(scriptArgs, multiSelect = multiSelect)
(selectors, args) = parsed
- targets <- {
+ taskss <- {
val selected = selectors.map { case (scopedSel, sel) =>
val (rootModule, discover) = scopedSel match{
case None => (evaluator.rootModule, evaluator.discover)
@@ -167,11 +169,14 @@ object RunScript{
}
EitherOps.sequence(selected)
}
- } yield {
- val (watched, res) = evaluate(
- evaluator,
- Agg.from(targets.flatten.distinct)
- )
+ } yield taskss.flatten
+ }
+
+ def evaluateTarget[T](evaluator: Evaluator[T],
+ scriptArgs: Seq[String],
+ multiSelect: Boolean) = {
+ for (targets <- resolveTargets(evaluator, scriptArgs, multiSelect)) yield {
+ val (watched, res) = evaluate(evaluator, Agg.from(targets.distinct))
val watched2 = for{
x <- res.right.toSeq