From 7cd18fd936b95410274be031a8231e5a3d9866a4 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sat, 6 Jan 2018 23:25:29 -0800 Subject: First pass at implicitly propagating a `def basePath: Path` up the `Module` hierarchy, which each module receives and extends. One constraint is that now must define your abstract modules as `trait`s rather than `class`es, or otherwise add an implicit `ctx: ModuleCtx` parameter to your class definition. So far this lets us remove some explicit `basePath` definitions in `build.sc`. Proper handling of `basePath` in `CrossModule`s is future work --- build.sc | 12 --- core/src/main/scala/mill/define/Cross.scala | 10 ++- core/src/main/scala/mill/define/Task.scala | 35 +++++++-- core/src/main/scala/mill/main/MainRunner.scala | 14 ++-- core/src/main/scala/mill/package.scala | 3 + .../src/test/scala/mill/define/BasePathTests.scala | 42 ++++++++++ core/src/test/scala/mill/define/CacherTests.scala | 6 +- .../test/scala/mill/define/MacroErrorTests.scala | 2 +- .../scala/mill/discover/CrossModuleTests.scala | 31 ++++---- .../test/scala/mill/discover/DiscoveredTests.scala | 7 +- .../src/test/scala/mill/eval/EvaluationTests.scala | 2 +- .../test/scala/mill/eval/JavaCompileJarTests.scala | 4 +- core/src/test/scala/mill/main/MainTests.scala | 26 +++---- core/src/test/scala/mill/util/TestGraphs.scala | 91 +++++++++++----------- core/src/test/scala/mill/util/TestUtil.scala | 16 +++- integration/src/test/resource/acyclic/build.sc | 2 +- .../src/test/resource/better-files/build.sc | 9 +-- integration/src/test/resource/jawn/build.sc | 40 +++++----- .../mill/integration/IntegrationTestSuite.scala | 2 +- .../scala/mill/scalajslib/HelloJSWorldTests.scala | 8 +- scalalib/src/main/scala/mill/scalalib/Module.scala | 4 +- .../test/scala/mill/scalalib/HelloWorldTests.scala | 16 ++-- 22 files changed, 228 insertions(+), 154 deletions(-) create mode 100644 core/src/test/scala/mill/define/BasePathTests.scala diff --git a/build.sc b/build.sc index 16642f6e..490fe55f 100755 --- a/build.sc +++ b/build.sc @@ -10,7 +10,6 @@ import mill.modules.Jvm.createAssembly object moduledefs extends SbtModule{ def scalaVersion = "2.12.4" - def basePath = pwd / 'moduledefs def ivyDeps = Seq( Dep.Java("org.scala-lang", "scala-compiler", scalaVersion()), Dep("com.lihaoyi", "sourcecode", "0.1.4") @@ -59,8 +58,6 @@ object core extends MillModule { Dep.Java("org.scala-sbt", "test-interface", "1.0") ) - def basePath = pwd / 'core - def generatedSources = T{ mkdir(T.ctx().dest) shared.generateSources(T.ctx().dest) @@ -87,13 +84,7 @@ case class BridgeModule(crossVersion: String) extends PublishModule { def publishName = "mill-bridge" def publishVersion = "0.1" - def basePath = pwd / 'bridge def scalaVersion = crossVersion - def sources = T.source { - val path = basePath / 'src - mkdir(path) - path - } def allSources = T{ Seq(PathRef(shared.downloadBridgeSource(T.ctx().dest, crossVersion))) } @@ -116,7 +107,6 @@ case class BridgeModule(crossVersion: String) extends PublishModule { object scalalib extends MillModule { def projectDeps = Seq(core) - def basePath = pwd / 'scalalib def bridgeCompiles = mill.define.Task.traverse(bridges.items)(_._2.compile) def testArgs = T{ @@ -146,7 +136,6 @@ case class JsBridgeModule(scalajsBinary: String) extends MillModule{ object scalajslib extends MillModule { def projectDeps = Seq(scalalib) - def basePath = pwd / 'scalajslib def bridgeClasspath(runDepClasspath: Seq[PathRef], classes: PathRef) = (runDepClasspath :+ classes).map(_.path).mkString(File.pathSeparator) @@ -171,7 +160,6 @@ def testRepos = T{ object integration extends MillModule{ def projectDeps = Seq(moduledefs, scalalib, scalajslib) - def basePath = pwd / 'integration def testArgs = T{ for((k, v) <- testRepos()) yield s"-D$k=$v" } diff --git a/core/src/main/scala/mill/define/Cross.scala b/core/src/main/scala/mill/define/Cross.scala index 90a383a6..26eef933 100644 --- a/core/src/main/scala/mill/define/Cross.scala +++ b/core/src/main/scala/mill/define/Cross.scala @@ -28,4 +28,12 @@ object Cross{ class CrossModule[T, V](constructor: T => V, cases: T*) (implicit e: sourcecode.Enclosing, l: sourcecode.Line) -extends Cross[V](cases.toList.map(x => (List(x), constructor(x)))) \ No newline at end of file +extends Cross[V](cases.toList.map(x => (List(x), constructor(x)))) + +class CrossModule2[T1, T2, V](constructor: (T1, T2) => V, cases: (T1, T2)*) + (implicit e: sourcecode.Enclosing, l: sourcecode.Line) +extends Cross[V](cases.toList.map(x => (List(x._2, x._1), constructor(x._1, x._2)))) + +class CrossModule3[T1, T2, T3, V](constructor: (T1, T2, T3) => V, cases: (T1, T2, T3)*) + (implicit e: sourcecode.Enclosing, l: sourcecode.Line) +extends Cross[V](cases.toList.map(x => (List(x._3, x._2, x._1), constructor(x._1, x._2, x._3)))) \ No newline at end of file diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala index 6ee9c606..0704c7c8 100644 --- a/core/src/main/scala/mill/define/Task.scala +++ b/core/src/main/scala/mill/define/Task.scala @@ -1,6 +1,7 @@ package mill.define import ammonite.main.Router.Overrides +import ammonite.ops.Path import mill.define.Applicative.Applyable import mill.eval.{PathRef, Result} import mill.util.Ctx @@ -361,10 +362,9 @@ class Input[T](t: Task[T], def evaluate(args: Ctx) = args[T](0) override def sideHash = util.Random.nextInt() } - +case class BasePath(value: Path) object Task { - trait TaskModule extends Module { def defaultCommandName(): String } @@ -375,14 +375,37 @@ object Task { * instantiation site so they can capture the enclosing/line information of * the concrete instance. */ - class Module(implicit millModuleEnclosing0: sourcecode.Enclosing, - millModuleLine0: sourcecode.Line) extends mill.moduledefs.Cacher{ + class Module(implicit ctx: Module.Ctx) extends mill.moduledefs.Cacher{ // Ensure we do not propagate the implicit parameters as implicits within // the body of any inheriting class/trait/objects, as it would screw up any // one else trying to use sourcecode.{Enclosing,Line} to capture debug info - val millModuleEnclosing = millModuleEnclosing0 - val millModuleLine = millModuleLine0 + val millModuleEnclosing = ctx.millModuleEnclosing0 + val millModuleLine = ctx.millModuleLine0 + def basePath: Path = ctx.millModuleBasePath0.value / ctx.millName0.value + implicit def millModuleBasePath: BasePath = BasePath(basePath) + } + object Module{ + case class Ctx(millModuleEnclosing0: sourcecode.Enclosing, + millModuleLine0: sourcecode.Line, + millName0: sourcecode.Name, + millModuleBasePath0: BasePath) + object Ctx{ + implicit def make(implicit millModuleEnclosing0: sourcecode.Enclosing, + millModuleLine0: sourcecode.Line, + millName0: sourcecode.Name, + millModuleBasePath0: BasePath): Ctx = Ctx( + millModuleEnclosing0, + millModuleLine0, + millName0, + millModuleBasePath0 + ) + } } + class BaseModule(basePath: Path) + (implicit millModuleEnclosing0: sourcecode.Enclosing, + millModuleLine0: sourcecode.Line, + millName0: sourcecode.Name) + extends Module()(Module.Ctx.make(implicitly, implicitly, implicitly, BasePath(basePath))) class Task0[T](t: T) extends Task[T]{ lazy val t0 = t diff --git a/core/src/main/scala/mill/main/MainRunner.scala b/core/src/main/scala/mill/main/MainRunner.scala index 76e2d069..322795ea 100644 --- a/core/src/main/scala/mill/main/MainRunner.scala +++ b/core/src/main/scala/mill/main/MainRunner.scala @@ -75,15 +75,12 @@ class MainRunner(config: ammonite.main.Cli.Config, } override def initMain(isRepl: Boolean) = { super.initMain(isRepl).copy( - scriptCodeWrapper = mill.main.MainRunner.CustomCodeWrapper, + scriptCodeWrapper = CustomCodeWrapper, // Ammonite does not properly forward the wd from CliConfig to Main, so // force forward it outselves wd = config.wd ) } -} - -object MainRunner{ object CustomCodeWrapper extends Preprocessor.CodeWrapper { def top(pkgName: Seq[Name], imports: Imports, indexedWrapperName: Name) = { val wrapName = indexedWrapperName.backticked @@ -93,14 +90,17 @@ object MainRunner{ |$imports |import mill._ | - |object $wrapName extends $wrapName{ + |object $wrapName extends mill.define.Task.BaseModule(ammonite.ops.Path(${pprint.Util.literalize(config.wd.toString)})) with $wrapName{ + | // Make sure we don't include the `build` wrapper-object's name in + | // the `basePath`s of our build + | override def basePath = super.basePath / ammonite.ops.up | // Stub to make sure Ammonite has something to call after it evaluates a script, | // even if it does nothing... | def $$main() = Iterator[String]() | lazy val mapping = mill.discover.Discovered.make[$wrapName].mapping(this) |} | - |sealed abstract class $wrapName extends mill.Module{ + |sealed trait $wrapName extends mill.Module{ |""".stripMargin } @@ -112,4 +112,4 @@ object MainRunner{ "\n}" } } -} \ No newline at end of file +} diff --git a/core/src/main/scala/mill/package.scala b/core/src/main/scala/mill/package.scala index b7332f9e..f833b82c 100644 --- a/core/src/main/scala/mill/package.scala +++ b/core/src/main/scala/mill/package.scala @@ -6,5 +6,8 @@ package object mill extends JsonFormatters{ val PathRef = mill.eval.PathRef type PathRef = mill.eval.PathRef type Module = define.Task.Module + val Module = define.Task.Module type CrossModule[T, V] = define.CrossModule[T, V] + type CrossModule2[T1, T2, V] = define.CrossModule2[T1, T2, V] + type CrossModule3[T1, T2, T3, V] = define.CrossModule3[T1, T2, T3, V] } diff --git a/core/src/test/scala/mill/define/BasePathTests.scala b/core/src/test/scala/mill/define/BasePathTests.scala new file mode 100644 index 00000000..67b6dc3c --- /dev/null +++ b/core/src/test/scala/mill/define/BasePathTests.scala @@ -0,0 +1,42 @@ +package mill.define + +import mill.util.TestGraphs +import utest._ +import ammonite.ops.pwd +object BasePathTests extends TestSuite{ + val testGraphs = new TestGraphs + val tests = Tests{ + 'singleton - { + assert( + testGraphs.singleton.millModuleBasePath == + BasePath(pwd / "mill.util.TestGraphs#singleton" / "singleton") + ) + } + 'separateGroups - { + assert( + TestGraphs.separateGroups.millModuleBasePath == + BasePath(pwd / "mill.util.TestGraphs.separateGroups" / "separateGroups") + ) + } + 'TraitWithModuleObject - { + assert( + TestGraphs.TraitWithModuleObject.TraitModule.millModuleBasePath == + BasePath(pwd / "mill.util.TestGraphs.TraitWithModuleObject" / "TraitWithModuleObject" / "TraitModule") + ) + } + 'nestedModuleNested - { + assert( + TestGraphs.nestedModule.nested.millModuleBasePath == + BasePath(pwd / "mill.util.TestGraphs.nestedModule" / "nestedModule" / "nested") + ) + } + 'nestedModuleInstance - { + assert( + TestGraphs.nestedModule.classInstance.millModuleBasePath == + BasePath(pwd / "mill.util.TestGraphs.nestedModule" / "nestedModule" / "classInstance") + ) + } + + } +} + diff --git a/core/src/test/scala/mill/define/CacherTests.scala b/core/src/test/scala/mill/define/CacherTests.scala index e46c0390..faf274f2 100644 --- a/core/src/test/scala/mill/define/CacherTests.scala +++ b/core/src/test/scala/mill/define/CacherTests.scala @@ -2,7 +2,7 @@ package mill.define import mill.discover.Discovered import mill.eval.Evaluator -import mill.util.{DummyLogger, OSet} +import mill.util.{DummyLogger, OSet, TestUtil} import mill.T import mill.eval.Result.Success import utest._ @@ -10,7 +10,7 @@ import utest.framework.TestPath object CacherTests extends TestSuite{ object Base extends Base - trait Base extends Task.Module{ + trait Base extends TestUtil.BaseModule{ def value = T{ 1 } def result = T{ Success(1) } } @@ -19,7 +19,7 @@ object CacherTests extends TestSuite{ def value = T{ super.value() + 2} def overriden = T{ super.value()} } - object Terminal extends Terminal + object Terminal extends Terminal trait Terminal extends Middle{ override def value = T{ super.value() + 4} } diff --git a/core/src/test/scala/mill/define/MacroErrorTests.scala b/core/src/test/scala/mill/define/MacroErrorTests.scala index fd0116d8..7c1bd3a1 100644 --- a/core/src/test/scala/mill/define/MacroErrorTests.scala +++ b/core/src/test/scala/mill/define/MacroErrorTests.scala @@ -11,7 +11,7 @@ object MacroErrorTests extends TestSuite{ val expectedMsg = "T{} members must be defs defined in a Cacher class/trait/object body" - val err = compileError("object Foo extends Module{ val x = T{1} }") + val err = compileError("object Foo extends TestUtil.BaseModule{ val x = T{1} }") assert(err.msg == expectedMsg) } diff --git a/core/src/test/scala/mill/discover/CrossModuleTests.scala b/core/src/test/scala/mill/discover/CrossModuleTests.scala index e0a7a1a0..6ae3d622 100644 --- a/core/src/test/scala/mill/discover/CrossModuleTests.scala +++ b/core/src/test/scala/mill/discover/CrossModuleTests.scala @@ -7,17 +7,17 @@ import mill.discover.Mirror.Segment.Label import mill.util.TestUtil.test import utest._ import mill.util.TestGraphs._ +import mill.util.TestUtil object CrossModuleTests extends TestSuite{ val tests = Tests{ 'cross - { - object outer{ - val crossed = - for(n <- Cross("2.10.6", "2.11.8", "2.12.4")) - yield new Module{ - def scalaVersion = n - } + object outer extends TestUtil.BaseModule { + object crossed extends mill.CrossModule(CrossedModule, "2.10.6", "2.11.8", "2.12.4") + case class CrossedModule(n: String) extends Module{ + def scalaVersion = n + } } val discovered = Discovered.make[outer.type] @@ -36,15 +36,16 @@ object CrossModuleTests extends TestSuite{ } } 'doubleCross - { - object outer{ - val crossed = - for{ - platform <- Cross("", "sjs0.6", "native0.3") - scalaVersion <- Cross("2.10.6", "2.11.8", "2.12.4") - if !(platform == "native0.3" && scalaVersion == "2.10.6") - } yield new Module{ - def suffix = Seq(scalaVersion, platform).filter(_.nonEmpty).map("_"+_).mkString - } + object outer extends TestUtil.BaseModule { + val crossMatrix = for{ + platform <- Seq("", "sjs0.6", "native0.3") + scalaVersion <- Seq("2.10.6", "2.11.8", "2.12.4") + if !(platform == "native0.3" && scalaVersion == "2.10.6") + } yield (platform, scalaVersion) + object crossed extends mill.CrossModule2(CrossModule, crossMatrix:_*) + case class CrossModule(platform: String, scalaVersion: String) extends mill.Module{ + def suffix = Seq(scalaVersion, platform).filter(_.nonEmpty).map("_"+_).mkString + } } val Some((gen, innerMirror)) = Discovered.make[outer.type] diff --git a/core/src/test/scala/mill/discover/DiscoveredTests.scala b/core/src/test/scala/mill/discover/DiscoveredTests.scala index 1a22e901..d141352e 100644 --- a/core/src/test/scala/mill/discover/DiscoveredTests.scala +++ b/core/src/test/scala/mill/discover/DiscoveredTests.scala @@ -7,6 +7,7 @@ import utest._ import mill.{Module, T} import mill.discover.Mirror.Segment.Label import mill.util.TestGraphs.{TraitWithModuleObject, nestedModule} +import mill.util.TestUtil object DiscoveredTests extends TestSuite{ val tests = Tests{ @@ -49,7 +50,7 @@ object DiscoveredTests extends TestSuite{ } 'commands - { - object outer extends mill.Module{ + object outer extends TestUtil.BaseModule{ def hello() = T.command{ println("Hello") } @@ -91,7 +92,7 @@ object DiscoveredTests extends TestSuite{ 'unserializableTarget - { - object outer extends Module { + object outer extends TestUtil.BaseModule { val error = compileError("def single = mill.T{ new InputStreamReader(System.in) }") } @@ -103,7 +104,7 @@ object DiscoveredTests extends TestSuite{ } 'unreadableCommand - { - object outer extends Module { + object outer extends TestUtil.BaseModule { def single(in: InputStreamReader) = mill.T.command{ println(123) } } diff --git a/core/src/test/scala/mill/eval/EvaluationTests.scala b/core/src/test/scala/mill/eval/EvaluationTests.scala index fb3f6b97..54e184b5 100644 --- a/core/src/test/scala/mill/eval/EvaluationTests.scala +++ b/core/src/test/scala/mill/eval/EvaluationTests.scala @@ -212,7 +212,7 @@ object EvaluationTests extends TestSuite{ // up middle -- down // / // right - object build extends Module{ + object build extends TestUtil.BaseModule{ var leftCount = 0 var rightCount = 0 var middleCount = 0 diff --git a/core/src/test/scala/mill/eval/JavaCompileJarTests.scala b/core/src/test/scala/mill/eval/JavaCompileJarTests.scala index ca317a06..47e09ec3 100644 --- a/core/src/test/scala/mill/eval/JavaCompileJarTests.scala +++ b/core/src/test/scala/mill/eval/JavaCompileJarTests.scala @@ -7,7 +7,7 @@ import mill.discover.Discovered import mill.modules.Jvm import mill.util.Ctx.DestCtx import mill.{Module, T} -import mill.util.{DummyLogger, OSet} +import mill.util.{DummyLogger, OSet, TestUtil} import utest._ import mill._ @@ -28,7 +28,7 @@ object JavaCompileJarTests extends TestSuite{ mkdir(pwd / 'target / 'workspace / 'javac) cp(javacSrcPath, javacDestPath) - object Build extends Module{ + object Build extends TestUtil.BaseModule{ def sourceRootPath = javacDestPath / 'src def resourceRootPath = javacDestPath / 'resources diff --git a/core/src/test/scala/mill/main/MainTests.scala b/core/src/test/scala/mill/main/MainTests.scala index 3e0f606b..320731fa 100644 --- a/core/src/test/scala/mill/main/MainTests.scala +++ b/core/src/test/scala/mill/main/MainTests.scala @@ -47,19 +47,19 @@ object MainTests extends TestSuite{ 'neg2 - check(mapping(singleCross), "cross[doesntExist].doesntExist", Left("Cannot resolve cross cross[doesntExist]")) 'neg2 - check(mapping(singleCross), "cross[doesntExist].suffix", Left("Cannot resolve cross cross[doesntExist]")) } - 'double - { - - 'pos1 - check( - mapping(doubleCross), - "cross[jvm,210].suffix", - Right(doubleCross.cross("jvm", "210").suffix) - ) - 'pos2 - check( - mapping(doubleCross), - "cross[jvm,211].suffix", - Right(doubleCross.cross("jvm", "211").suffix) - ) - } +// 'double - { +// +// 'pos1 - check( +// mapping(doubleCross), +// "cross[jvm,210].suffix", +// Right(doubleCross.cross("jvm", "210").suffix) +// ) +// 'pos2 - check( +// mapping(doubleCross), +// "cross[jvm,211].suffix", +// Right(doubleCross.cross("jvm", "211").suffix) +// ) +// } 'nested - { 'indirect - { 'pos1 - check( diff --git a/core/src/test/scala/mill/util/TestGraphs.scala b/core/src/test/scala/mill/util/TestGraphs.scala index 25c806fa..64fc4737 100644 --- a/core/src/test/scala/mill/util/TestGraphs.scala +++ b/core/src/test/scala/mill/util/TestGraphs.scala @@ -1,5 +1,6 @@ package mill.util import TestUtil.test +import mill.define.CrossModule import mill.{Module, T} /** @@ -15,18 +16,18 @@ import mill.{Module, T} */ class TestGraphs(){ // single - object singleton extends Module{ + object singleton extends TestUtil.BaseModule { val single = test() } // up---down - object pair extends Module { + object pair extends TestUtil.BaseModule{ val up = test() val down = test(up) } // up---o---down - object anonTriple extends Module{ + object anonTriple extends TestUtil.BaseModule { val up = test() val down = test(test.anon(up)) } @@ -36,7 +37,7 @@ class TestGraphs(){ // up down // \ / // right - object diamond extends Module{ + object diamond extends TestUtil.BaseModule { val up = test() val left = test(up) val right = test(up) @@ -48,12 +49,12 @@ class TestGraphs(){ // up down // \ / // o - object anonDiamond extends Module{ + object anonDiamond extends TestUtil.BaseModule { val up = test() val down = test(test.anon(up), test.anon(up)) } - object defCachedDiamond extends Module{ + object defCachedDiamond extends TestUtil.BaseModule { def up = T{ test() } def left = T{ test(up) } def right = T{ test(up) } @@ -61,14 +62,14 @@ class TestGraphs(){ } - object borkedCachedDiamond2 extends Module { + object borkedCachedDiamond2 extends TestUtil.BaseModule { def up = test() def left = test(up) def right = test(up) def down = test(left, right) } - object borkedCachedDiamond3 extends Module { + object borkedCachedDiamond3 extends TestUtil.BaseModule { def up = test() def left = test(up) def right = test(up) @@ -86,7 +87,7 @@ class TestGraphs(){ // o o---F---o // / / // o--B o - object bigSingleTerminal extends Module{ + object bigSingleTerminal extends TestUtil.BaseModule { val a = test(test.anon(), test.anon()) val b = test(test.anon()) val e = { @@ -113,7 +114,7 @@ object TestGraphs{ // task1 -------- right // _/ // change - task2 - object separateGroups extends Module{ + object separateGroups extends TestUtil.BaseModule { val task1 = T.task{ 1 } def left = T{ task1() } val change = test() @@ -125,7 +126,7 @@ object TestGraphs{ // _ left _ // / \ // task -------- right - object triangleTask extends Module{ + object triangleTask extends TestUtil.BaseModule { val task = T.task{ 1 } def left = T{ task() } def right = T{ task() + left() + 1 } @@ -135,7 +136,7 @@ object TestGraphs{ // _ left // / // task -------- right - object multiTerminalGroup extends Module{ + object multiTerminalGroup extends TestUtil.BaseModule { val task = T.task{ 1 } def left = T{ task() } def right = T{ task() } @@ -144,7 +145,7 @@ object TestGraphs{ // _ left _____________ // / \ \ // task1 -------- right ----- task2 - object multiTerminalBoundary extends Module{ + object multiTerminalBoundary extends TestUtil.BaseModule { val task1 = T.task{ 1 } def left = T{ task1() } def right = T{ task1() + left() + 1 } @@ -152,13 +153,13 @@ object TestGraphs{ } - class CanNest extends Module{ + trait CanNest extends Module{ def single = T{ 1 } def invisible: Any = T{ 2 } def invisible2: mill.define.Task[Int] = T{ 3 } def invisible3: mill.define.Task[_] = T{ 4 } } - object nestedModule extends Module{ + object nestedModule extends TestUtil.BaseModule { def single = T{ 5 } def invisible: Any = T{ 6 } object nested extends Module{ @@ -166,7 +167,7 @@ object TestGraphs{ def invisible: Any = T{ 8 } } - val classInstance = new CanNest + object classInstance extends CanNest } @@ -174,7 +175,7 @@ object TestGraphs{ def foo = T{ Seq("base") } } - object canOverrideSuper extends BaseModule { + object canOverrideSuper extends TestUtil.BaseModule with BaseModule { override def foo = T{ super.foo() ++ Seq("object") } } @@ -187,46 +188,44 @@ object TestGraphs{ // Make sure nested objects inherited from traits work - object TraitWithModuleObject extends TraitWithModule + object TraitWithModuleObject extends TestUtil.BaseModule with TraitWithModule - object singleCross{ - val cross = - for(scalaVersion <- mill.define.Cross("210", "211", "212")) - yield new mill.Module{ - def suffix = T{ scalaVersion } - } + object singleCross extends TestUtil.BaseModule { + object cross extends mill.CrossModule(CrossModule, "210", "211", "212") + case class CrossModule(scalaVersion: String) extends Module{ + def suffix = T{ scalaVersion } + } } - object doubleCross{ - val cross = for{ - scalaVersion <- mill.define.Cross("210", "211", "212") - platform <- mill.define.Cross("jvm", "js", "native") + object doubleCross extends TestUtil.BaseModule { + val crossMatrix = for{ + scalaVersion <- Seq("210", "211", "212") + platform <- Seq("jvm", "js", "native") if !(platform == "native" && scalaVersion != "212") - } yield new Module{ + } yield (scalaVersion, platform) + object cross extends mill.CrossModule2(CrossModule, crossMatrix:_*) + case class CrossModule(scalaVersion: String, platform: String) extends Module{ def suffix = T{ scalaVersion + "_" + platform } } } - object indirectNestedCrosses{ - val cross = mill.define.Cross("210", "211", "212").map(new cross(_)) - class cross(scalaVersion: String) extends mill.Module{ - val cross2 = - for(platform <- mill.define.Cross("jvm", "js", "native")) - yield new mill.Module{ - def suffix = T{ scalaVersion + "_" + platform } - } + object indirectNestedCrosses extends TestUtil.BaseModule { + object cross extends mill.CrossModule(CrossModule, "210", "211", "212") + case class CrossModule(scalaVersion: String) extends mill.Module{ + object cross2 extends mill.CrossModule(CrossModule, "jvm", "js", "native") + case class CrossModule(platform: String) extends mill.Module{ + def suffix = T{ scalaVersion + "_" + platform } + } } } - object nestedCrosses{ - val cross = - for(scalaVersion <- mill.define.Cross("210", "211", "212")) - yield new mill.Module{ - val cross2 = - for(platform <- mill.define.Cross("jvm", "js", "native")) - yield new mill.Module{ - def suffix = T{ scalaVersion + "_" + platform } - } + object nestedCrosses extends TestUtil.BaseModule { + object cross extends mill.CrossModule(CrossModule, "210", "211", "212") + case class CrossModule(scalaVersion: String) extends mill.Module{ + object cross2 extends mill.CrossModule(CrossModule, "jvm", "js", "native") + case class CrossModule(platform: String) extends mill.Module{ + def suffix = T{ scalaVersion + "_" + platform } } + } } } diff --git a/core/src/test/scala/mill/util/TestUtil.scala b/core/src/test/scala/mill/util/TestUtil.scala index 0d28fcf6..8cb1c375 100644 --- a/core/src/test/scala/mill/util/TestUtil.scala +++ b/core/src/test/scala/mill/util/TestUtil.scala @@ -1,13 +1,27 @@ package mill.util import ammonite.main.Router.Overrides -import mill.define.{Caller, Target, Task} +import ammonite.ops.Path +import mill.define.Task.Module +import mill.define.{BasePath, Caller, Target, Task} import mill.eval.Result import utest.assert +import utest.framework.TestPath import scala.collection.mutable object TestUtil { + class BaseModule(implicit millModuleEnclosing0: sourcecode.Enclosing, + millModuleLine0: sourcecode.Line, + millName0: sourcecode.Name) + extends Module()( + Module.Ctx.make( + implicitly, + implicitly, + implicitly, + BasePath(ammonite.ops.pwd / millModuleEnclosing0.value) + ) + ) object test{ def anon(inputs: Task[Int]*) = new Test(inputs) diff --git a/integration/src/test/resource/acyclic/build.sc b/integration/src/test/resource/acyclic/build.sc index ec338e9f..f1381c7e 100644 --- a/integration/src/test/resource/acyclic/build.sc +++ b/integration/src/test/resource/acyclic/build.sc @@ -5,7 +5,7 @@ import mill.scalalib.publish.{PomSettings, License, Developer, SCM} object acyclic extends CrossModule(AcyclicModule, "2.10.6", "2.11.8", "2.12.3", "2.12.4") case class AcyclicModule(crossVersion: String) extends SbtModule with PublishModule { - def basePath = ammonite.ops.pwd / 'target / 'workspace / 'acyclic + def basePath = super.basePath / ammonite.ops.up def artifactName = "acyclic" def publishVersion = "0.1.7" diff --git a/integration/src/test/resource/better-files/build.sc b/integration/src/test/resource/better-files/build.sc index bfb7f89c..ace8f766 100644 --- a/integration/src/test/resource/better-files/build.sc +++ b/integration/src/test/resource/better-files/build.sc @@ -61,25 +61,20 @@ trait BetterFilesModule extends SbtModule{ } } -object core extends BetterFilesModule{ - def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'core -} +object core extends BetterFilesModule object akka extends BetterFilesModule{ def projectDeps = Seq(core) - def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'akka def ivyDeps = Seq(Dep("com.typesafe.akka", "akka-actor", "2.5.6")) } -object shapelessScanner extends BetterFilesModule{ +object shapeless extends BetterFilesModule{ def projectDeps = Seq(core) - def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'shapeless def ivyDeps = Seq(Dep("com.chuusai", "shapeless", "2.3.2")) } object benchmarks extends BetterFilesModule{ def projectDeps = Seq(core) - def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'benchmarks def ivyDeps = Seq( Dep.Java("commons-io", "commons-io", "2.5") // "fastjavaio" % "fastjavaio" % "1.0" from "https://github.com/williamfiset/FastJavaIO/releases/download/v1.0/fastjavaio.jar" diff --git a/integration/src/test/resource/jawn/build.sc b/integration/src/test/resource/jawn/build.sc index 75dfeaa1..074e30f9 100644 --- a/integration/src/test/resource/jawn/build.sc +++ b/integration/src/test/resource/jawn/build.sc @@ -4,6 +4,8 @@ import mill.scalalib.{Dep, TestModule, Module} object jawn extends CrossModule(JawnModule, "2.10.6", "2.11.11", "2.12.3") case class JawnModule(crossVersion: String) extends mill.Module{ + override def basePath = super.basePath / ammonite.ops.up + trait JawnModule extends scalalib.SbtModule{ def scalaVersion = crossVersion def scalacOptions = Seq( @@ -21,38 +23,38 @@ case class JawnModule(crossVersion: String) extends mill.Module{ def testFramework = "org.scalatest.tools.Framework" } } - object parser extends JawnModule{ - def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'parser - } + object parser extends JawnModule + object util extends JawnModule{ def projectDeps = Seq(parser) def testProjectDeps = Seq(parser.test) - def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'util } object ast extends JawnModule{ def projectDeps = Seq(parser, util) def testProjectDeps = Seq(parser.test, util.test) - def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'ast } - class Support(name: String, ivyDeps0: Dep*) extends JawnModule{ + class Support(ivyDeps0: Dep*)(implicit ctx: mill.Module.Ctx) extends JawnModule{ def projectDeps = Seq[Module](parser) - def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'support / name def ivyDeps = ivyDeps0 } - object argonaut extends Support("argonaut", Dep("io.argonaut", "argonaut", "6.2")) - object json4s extends Support("json4s", Dep("org.json4s", "json4s-ast", "3.5.2")) + object support extends mill.Module{ + object argonaut extends Support(Dep("io.argonaut", "argonaut", "6.2")) + object json4s extends Support(Dep("org.json4s", "json4s-ast", "3.5.2")) - object play extends Support("play"){ - def ivyDeps = mill.T{ - scalaBinaryVersion() match{ - case "2.10" => Seq(Dep("com.typesafe.play", "play-json", "2.4.11")) - case "2.11" => Seq(Dep("com.typesafe.play", "play-json", "2.5.15")) - case _ => Seq(Dep("com.typesafe.play", "play-json", "2.6.0")) + object play extends Support(){ + def ivyDeps = mill.T{ + scalaBinaryVersion() match{ + case "2.10" => Seq(Dep("com.typesafe.play", "play-json", "2.4.11")) + case "2.11" => Seq(Dep("com.typesafe.play", "play-json", "2.5.15")) + case _ => Seq(Dep("com.typesafe.play", "play-json", "2.6.0")) + } } } - } - object rojoma extends Support("rojoma", Dep("com.rojoma", "rojoma-json", "2.4.3")) - object rojomaV3 extends Support("rojoma-v3", Dep("com.rojoma", "rojoma-json-v3", "3.7.2")) - object spray extends Support("spray", Dep("io.spray", "spray-json", "1.3.3")) + object rojoma extends Support(Dep("com.rojoma", "rojoma-json", "2.4.3")) + object rojomaV3 extends Support(Dep("com.rojoma", "rojoma-json-v3", "3.7.2")){ + override def basePath = super.basePath / ammonite.ops.up / "rojoma-v3" + } + object spray extends Support(Dep("io.spray", "spray-json", "1.3.3")) + } } \ No newline at end of file diff --git a/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala b/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala index 2c595e35..b7dc722d 100644 --- a/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala +++ b/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala @@ -12,7 +12,7 @@ abstract class IntegrationTestSuite(repoKey: String, workspaceSlug: String) exte val stdIn = new ByteArrayInputStream(Array()) val runner = new mill.main.MainRunner( ammonite.main.Cli.Config(wd = workspacePath), false, - System.out, System.err, System.in + stdOutErr, stdOutErr, stdIn ) def eval(s: String*) = runner.runScript(workspacePath / "build.sc", s.toList) def meta(s: String) = read(workspacePath / "out" / RelPath(s.replaceAll("\\.", "/")) / "meta.json") diff --git a/scalajslib/src/test/scala/mill/scalajslib/HelloJSWorldTests.scala b/scalajslib/src/test/scala/mill/scalajslib/HelloJSWorldTests.scala index 85052a04..4a8fd3cf 100644 --- a/scalajslib/src/test/scala/mill/scalajslib/HelloJSWorldTests.scala +++ b/scalajslib/src/test/scala/mill/scalajslib/HelloJSWorldTests.scala @@ -10,17 +10,17 @@ import mill.define.Cross import mill.discover.Discovered import mill.scalalib.PublishModule import mill.scalalib.publish.{Developer, License, PomSettings, SCM} -import mill.util.TestEvaluator +import mill.util.{TestEvaluator, TestUtil} import utest._ import scala.collection.JavaConverters._ -trait HelloJSWorldModule extends ScalaJSModule with PublishModule { - def basePath = HelloJSWorldTests.workspacePath +trait HelloJSWorldModule extends TestUtil.BaseModule with ScalaJSModule with PublishModule { + override def basePath = HelloJSWorldTests.workspacePath override def mainClass = Some("Main") } -object HelloJSWorld { +object HelloJSWorld extends TestUtil.BaseModule { val build = for { scalaJS <- Cross("0.6.20", "0.6.21", "1.0.0-M2") scala <- Cross("2.11.8", "2.12.3", "2.12.4") diff --git a/scalalib/src/main/scala/mill/scalalib/Module.scala b/scalalib/src/main/scala/mill/scalalib/Module.scala index c6fcfb4d..6cc47176 100644 --- a/scalalib/src/main/scala/mill/scalalib/Module.scala +++ b/scalalib/src/main/scala/mill/scalalib/Module.scala @@ -75,7 +75,6 @@ trait Module extends mill.Module with TaskModule { outer => def compileIvyDeps = T{ Seq[Dep]() } def scalacPluginIvyDeps = T{ Seq[Dep]() } def runIvyDeps = T{ Seq[Dep]() } - def basePath: Path def scalacOptions = T{ Seq.empty[String] } def javacOptions = T{ Seq.empty[String] } @@ -360,11 +359,10 @@ trait PublishModule extends Module { outer => } trait SbtModule extends Module { outer => - def basePath: Path override def sources = T.source{ basePath / 'src / 'main / 'scala } override def resources = T.source{ basePath / 'src / 'main / 'resources } trait Tests extends super.Tests{ - def basePath = outer.basePath + override def basePath = outer.basePath override def sources = T.source{ basePath / 'src / 'test / 'scala } override def resources = T.source{ basePath / 'src / 'test / 'resources } } diff --git a/scalalib/src/test/scala/mill/scalalib/HelloWorldTests.scala b/scalalib/src/test/scala/mill/scalalib/HelloWorldTests.scala index 4cd1d58d..c9419d07 100644 --- a/scalalib/src/test/scala/mill/scalalib/HelloWorldTests.scala +++ b/scalalib/src/test/scala/mill/scalalib/HelloWorldTests.scala @@ -9,7 +9,7 @@ import mill.define.{Cross, Target} import mill.discover.Discovered import mill.eval.{Evaluator, Result} import mill.scalalib.publish._ -import mill.util.TestEvaluator +import mill.util.{TestEvaluator, TestUtil} import sbt.internal.inc.CompileFailed import utest._ @@ -20,8 +20,8 @@ trait HelloWorldModule extends scalalib.Module { def basePath = HelloWorldTests.workingSrcPath } -object HelloWorld extends HelloWorldModule -object CrossHelloWorld extends mill.Module{ +object HelloWorld extends TestUtil.BaseModule with HelloWorldModule +object CrossHelloWorld extends TestUtil.BaseModule { val cross = for(v <- Cross("2.10.6", "2.11.11", "2.12.3", "2.12.4")) yield new HelloWorldModule { @@ -29,19 +29,19 @@ object CrossHelloWorld extends mill.Module{ } } -object HelloWorldWithMain extends HelloWorldModule { +object HelloWorldWithMain extends TestUtil.BaseModule with HelloWorldModule { def mainClass = Some("Main") } -object HelloWorldWarnUnused extends HelloWorldModule { +object HelloWorldWarnUnused extends TestUtil.BaseModule with HelloWorldModule { def scalacOptions = T(Seq("-Ywarn-unused")) } -object HelloWorldFatalWarnings extends HelloWorldModule { +object HelloWorldFatalWarnings extends TestUtil.BaseModule with HelloWorldModule { def scalacOptions = T(Seq("-Ywarn-unused", "-Xfatal-warnings")) } -object HelloWorldWithPublish extends HelloWorldModule with PublishModule { +object HelloWorldWithPublish extends TestUtil.BaseModule with HelloWorldModule with PublishModule { def artifactName = "hello-world" def publishVersion = "0.0.1" @@ -60,7 +60,7 @@ object HelloWorldWithPublish extends HelloWorldModule with PublishModule { Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi")) ) } -object HelloWorldScalaOverride extends HelloWorldModule { +object HelloWorldScalaOverride extends TestUtil.BaseModule with HelloWorldModule { override def scalaVersion: Target[String] = "2.11.11" } object HelloWorldTests extends TestSuite { -- cgit v1.2.3