diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2018-01-17 23:44:01 -0800 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2018-01-17 23:44:01 -0800 |
commit | 1341e29629ec633a8d9db0e1717434ab560aab42 (patch) | |
tree | b70ce24feef8ddb7e009a1521e2ca14868a7a5da | |
parent | 26e3702f3fccdedbb9dd44574678e9217d16959c (diff) | |
download | mill-1341e29629ec633a8d9db0e1717434ab560aab42.tar.gz mill-1341e29629ec633a8d9db0e1717434ab560aab42.tar.bz2 mill-1341e29629ec633a8d9db0e1717434ab560aab42.zip |
Introduce an Ammonite build to our test suite
-rw-r--r-- | build.sbt | 6 | ||||
-rwxr-xr-x | build.sc | 4 | ||||
-rwxr-xr-x | ci/test.sh | 5 | ||||
-rwxr-xr-x | ci/test2.sh | 4 | ||||
-rwxr-xr-x | ci/test3.sh | 2 | ||||
-rwxr-xr-x | ci/test_all.sh | 15 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Cross.scala | 5 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Ctx.scala | 30 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Module.scala | 5 | ||||
-rw-r--r-- | core/src/main/scala/mill/main/MainRunner.scala | 3 | ||||
-rw-r--r-- | integration/src/test/resources/ammonite/build.sc | 177 | ||||
-rw-r--r-- | integration/src/test/scala/mill/integration/AmmoniteTests.scala | 36 | ||||
-rw-r--r-- | integration/src/test/scala/mill/integration/IntegrationTestSuite.scala | 8 |
13 files changed, 269 insertions, 31 deletions
@@ -200,6 +200,11 @@ val testRepos = Map( resourceManaged in test, List("shared.sc", "downloadTestRepo", "pathikrit/better-files", "e235722f91f78b8f34a41b8332d7fae3e8a64141", _), suffix = "better-files" + ), + "MILL_AMMONITE_REPO" -> ammoniteRun( + resourceManaged in test, + List("shared.sc", "downloadTestRepo", "lihaoyi/ammonite", "96ea548d5e3b72ab6ad4d9765e205bf6cc1c82ac", _), + suffix = "ammonite" ) ) @@ -213,6 +218,7 @@ lazy val integration = project javaOptions in Test := { val kvs = Seq( "MILL_ACYCLIC_REPO" -> testRepos("MILL_ACYCLIC_REPO").value, + "MILL_AMMONITE_REPO" -> testRepos("MILL_AMMONITE_REPO").value, "MILL_JAWN_REPO" -> testRepos("MILL_JAWN_REPO").value, "MILL_BETTERFILES_REPO" -> testRepos("MILL_BETTERFILES_REPO").value ) @@ -149,7 +149,9 @@ def testRepos = T{ "MILL_JAWN_REPO" -> shared.downloadTestRepo("non/jawn", "fd8dc2b41ce70269889320aeabf8614fe1e8fbcb", T.ctx().dest/"jawn"), "MILL_BETTERFILES_REPO" -> - shared.downloadTestRepo("pathikrit/better-files", "e235722f91f78b8f34a41b8332d7fae3e8a64141", T.ctx().dest/"better-files") + shared.downloadTestRepo("pathikrit/better-files", "e235722f91f78b8f34a41b8332d7fae3e8a64141", T.ctx().dest/"better-files"), + "MILL_AMMONITE_REPO" -> + shared.downloadTestRepo("lihaoyi/ammonite", "96ea548d5e3b72ab6ad4d9765e205bf6cc1c82ac", T.ctx().dest/"ammonite") ) } @@ -6,7 +6,4 @@ set -eux git clean -xdf # First build & run tests using SBT -sbt core/test scalalib/test scalajslib/test -sbt integration/test -sbt bin/test:assembly - +sbt core/test scalalib/test scalajslib/test integration/test bin/test:assembly diff --git a/ci/test2.sh b/ci/test2.sh index 28fa65cd..9d84ecdc 100755 --- a/ci/test2.sh +++ b/ci/test2.sh @@ -5,7 +5,7 @@ set -eux # Starting from scratch... git clean -xdf - sbt bin/test:assembly -# Run tests using + +# Run tests using Mill built using SBT target/bin/mill --all {core,scalalib,scalajslib,integration}.test devAssembly diff --git a/ci/test3.sh b/ci/test3.sh index 0be934c1..ffeb259c 100755 --- a/ci/test3.sh +++ b/ci/test3.sh @@ -5,7 +5,7 @@ set -eux # Starting from scratch... git clean -xdf -# First build & run tests using SBT +# First build using SBT sbt bin/test:assembly # Build Mill using SBT diff --git a/ci/test_all.sh b/ci/test_all.sh new file mode 100755 index 00000000..558f76d6 --- /dev/null +++ b/ci/test_all.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -eux + +# Starting from scratch... +git clean -xdf + +# First build & run tests using SBT +sbt core/test scalalib/test scalajslib/test integration/test bin/test:assembly + +# Run tests using Mill built using SBT +target/bin/mill --all {core,scalalib,scalajslib,integration}.test devAssembly + +# Second build & run tests using Mill +out/devAssembly/dest --all {core,scalalib,scalajslib,integration}.test devAssembly
\ No newline at end of file diff --git a/core/src/main/scala/mill/define/Cross.scala b/core/src/main/scala/mill/define/Cross.scala index 0d799f19..b51064be 100644 --- a/core/src/main/scala/mill/define/Cross.scala +++ b/core/src/main/scala/mill/define/Cross.scala @@ -56,10 +56,7 @@ class Cross[T](cases: Any*) case v => Tuple1(v) } val crossValues = c.productIterator.toList - val relPath = ctx.segment match{ - case Segment.Label(s) => ammonite.ops.empty / s - case Segment.Cross(vs) => ammonite.ops.empty / vs.map(_.toString) - } + val relPath = ctx.segment.pathSegments val sub = ci.make( c, ctx.copy( diff --git a/core/src/main/scala/mill/define/Ctx.scala b/core/src/main/scala/mill/define/Ctx.scala index 308c50ef..6d685521 100644 --- a/core/src/main/scala/mill/define/Ctx.scala +++ b/core/src/main/scala/mill/define/Ctx.scala @@ -1,11 +1,16 @@ package mill.define import ammonite.main.Router.Overrides -import ammonite.ops.Path +import ammonite.ops.{Path, RelPath} import scala.annotation.implicitNotFound -sealed trait Segment +sealed trait Segment{ + def pathSegments: Seq[String] = this match{ + case Segment.Label(s) => List(s) + case Segment.Cross(vs) => vs.map(_.toString) + } +} object Segment{ case class Label(value: String) extends Segment case class Cross(value: Seq[Any]) extends Segment @@ -42,7 +47,8 @@ case class Ctx(enclosing: String, segment: Segment, basePath: Path, segments: Segments, - overrides: Int) + overrides: Int){ +} object Ctx{ implicit def make(implicit millModuleEnclosing0: sourcecode.Enclosing, @@ -50,12 +56,14 @@ object Ctx{ millName0: sourcecode.Name, millModuleBasePath0: BasePath, segments0: Segments, - overrides0: Overrides): Ctx = Ctx( - millModuleEnclosing0.value, - millModuleLine0.value, - Segment.Label(millName0.value), - millModuleBasePath0.value, - segments0, - overrides0.value - ) + overrides0: Overrides): Ctx = { + Ctx( + millModuleEnclosing0.value, + millModuleLine0.value, + Segment.Label(millName0.value), + millModuleBasePath0.value, + segments0, + overrides0.value + ) + } }
\ No newline at end of file diff --git a/core/src/main/scala/mill/define/Module.scala b/core/src/main/scala/mill/define/Module.scala index f7c84b6d..e42ce798 100644 --- a/core/src/main/scala/mill/define/Module.scala +++ b/core/src/main/scala/mill/define/Module.scala @@ -24,10 +24,7 @@ class Module(implicit outerCtx0: mill.define.Ctx) extends mill.moduledefs.Cacher lazy val millModuleDirectChildren = millInternal.reflectNestedObjects[Module] def millOuterCtx = outerCtx0 - def basePath: Path = millOuterCtx.basePath / (millOuterCtx.segment match{ - case Segment.Label(s) => List(s) - case Segment.Cross(vs) => vs.map(_.toString) - }) + def basePath: Path = millOuterCtx.basePath / millOuterCtx.segment.pathSegments implicit def millModuleBasePath: BasePath = BasePath(basePath) implicit def millModuleSegments: Segments = { millOuterCtx.segments ++ Seq(millOuterCtx.segment) diff --git a/core/src/main/scala/mill/main/MainRunner.scala b/core/src/main/scala/mill/main/MainRunner.scala index 70cc350c..5281b886 100644 --- a/core/src/main/scala/mill/main/MainRunner.scala +++ b/core/src/main/scala/mill/main/MainRunner.scala @@ -91,9 +91,6 @@ class MainRunner(config: ammonite.main.Cli.Config, |import mill._ | |object $wrapName extends mill.define.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]() diff --git a/integration/src/test/resources/ammonite/build.sc b/integration/src/test/resources/ammonite/build.sc new file mode 100644 index 00000000..cb8d32ab --- /dev/null +++ b/integration/src/test/resources/ammonite/build.sc @@ -0,0 +1,177 @@ +import mill._, scalalib._ +val binCrossScalaVersions = Seq("2.11.11", "2.12.4") +val fullCrossScalaVersions = Seq( + "2.11.3", "2.11.4", "2.11.5", "2.11.6", "2.11.7", "2.11.8", "2.11.9", "2.11.11", + "2.12.0", "2.12.1", "2.12.2", "2.12.3", "2.12.4" +) +trait AmmModule extends mill.scalalib.CrossSbtModule{ + def testFramework = "utest.runner.Framework" + def scalacOptions = Seq("-P:acyclic:force", "-target:jvm-1.7") + def compileIvyDeps = Agg(ivy"com.lihaoyi::acyclic:0.1.7") + def scalacPluginIvyDeps = Agg(ivy"com.lihaoyi::acyclic:0.1.7") + trait Tests extends super.Tests{ + def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.6.0") + def testFramework = "utest.runner.Framework" + } +} + +object ops extends Cross[OpsModule](binCrossScalaVersions:_*) +class OpsModule(val crossScalaVersion: String) extends AmmModule{ + def ivyDeps = Agg(ivy"com.lihaoyi::geny:0.1.2") + + object test extends Tests +} + +object terminal extends Cross[TerminalModule](binCrossScalaVersions:_*) +class TerminalModule(val crossScalaVersion: String) extends AmmModule{ + def ivyDeps = Agg( + ivy"com.lihaoyi::sourcecode:0.1.3", + ivy"com.lihaoyi::fansi:0.2.3" + ) + def compileIvyDeps = Agg( + ivy"org.scala-lang:scala-reflect:$crossScalaVersion" + ) + + object test extends Tests +} + +object amm extends Cross[MainModule](fullCrossScalaVersions:_*){ + object util extends Cross[UtilModule](binCrossScalaVersions:_*) + class UtilModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq(ops()) + def ivyDeps = Agg( + ivy"com.lihaoyi::upickle:0.5.1", + ivy"com.lihaoyi::pprint:0.5.2", + ivy"com.lihaoyi::fansi:0.2.4" + ) + } + + + object runtime extends Cross[RuntimeModule](binCrossScalaVersions:_*) + class RuntimeModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq(ops(), amm.util()) + def ivyDeps = Agg( + ivy"io.get-coursier::coursier:1.0.0", + ivy"io.get-coursier::coursier-cache:1.0.0", + ivy"org.scalaj::scalaj-http:2.3.0" + ) + + def generatedSources = T{ + import ammonite.ops._ + mkdir(T.ctx().dest) + cp(build.basePath/'project/"Constants.scala", T.ctx().dest/"Constants.scala") + Seq(PathRef(T.ctx().dest)) + } + } + + object interp extends Cross[InterpModule](fullCrossScalaVersions:_*) + class InterpModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq(ops(), amm.util(), amm.runtime()) + def ivyDeps = Agg( + ivy"org.scala-lang:scala-compiler:$crossScalaVersion", + ivy"org.scala-lang:scala-reflect:$crossScalaVersion", + ivy"com.lihaoyi::scalaparse:1.0.0", + ivy"org.javassist:javassist:3.21.0-GA" + ) + } + + object repl extends Cross[ReplModule](fullCrossScalaVersions:_*) + class ReplModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq( + ops(), amm.util(), + amm.runtime(), amm.interp(), + terminal() + ) + def ivyDeps = Agg( + ivy"jline:jline:2.14.3", + ivy"com.github.javaparser:javaparser-core:3.2.5", + ivy"com.github.scopt::scopt:3.5.0" + ) + + object test extends Tests{ + def resources = T.input { + super.resources() ++ + ReplModule.this.sources() ++ + ReplModule.this.externalCompileDepSources() + } + } + } +} +class MainModule(val crossScalaVersion: String) extends AmmModule{ + + def mainClass = Some("ammonite.Main") + + def moduleDeps = Seq( + terminal(), ops(), + amm.util(), amm.runtime(), + amm.interp(), amm.repl() + ) + def ivyDeps = Agg( + ivy"com.github.scopt::scopt:3.5.0", + ) + + def runClasspath = + super.runClasspath() ++ + ops().sources() ++ + terminal().sources() ++ + amm.util().sources() ++ + amm.runtime().sources() ++ + amm.interp().sources() ++ + amm.repl().sources() ++ + sources() ++ + externalCompileDepSources() + + + + def prependShellScript = + "#!/usr/bin/env sh\n" + + """exec java -jar -Xmx500m -XX:+UseG1GC $JAVA_OPTS "$0" "$@"""" + + + object test extends Tests{ + def moduleDeps = super.moduleDeps ++ Seq(amm.repl().test) + def ivyDeps = super.ivyDeps() ++ Agg( + ivy"com.chuusai::shapeless:2.3.2" + ) + } +} + +object shell extends Cross[ShellModule](fullCrossScalaVersions:_*) +class ShellModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq(ops(), amm()) + object test extends Tests{ + def moduleDeps = super.moduleDeps ++ Seq(amm.repl().test) + // (test in Test) := (test in Test).dependsOn(packageBin in Compile).value, + // (run in Test) := (run in Test).dependsOn(packageBin in Compile).evaluated, + // (testOnly in Test) := (testOnly in Test).dependsOn(packageBin in Compile).evaluated + } +} +object integration extends Cross[IntegrationModule](fullCrossScalaVersions:_*) +class IntegrationModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq(ops(), amm()) + // (test in Test) := (test in Test).dependsOn(integrationTasks:_*).value, + // (run in Test) := (run in Test).dependsOn(integrationTasks:_*).evaluated, + // (testOnly in Test) := (testOnly in Test).dependsOn(integrationTasks:_*).evaluated, + // (console in Test) := (console in Test).dependsOn(integrationTasks:_*).value, + // initialCommands in (Test, console) := "ammonite.integration.Main.main(null)" + object test extends Tests { + } +} + +object sshd extends Cross[SshdModule](fullCrossScalaVersions:_*) +class SshdModule(val crossScalaVersion: String) extends AmmModule{ + def moduleDeps = Seq(ops(), amm()) + def ivyDeps = Agg( + // sshd-core 1.3.0 requires java8 + ivy"org.apache.sshd:sshd-core:1.2.0", + ivy"org.bouncycastle:bcprov-jdk15on:1.56", + ) + object test extends Tests { + def ivyDeps = super.ivyDeps() ++ Agg( + // slf4j-nop makes sshd server use logger that writes into the void + ivy"org.slf4j:slf4j-nop:1.7.12", + ivy"com.jcraft:jsch:0.1.54", + ivy"org.scalacheck::scalacheck:1.12.6" + ) + } +}
\ No newline at end of file diff --git a/integration/src/test/scala/mill/integration/AmmoniteTests.scala b/integration/src/test/scala/mill/integration/AmmoniteTests.scala new file mode 100644 index 00000000..22bd3cb8 --- /dev/null +++ b/integration/src/test/scala/mill/integration/AmmoniteTests.scala @@ -0,0 +1,36 @@ +package mill.integration + +import ammonite.ops._ +import utest._ + +object AmmoniteTests extends IntegrationTestSuite("MILL_AMMONITE_REPO", "ammonite") { + val tests = Tests{ + initWorkspace() + + def check(scalaVersion: String) = { + val replTests = eval( + s"amm.repl[$scalaVersion].test", "{ammonite.unit,ammonite.session.ProjectTests.guava}" + ) + val replTestMeta = meta(s"amm.repl[$scalaVersion].test.test") + assert( + replTests, + replTestMeta.contains("ammonite.session.ProjectTests.guava"), + replTestMeta.contains("ammonite.unit.SourceTests.objectInfo.thirdPartyJava") + ) + + val compileResult = eval( + "--all", s"{shell,sshd,amm,integration}[$scalaVersion].test.compile" + ) + + assert( + compileResult, + ls.rec(workspacePath / 'out / 'integration / scalaVersion / 'test / 'compile) + .exists(_.name == "ErrorTruncationTests.class") + ) + } + + 'scala2118 - check("2.11.8") + 'scala2124 - check("2.12.4") + + } +} diff --git a/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala b/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala index ba4415fa..293411c5 100644 --- a/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala +++ b/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala @@ -3,6 +3,8 @@ package mill.integration import java.io.{ByteArrayInputStream, ByteArrayOutputStream, InputStream, PrintStream} import ammonite.ops._ +import mill.define.Segments +import mill.main.ParseArgs import utest._ abstract class IntegrationTestSuite(repoKey: String, workspaceSlug: String) extends TestSuite{ @@ -15,7 +17,11 @@ abstract class IntegrationTestSuite(repoKey: String, workspaceSlug: String) exte 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") + def meta(s: String) = { + val (List(selector), args) = ParseArgs.apply(Seq(s)).right.get + + read(workspacePath / "out" / selector.flatMap(_.pathSegments) / "meta.json") + } def initWorkspace() = { rm(workspacePath) mkdir(workspacePath / up) |