From a9ed3b67cc1d0b0a755159013b28766f436e866a Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 4 Dec 2017 10:17:25 -0800 Subject: Flesh out `bridges` pre-compilation in Mill build, getting the cross-minor-version `AcyclicTests` running using the `mill` test runner Fixed `Discovered` to only pick up public `Target`s, which makes it skip things like the `super$compile` of an overriden `compile` target. Split up `sources` and `allSources` TBD how to properly switch the `compilerBridgeJar` between the different output paths of SBT's compile-dir and Mill's compile-dir, and eventually to a maven-central artifact too --- build.sbt | 9 +----- build.sc | 35 ++++++++++++++++++++++ core/src/main/scala/mill/Main.scala | 19 ++++-------- core/src/main/scala/mill/discover/Discovered.scala | 3 +- core/src/main/scala/mill/discover/Mirror.scala | 9 ++++++ .../main/scala/mill/scalaplugin/ScalaModule.scala | 10 ++++--- 6 files changed, 59 insertions(+), 26 deletions(-) diff --git a/build.sbt b/build.sbt index c1d8719b..3002eeb7 100644 --- a/build.sbt +++ b/build.sbt @@ -54,15 +54,8 @@ def bridge(bridgeVersion: String) = Project( val url = s"http://repo1.maven.org/maven2/org/scala-sbt/compiler-bridge_$v/1.0.5/compiler-bridge_$v-1.0.5-sources.jar" val curlDest = java.nio.file.Paths.get(target.value.toString, "sources") - if (java.nio.file.Files.exists(curlDest)) { - java.nio.file.Files.walk(curlDest) - .iterator() - .asScala - .toSeq - .reverse - .foreach(java.nio.file.Files.delete) - } + Seq("rm", "-rf", curlDest.toString).! java.nio.file.Files.createDirectories(curlDest) Seq("curl", "-L", "-o", curlDest.resolve("bridge.jar").toString, url).! diff --git a/build.sc b/build.sc index 6eb3de2b..7b261892 100755 --- a/build.sc +++ b/build.sc @@ -48,10 +48,45 @@ object Core extends MillModule { } } + +val bridges = for{ + crossVersion <- mill.define.Cross("2.10.6", "2.11.8", "2.11.11", "2.12.3", "2.12.4") +} yield new ScalaModule{ + def basePath = pwd / 'bridge + def scalaVersion = crossVersion + override def allSources = T{ + + val v = crossVersion.split('.').dropRight(1).mkString(".") + val url = + s"http://repo1.maven.org/maven2/org/scala-sbt/compiler-bridge_$v/1.0.5/compiler-bridge_$v-1.0.5-sources.jar" + val curlDest = T.ctx().dest + implicit val pwd = curlDest + mkdir(curlDest) + rm(curlDest/"bridge.jar") + + %("curl", "-L", "-o", curlDest / "bridge.jar", url) + %("unzip", curlDest / "bridge.jar" , "-d", curlDest / 'classes) + + + Seq(PathRef(curlDest / 'classes)) + } + override def ivyDeps = Seq( + Dep.Java("org.scala-lang", "scala-compiler", crossVersion), + Dep.Java("org.scala-sbt", "compiler-interface", "1.0.5") + ) +} object ScalaPlugin extends MillModule { override def projectDeps = Seq(Core) def basePath = pwd / 'scalaplugin + override def compile = T.persistent[mill.eval.PathRef]{ + bridges("2.10.6").compile() + bridges("2.11.8").compile() + bridges("2.11.11").compile() + bridges("2.12.3").compile() + bridges("2.12.4").compile() + super.compile() + } override def prependShellScript = "#!/usr/bin/env sh\n" + """exec java $JAVA_OPTS -cp "$0" mill.Main "$@" """ diff --git a/core/src/main/scala/mill/Main.scala b/core/src/main/scala/mill/Main.scala index 1dbae4c3..db7a6c1a 100644 --- a/core/src/main/scala/mill/Main.scala +++ b/core/src/main/scala/mill/Main.scala @@ -26,14 +26,7 @@ object Main { query.parse(input) } - def renderSelector(selector: List[Mirror.Segment]) = { - val Mirror.Segment.Label(head) :: rest = selector - val stringSegments = rest.map{ - case Mirror.Segment.Label(s) => "." + s - case Mirror.Segment.Cross(vs) => "[" + vs.mkString(",") + "]" - } - head + stringSegments.mkString - } + def parseArgs(selectorString: String): Either[String, List[Mirror.Segment]] = { import fastparse.all.Parsed @@ -81,7 +74,7 @@ object Main { def command = invokeCommand(hierarchy, last) command orElse target orElse runDefault.headOption.flatten match{ - case None => Left("Cannot resolve task " + renderSelector( + case None => Left("Cannot resolve task " + Mirror.renderSelector( (Mirror.Segment.Label(last) :: revSelectorsSoFar).reverse) ) case Some(either) => either @@ -96,7 +89,7 @@ object Main { case (label, child) if label == singleLabel => child } match{ case Some(child) => resolve(tail, child, obj, rest, remainingCrossSelectors, newRevSelectorsSoFar) - case None => Left("Cannot resolve module " + renderSelector(newRevSelectorsSoFar.reverse)) + case None => Left("Cannot resolve module " + Mirror.renderSelector(newRevSelectorsSoFar.reverse)) } case Mirror.Segment.Cross(cross) => @@ -105,7 +98,7 @@ object Main { if (crossOptions.contains(cross)){ resolve(tail, childMirror, obj, rest, remainingCrossSelectors, newRevSelectorsSoFar) }else{ - Left("Cannot resolve cross " + renderSelector(newRevSelectorsSoFar.reverse)) + Left("Cannot resolve cross " + Mirror.renderSelector(newRevSelectorsSoFar.reverse)) } @@ -119,7 +112,7 @@ object Main { val discovered = implicitly[Discovered[T]] val consistencyErrors = Discovered.consistencyCheck(obj, discovered) if (consistencyErrors.nonEmpty) { - Left(s"Failed Discovered.consistencyCheck: $consistencyErrors") + Left(s"Failed Discovered.consistencyCheck: ${consistencyErrors.map(Mirror.renderSelector)}") } else { Right(discovered) } @@ -138,7 +131,7 @@ object Main { (for((k, fs) <- evaluated.failing.items()) yield { val ks = k match{ case Left(t) => t.toString - case Right(t) => renderSelector(t.segments.toList) + case Right(t) => Mirror.renderSelector(t.segments.toList) } val fss = fs.map{ case Result.Exception(t) => t.toString diff --git a/core/src/main/scala/mill/discover/Discovered.scala b/core/src/main/scala/mill/discover/Discovered.scala index aef5f14f..753ac141 100644 --- a/core/src/main/scala/mill/discover/Discovered.scala +++ b/core/src/main/scala/mill/discover/Discovered.scala @@ -47,7 +47,8 @@ object Discovered { if m.isMethod && m.typeSignature.paramLists.isEmpty && m.typeSignature.resultType <:< c.weakTypeOf[Target[_]] && - !m.name.toString.contains(' ') + !m.name.toString.contains(' ') && + m.isPublic } yield { val x = Ident(TermName(c.freshName())) val t = q"""mill.discover.Mirror.makeTargetPoint( diff --git a/core/src/main/scala/mill/discover/Mirror.scala b/core/src/main/scala/mill/discover/Mirror.scala index 4dfeaa25..6293e599 100644 --- a/core/src/main/scala/mill/discover/Mirror.scala +++ b/core/src/main/scala/mill/discover/Mirror.scala @@ -25,6 +25,15 @@ case class Mirror[-T, V](node: (T, List[List[Any]]) => V, } object Mirror{ + def renderSelector(selector: Seq[Mirror.Segment]) = { + val Mirror.Segment.Label(head) :: rest = selector.toList + val stringSegments = rest.map{ + case Mirror.Segment.Label(s) => "." + s + case Mirror.Segment.Cross(vs) => "[" + vs.mkString(",") + "]" + } + head + stringSegments.mkString + } + sealed trait Segment object Segment{ case class Label(value: String) extends Segment diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala b/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala index 27aefb12..3d194190 100644 --- a/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala +++ b/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala @@ -34,7 +34,7 @@ object ScalaModule{ val compilerCache = new CompilerCache(2) def compileScala(scalaVersion: String, - sources: Path, + sources: Seq[Path], compileClasspath: Seq[Path], compilerClasspath: Seq[Path], compilerBridge: Seq[Path], @@ -54,7 +54,8 @@ object ScalaModule{ val compilerJars = compilerClasspath.toArray.map(_.toIO) val compilerBridgeJar = new java.io.File( - s"bridge/${scalaVersion.replace('.', '_')}/target/scala-$binaryScalaVersion/mill-bridge_$scalaVersion-0.1-SNAPSHOT.jar" +// s"bridge/${scalaVersion.replace('.', '_')}/target/scala-$binaryScalaVersion/mill-bridge_$scalaVersion-0.1-SNAPSHOT.jar" + s"out/bridges/$scalaVersion/compile/classes" ) val zincClassLoader = new URLClassLoader(compilerJars.map(_.toURI.toURL), null){ @@ -110,7 +111,7 @@ object ScalaModule{ val newResult = ic.compile( ic.inputs( classpath = classesDir +: compileClasspathFiles, - sources = ls.rec(sources).filter(_.isFile).map(_.toIO).toArray, + sources = sources.flatMap(ls.rec).filter(x => x.isFile && x.ext == "scala").map(_.toIO).toArray, classesDirectory = classesDir, scalacOptions = scalacOptions.toArray, javacOptions = javacOptions.toArray, @@ -334,10 +335,11 @@ trait ScalaModule extends Module with TaskModule{ outer => def sources = T.source{ basePath / 'src } def resources = T.source{ basePath / 'resources } + def allSources = T{ Seq(sources()) } def compile = T.persistent{ compileScala( scalaVersion(), - sources().path, + allSources().map(_.path), compileDepClasspath().map(_.path), scalaCompilerClasspath().map(_.path), compilerBridgeClasspath().map(_.path), -- cgit v1.2.3