summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-11-11 20:18:01 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-11-11 20:18:01 -0800
commit37fd5e9de133dc157cdaa6d432700b93324680fe (patch)
treeb30b279b32c48813cce30507473e4fab65c2fe50
parent21325c4dd9e52d6ae6f6b1a8ce606962922100b1 (diff)
downloadmill-37fd5e9de133dc157cdaa6d432700b93324680fe.tar.gz
mill-37fd5e9de133dc157cdaa6d432700b93324680fe.tar.bz2
mill-37fd5e9de133dc157cdaa6d432700b93324680fe.zip
- Smoothed out syntax for defining ivy dependencies
- Made `build.sc` file directly runnable using Ammonite, without any wrapper
-rwxr-xr-x[-rw-r--r--]build.sc34
-rw-r--r--core/src/main/scala/mill/Main.scala81
-rw-r--r--core/src/main/scala/mill/discover/Discovered.scala25
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/Subproject.scala64
-rw-r--r--scalaplugin/src/test/scala/mill/scalaplugin/MetacircularTests.scala16
5 files changed, 123 insertions, 97 deletions
diff --git a/build.sc b/build.sc
index 0ce695c7..15e958ff 100644..100755
--- a/build.sc
+++ b/build.sc
@@ -1,13 +1,13 @@
-import $cp.scalaplugin.target.`scala-2.12`.classes
+#!/usr/bin/env amm
+import $cp.scalaplugin.target.`scala-2.12`.`mill-scalaplugin-assembly-0.1-SNAPSHOT.jar`
import ammonite.ops.pwd
-import coursier.{Dependency => Dep, Module => Mod}
import mill.discover.Discovered
import mill.eval.{Evaluator, PathRef}
-import mill.scalaplugin.Subproject.ScalaDep
+import mill.scalaplugin.Subproject.Dep
import mill.util.OSet
import mill.{T, _}
import mill.scalaplugin.{TestRunner, _}
-
+@main def main(args: String*) = mill.Main(args, Build)
object Build{
trait MillSubproject extends Subproject{
def scalaVersion = T{ "2.12.4" }
@@ -16,19 +16,19 @@ object Build{
object Core extends MillSubproject {
override def compileIvyDeps = T{
- Seq[ScalaDep](
- Dep(Mod("org.scala-lang", "scala-reflect"), scalaVersion(), configuration = "provided")
+ Seq(
+ Dep.Java("org.scala-lang", "scala-reflect", scalaVersion())
)
}
override def ivyDeps = T{
- Seq[ScalaDep](
- ScalaDep(Dep(Mod("com.lihaoyi", "sourcecode"), "0.1.4")),
- ScalaDep(Dep(Mod("com.lihaoyi", "pprint"), "0.5.3")),
- ScalaDep.Point(Dep(Mod("com.lihaoyi", "ammonite"), "1.0.3")),
- ScalaDep(Dep(Mod("com.typesafe.play", "play-json"), "2.6.6")),
- ScalaDep(Dep(Mod("org.scala-sbt", "zinc"), "1.0.3")),
- Dep(Mod("org.scala-sbt", "test-interface"), "1.0")
+ Seq(
+ Dep("com.lihaoyi", "sourcecode", "0.1.4"),
+ Dep("com.lihaoyi", "pprint", "0.5.3"),
+ Dep.Point("com.lihaoyi", "ammonite", "1.0.3"),
+ Dep("com.typesafe.play", "play-json", "2.6.6"),
+ Dep("org.scala-sbt", "zinc", "1.0.3"),
+ Dep.Java("org.scala-sbt", "test-interface", "1.0")
)
}
@@ -40,12 +40,11 @@ object Build{
def basePath = T{ pwd / 'scalaplugin }
override def sources = T{ pwd/'core/'src/'test/'scala }
override def ivyDeps = T{
- Seq[ScalaDep](
- ScalaDep(Dep(Mod("com.lihaoyi", "utest"), "0.6.0"))
+ Seq[Dep](
+ Dep("com.lihaoyi", "utest", "0.6.0")
)
}
def test() = T.command{
- pprint.log(runDepClasspath().map(_.path.toString), height=999)
TestRunner.apply(
"mill.UTestFramework",
runDepClasspath().map(_.path) :+ compiled().path,
@@ -60,4 +59,5 @@ object Build{
override def sources = T{ pwd/'scalaplugin/'src/'main/'scala }
}
}
-@main def main(): Any = Build -> mill.discover.Discovered[Build.type]
+
+
diff --git a/core/src/main/scala/mill/Main.scala b/core/src/main/scala/mill/Main.scala
index 0d316530..3112ec27 100644
--- a/core/src/main/scala/mill/Main.scala
+++ b/core/src/main/scala/mill/Main.scala
@@ -3,18 +3,55 @@ package mill
import ammonite.ops._
import ammonite.util.{Name, Res}
import mill.define.Task
-import mill.discover.{Discovered, NestedEntry}
+import mill.discover.{CommandInfo, Discovered, Info, LabelInfo}
import mill.eval.Evaluator
import mill.util.OSet
import play.api.libs.json.Format
object Main {
+ def apply[T: Discovered](args: Seq[String], obj: T) = {
+ val Seq(selectorString, rest @_*) = args
+ val selector = selectorString.split('.')
+ val discovered = implicitly[Discovered[T]]
+ val consistencyErrors = Discovered.consistencyCheck(obj, discovered)
+ pprint.log(consistencyErrors)
+ if (consistencyErrors.nonEmpty) println("Failed Discovered.consistencyCheck: " + consistencyErrors)
+ else {
+ val mapping = Discovered.mapping(obj)(discovered)
+ val workspacePath = pwd / 'out
+ val evaluator = new Evaluator(workspacePath, mapping)
+ val mainRoutes = discovered.mains.map(x => (x.path :+ x.entryPoint.name, x: Info[T, _]))
+ val targetRoutes = discovered.targets.map(x => (x.path, x: Info[T, _]))
+ val routeList: Seq[(Seq[String], Info[T, _])] = mainRoutes ++ targetRoutes
+ val allRoutes = routeList.toMap[Seq[String], Info[_, _]]
+ allRoutes.get(selector) match{
+ case Some(nestedEntryPoint: CommandInfo[T, _]) =>
+ nestedEntryPoint.invoke(
+ obj,
+ ammonite.main.Scripts.groupArgs(rest.toList)
+ ) match{
+ case error: mill.discover.Router.Result.Error =>
+ println("Failed to evaluate main method: " + error)
+ case mill.discover.Router.Result.Success(target) =>
+ println("Found target! " + target)
+ val evaluated = evaluator.evaluate(OSet(target))
+ pprint.log(evaluated)
+ }
+
+ case Some(labelled: LabelInfo[T, _]) =>
+ val target = labelled.run(obj)
+ val evaluated = evaluator.evaluate(OSet(target))
+ pprint.log(evaluated)
+ case None => println("Unknown selector: " + selector)
+ }
+ }
+
+ }
def main(args: Array[String]): Unit = {
- val List(buildFile, selector0, rest @_*) = args.toList
- pprint.log((buildFile, selector0, rest))
- val selector = selector0.split('.').toList
+ val List(buildFile, rest @_*) = args.toList
+
ammonite.Main().instantiateInterpreter() match{
case Left(problems) => pprint.log(problems)
case Right(interp) =>
@@ -22,42 +59,8 @@ object Main {
if (!result.isSuccess) println(result)
else{
-
val (obj, discovered) = result.asInstanceOf[Res.Success[(Any, Discovered[Any])]].s
- val consistencyErrors = Discovered.consistencyCheck(obj, discovered)
- pprint.log(consistencyErrors)
- if (consistencyErrors.nonEmpty) println("Failed Discovered.consistencyCheck: " + consistencyErrors)
- else {
- val mapping = Discovered.mapping(obj)(discovered)
- val workspacePath = pwd / 'out
- val evaluator = new Evaluator(workspacePath, mapping)
- val mainRoutes = discovered.mains.map(x => (x.path :+ x.entryPoint.name, Left(x)))
- val targetRoutes = discovered.targets.map(x => x._1 -> Right(x))
- val allRoutes = (mainRoutes ++ targetRoutes).toMap[
- Seq[String],
- Either[NestedEntry[Any, _], (Seq[String], Format[_], Any => Task[_])]
- ]
- allRoutes.get(selector) match{
- case Some(Left(nestedEntryPoint)) =>
- nestedEntryPoint.invoke(
- obj,
- ammonite.main.Scripts.groupArgs(rest.toList)
- ) match{
- case error: mill.discover.Router.Result.Error =>
- println("Failed to evaluate main method: " + error)
- case mill.discover.Router.Result.Success(target) =>
- println("Found target! " + target)
- val evaluated = evaluator.evaluate(OSet(target))
- pprint.log(evaluated)
- }
-
- case None => println("Unknown selector: " + selector)
- case Some(Right((_, _, targetFunc))) =>
- val target = targetFunc(obj)
- val evaluated = evaluator.evaluate(OSet(target))
- pprint.log(evaluated)
- }
- }
+ apply(rest, obj)(discovered)
}
}
diff --git a/core/src/main/scala/mill/discover/Discovered.scala b/core/src/main/scala/mill/discover/Discovered.scala
index 0a17dcba..3c89fbc2 100644
--- a/core/src/main/scala/mill/discover/Discovered.scala
+++ b/core/src/main/scala/mill/discover/Discovered.scala
@@ -6,36 +6,41 @@ import play.api.libs.json.Format
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
-
-class Discovered[T](val targets: Seq[(Seq[String], Format[_], T => Task[_])],
- val mains: Seq[NestedEntry[T, _]]){
- def apply(t: T) = targets.map{case (a, f, b) => (a, f, b(t)) }
+sealed trait Info[T, V]
+class Discovered[T](val targets: Seq[LabelInfo[T, _]],
+ val mains: Seq[CommandInfo[T, _]]){
+ def apply(t: T) = targets.map{case LabelInfo(a, f, b) => (a, f, b(t)) }
}
case class Labelled[T](target: Task[T],
format: Format[T],
segments: Seq[String])
+case class LabelInfo[T, V](path: Seq[String],
+ format: Format[V],
+ run: T => Task[V]) extends Info[T, V]
-case class NestedEntry[T, V](path: Seq[String], resolve: T => V, entryPoint: EntryPoint[V]){
+case class CommandInfo[T, V](path: Seq[String],
+ resolve: T => V,
+ entryPoint: EntryPoint[V]) extends Info[T, V]{
def invoke(target: T, groupedArgs: Seq[(String, Option[String])]): Result[Task[Any]] = {
entryPoint.invoke(resolve(target),groupedArgs)
}
}
-object NestedEntry{
+object CommandInfo{
def make[T, V](path: Seq[String], resolve: T => V)
- (entryPoint: EntryPoint[V]) = NestedEntry(path, resolve, entryPoint)
+ (entryPoint: EntryPoint[V]) = CommandInfo(path, resolve, entryPoint)
}
object Discovered {
def consistencyCheck[T](base: T, d: Discovered[T]) = {
val inconsistent = for{
- (path, formatter, targetGen) <- d.targets
+ LabelInfo(path, formatter, targetGen) <- d.targets
if targetGen(base) ne targetGen(base)
} yield path
inconsistent
}
def makeTuple[T, V](path: Seq[String], func: T => Task[V])(implicit f: Format[V]) = {
- (path, f, func)
+ LabelInfo(path, f, func)
}
@@ -102,7 +107,7 @@ object Discovered {
val select = segments.foldLeft[Tree](Ident(arg)) { (prefix, name) =>
q"$prefix.${TermName(name)}"
}
- q"mill.discover.NestedEntry.make(Seq(..$segments), ($arg: $tpe) => $select)($entry)"
+ q"mill.discover.CommandInfo.make(Seq(..$segments), ($arg: $tpe) => $select)($entry)"
}
c.Expr[Discovered[T]](q"""
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/Subproject.scala b/scalaplugin/src/main/scala/mill/scalaplugin/Subproject.scala
index 0408833a..2dcbbe04 100644
--- a/scalaplugin/src/main/scala/mill/scalaplugin/Subproject.scala
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/Subproject.scala
@@ -116,11 +116,11 @@ object Subproject{
def resolveDependencies(repositories: Seq[Repository],
scalaVersion: String,
scalaBinaryVersion: String,
- deps: Seq[ScalaDep]): Seq[PathRef] = {
+ deps: Seq[Dep]): Seq[PathRef] = {
val flattened = deps.map{
- case ScalaDep.Java(dep) => dep
- case ScalaDep.Scala(dep) => dep.copy(module = dep.module.copy(name = dep.module.name + "_" + scalaBinaryVersion))
- case ScalaDep.Point(dep) => dep.copy(module = dep.module.copy(name = dep.module.name + "_" + scalaVersion))
+ case Dep.Java(dep) => dep
+ case Dep.Scala(dep) => dep.copy(module = dep.module.copy(name = dep.module.name + "_" + scalaBinaryVersion))
+ case Dep.Point(dep) => dep.copy(module = dep.module.copy(name = dep.module.name + "_" + scalaVersion))
}.toSet
val start = Resolution(flattened)
@@ -133,22 +133,40 @@ object Subproject{
localArtifacts.map(p => PathRef(Path(p)))
}
- def scalaCompilerIvyDeps(scalaVersion: String) = Seq[ScalaDep](
- Dependency(Module("org.scala-lang", "scala-compiler"), scalaVersion),
- ScalaDep.Scala(Dependency(Module("org.scala-sbt", s"compiler-bridge"), "1.0.3"))
+ def scalaCompilerIvyDeps(scalaVersion: String) = Seq(
+ Dep.Java("org.scala-lang", "scala-compiler", scalaVersion),
+ Dep("org.scala-sbt", s"compiler-bridge", "1.0.3")
)
- def scalaRuntimeIvyDeps(scalaVersion: String) = Seq[ScalaDep](
- Dependency(Module("org.scala-lang", "scala-library"), scalaVersion)
+ def scalaRuntimeIvyDeps(scalaVersion: String) = Seq[Dep](
+ Dep.Java("org.scala-lang", "scala-library", scalaVersion)
)
- sealed trait ScalaDep
- object ScalaDep{
- case class Java(dep: coursier.Dependency) extends ScalaDep
- implicit def default(dep: coursier.Dependency): ScalaDep = new Java(dep)
+ sealed trait Dep
+ object Dep{
+ def apply(org: String, name: String, version: String): Dep = {
+ this(coursier.Dependency(coursier.Module(org, name), version))
+ }
+ case class Java(dep: coursier.Dependency) extends Dep
+ object Java{
+ def apply(org: String, name: String, version: String): Dep = {
+ Java(coursier.Dependency(coursier.Module(org, name), version))
+ }
+ }
+ implicit def default(dep: coursier.Dependency): Dep = new Java(dep)
def apply(dep: coursier.Dependency) = Scala(dep)
- case class Scala(dep: coursier.Dependency) extends ScalaDep
- case class Point(dep: coursier.Dependency) extends ScalaDep
- implicit def formatter: Format[ScalaDep] = new Format[ScalaDep]{
- def writes(o: ScalaDep) = o match{
+ case class Scala(dep: coursier.Dependency) extends Dep
+ object Scala{
+ def apply(org: String, name: String, version: String): Dep = {
+ Scala(coursier.Dependency(coursier.Module(org, name), version))
+ }
+ }
+ case class Point(dep: coursier.Dependency) extends Dep
+ object Point{
+ def apply(org: String, name: String, version: String): Dep = {
+ Point(coursier.Dependency(coursier.Module(org, name), version))
+ }
+ }
+ implicit def formatter: Format[Dep] = new Format[Dep]{
+ def writes(o: Dep) = o match{
case Java(dep) => Json.obj("Java" -> Json.toJson(dep))
case Scala(dep) => Json.obj("Scala" -> Json.toJson(dep))
case Point(dep) => Json.obj("PointScala" -> Json.toJson(dep))
@@ -157,9 +175,9 @@ object Subproject{
def reads(json: JsValue) = json match{
case obj: JsObject =>
obj.fields match{
- case Seq(("Java", dep)) => Json.fromJson[coursier.Dependency](dep).map(Java)
- case Seq(("Scala", dep)) => Json.fromJson[coursier.Dependency](dep).map(Scala)
- case Seq(("PointScala", dep)) => Json.fromJson[coursier.Dependency](dep).map(Point)
+ case Seq(("Java", dep)) => Json.fromJson[coursier.Dependency](dep).map(Java(_))
+ case Seq(("Scala", dep)) => Json.fromJson[coursier.Dependency](dep).map(Scala(_))
+ case Seq(("PointScala", dep)) => Json.fromJson[coursier.Dependency](dep).map(Point(_))
case _ => JsError("Invalid JSON object to parse ScalaDep")
}
@@ -175,9 +193,9 @@ trait Subproject extends Cacher{
def scalaVersion: T[String]
def scalaBinaryVersion = T{ scalaVersion().split('.').dropRight(1).mkString(".") }
- def ivyDeps = T{ Seq[ScalaDep]() }
- def compileIvyDeps = T{ Seq[ScalaDep]() }
- def runIvyDeps = T{ Seq[ScalaDep]() }
+ def ivyDeps = T{ Seq[Dep]() }
+ def compileIvyDeps = T{ Seq[Dep]() }
+ def runIvyDeps = T{ Seq[Dep]() }
def basePath: T[Path]
val repositories: Seq[Repository] = Seq(
diff --git a/scalaplugin/src/test/scala/mill/scalaplugin/MetacircularTests.scala b/scalaplugin/src/test/scala/mill/scalaplugin/MetacircularTests.scala
index 21640e6b..8159b8ce 100644
--- a/scalaplugin/src/test/scala/mill/scalaplugin/MetacircularTests.scala
+++ b/scalaplugin/src/test/scala/mill/scalaplugin/MetacircularTests.scala
@@ -5,7 +5,7 @@ import ammonite.ops.pwd
import coursier.{Dependency => Dep, Module => Mod}
import mill.discover.Discovered
import mill.eval.{Evaluator, PathRef}
-import mill.scalaplugin.Subproject.ScalaDep
+import mill.scalaplugin.Subproject.Dep
import mill.util.OSet
import utest._
@@ -13,18 +13,18 @@ object MetacircularTests extends TestSuite{
object Core extends Subproject {
def scalaVersion = T{ "2.12.4" }
override def compileIvyDeps = T{
- super.compileIvyDeps() ++ Seq[ScalaDep](
+ super.compileIvyDeps() ++ Seq[Dep](
Dep(Mod("org.scala-lang", "scala-reflect"), scalaVersion(), configuration = "provided")
)
}
override def ivyDeps = T{
- super.ivyDeps() ++ Seq[ScalaDep](
- ScalaDep(Dep(Mod("com.lihaoyi", "sourcecode"), "0.1.4")),
- ScalaDep(Dep(Mod("com.lihaoyi", "pprint"), "0.5.3")),
- ScalaDep.Point(Dep(Mod("com.lihaoyi", "ammonite"), "1.0.3")),
- ScalaDep(Dep(Mod("com.typesafe.play", "play-json"), "2.6.6")),
- ScalaDep(Dep(Mod("org.scala-sbt", "zinc"), "1.0.3"))
+ super.ivyDeps() ++ Seq[Dep](
+ Dep(Dep(Mod("com.lihaoyi", "sourcecode"), "0.1.4")),
+ Dep(Dep(Mod("com.lihaoyi", "pprint"), "0.5.3")),
+ Dep.Point(Dep(Mod("com.lihaoyi", "ammonite"), "1.0.3")),
+ Dep(Dep(Mod("com.typesafe.play", "play-json"), "2.6.6")),
+ Dep(Dep(Mod("org.scala-sbt", "zinc"), "1.0.3"))
)
}