diff options
-rw-r--r-- | build.sbt | 24 | ||||
-rwxr-xr-x | build.sc | 7 | ||||
-rw-r--r-- | core/test/src/mill/util/TestEvaluator.scala | 2 | ||||
-rw-r--r-- | scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala | 2 | ||||
-rw-r--r-- | scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala | 2 | ||||
-rw-r--r-- | scalajslib/src/mill/scalajslib/Lib.scala | 62 | ||||
-rw-r--r-- | scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala | 62 | ||||
-rw-r--r-- | scalajslib/src/mill/scalajslib/ScalaJSModule.scala | 74 | ||||
-rw-r--r-- | scalaworker/src/mill/scalaworker/ScalaWorker.scala | 2 |
9 files changed, 126 insertions, 111 deletions
@@ -175,14 +175,14 @@ lazy val scalajslib = project sharedSettings, name := "mill-scalajslib", fork in Test := true, - baseDirectory in Test := (baseDirectory in Test).value / "..", - javaOptions in Test := jsbridgeProps.value.toSeq ++ scalaWorkerProps.value + baseDirectory in Test := (baseDirectory in Test).value / ".." ) + def jsbridge(binary: String, version: String) = Project( id = "scalajsbridge_" + binary.replace('.', '_'), base = file("scalajslib/jsbridges/" + binary) - ) + ).dependsOn(scalajslib) .settings( sharedSettings, organization := "com.lihaoyi", @@ -192,19 +192,15 @@ def jsbridge(binary: String, version: String) = ) lazy val scalajsbridge_0_6 = jsbridge("0.6", "0.6.21") lazy val scalajsbridge_1_0 = jsbridge("1.0", "1.0.0-M2") + +javaOptions in (scalajslib, Test) := jsbridgeProps.value.toSeq ++ scalaWorkerProps.value + val jsbridgeProps = Def.task{ - def bridgeClasspath(depClasspath: Classpath, jar: File) = { - (depClasspath.files :+ jar).map(_.absolutePath).mkString(File.pathSeparator) - } val mapping = Map( - "MILL_SCALAJS_BRIDGE_0_6" -> bridgeClasspath( - (dependencyClasspath in (scalajsbridge_0_6, Compile)).value, - (packageBin in (scalajsbridge_0_6, Compile)).value - ), - "MILL_SCALAJS_BRIDGE_1_0" -> bridgeClasspath( - (dependencyClasspath in (scalajsbridge_1_0, Compile)).value, - (packageBin in (scalajsbridge_1_0, Compile)).value - ) + "MILL_SCALAJS_BRIDGE_0_6" -> + (packageBin in (scalajsbridge_0_6, Compile)).value.absolutePath.toString, + "MILL_SCALAJS_BRIDGE_1_0" -> + (packageBin in (scalajsbridge_1_0, Compile)).value.absolutePath.toString ) for((k, v) <- mapping) yield s"-D$k=$v" } @@ -134,18 +134,17 @@ object scalajslib extends MillModule { def moduleDeps = Seq(scalalib) - def bridgeClasspath(runDepClasspath: Agg[PathRef], classes: PathRef) = - (runDepClasspath ++ Agg(classes)).map(_.path).mkString(File.pathSeparator) def testArgs = T{ val mapping = Map( - "MILL_SCALAJS_BRIDGE_0_6" -> bridgeClasspath(jsbridges("0.6").runDepClasspath(), jsbridges("0.6").compile().classes), - "MILL_SCALAJS_BRIDGE_1_0" -> bridgeClasspath(jsbridges("1.0").runDepClasspath(), jsbridges("1.0").compile().classes) + "MILL_SCALAJS_BRIDGE_0_6" -> jsbridges("0.6").compile().classes.path, + "MILL_SCALAJS_BRIDGE_1_0" -> jsbridges("1.0").compile().classes.path ) scalaworker.testArgs() ++ (for((k, v) <- mapping.toSeq) yield s"-D$k=$v") } object jsbridges extends Cross[JsBridgeModule]("0.6", "1.0") class JsBridgeModule(scalajsBinary: String) extends MillModule{ + def moduleDeps = Seq(scalajslib) val scalajsVersion = scalajsBinary match { case "0.6" => "0.6.21" case "1.0" => "1.0.0-M2" diff --git a/core/test/src/mill/util/TestEvaluator.scala b/core/test/src/mill/util/TestEvaluator.scala index 47c9d940..e437017a 100644 --- a/core/test/src/mill/util/TestEvaluator.scala +++ b/core/test/src/mill/util/TestEvaluator.scala @@ -8,7 +8,7 @@ class TestEvaluator(module: mill.Module, workspacePath: Path, basePath: Path){ val evaluator = new Evaluator(workspacePath, basePath, module, DummyLogger) - + //val evaluator = new Evaluator(workspacePath, basePath, module, new PrintLogger(true, ammonite.util.Colors.Default, System.out, System.out, System.err)) def apply[T](t: Task[T]): Either[Result.Failing, (T, Int)] = { val evaluated = evaluator.evaluate(Agg(t)) diff --git a/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala b/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala index 4826b1cd..3ed17f16 100644 --- a/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala +++ b/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala @@ -9,7 +9,7 @@ import org.scalajs.core.tools.io.{AtomicWritableFileVirtualJSFile, FileVirtualBi import org.scalajs.core.tools.linker.{ModuleInitializer, StandardLinker} import org.scalajs.core.tools.logging.ScalaConsoleLogger -class ScalaJSLinkerBridge { +class ScalaJSLinkerBridge extends mill.scalajslib.ScalaJSLinkerBridge{ def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit = { val config = StandardLinker.Config().withOptimizer(fullOpt) val linker = StandardLinker(config) diff --git a/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala b/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala index ef896726..8bd28e49 100644 --- a/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala +++ b/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSLinkerBridge.scala @@ -8,7 +8,7 @@ import org.scalajs.core.tools.io._ import org.scalajs.core.tools.linker.{ModuleInitializer, StandardLinker} import org.scalajs.core.tools.logging.ScalaConsoleLogger -class ScalaJSLinkerBridge { +class ScalaJSLinkerBridge extends mill.scalajslib.ScalaJSLinkerBridge{ def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit = { val config = StandardLinker.Config().withOptimizer(fullOpt) val linker = StandardLinker(config) diff --git a/scalajslib/src/mill/scalajslib/Lib.scala b/scalajslib/src/mill/scalajslib/Lib.scala deleted file mode 100644 index 6a85cf0c..00000000 --- a/scalajslib/src/mill/scalajslib/Lib.scala +++ /dev/null @@ -1,62 +0,0 @@ -package mill -package scalajslib - -import java.io.File -import java.net.URLClassLoader - -import ammonite.ops.{Path, mkdir, rm, _} -import mill.eval.PathRef -import mill.scalalib.Dep -import mill.util.{Ctx, Loose} - -import scala.collection.breakOut -import scala.language.reflectiveCalls - -private object LinkerBridge { - @volatile var scalaInstanceCache = Option.empty[(Long, ScalaJSLinkerBridge)] -} - -object Lib { - - def scalaJSLinkerIvyDep(scalaJSVersion: String): Dep = - Dep("com.lihaoyi", s"mill-jsbridge_${scalaJSVersion.replace('.', '_')}", "0.1-SNAPSHOT") - - def scalaJSLinkerBridge(classPath: Loose.Agg[Path]): ScalaJSLinkerBridge = { - val classloaderSig = classPath.map(p => p.toString().hashCode + p.mtime.toMillis).sum - LinkerBridge.scalaInstanceCache match { - case Some((`classloaderSig`, linker)) => linker - case _ => - val cl = new URLClassLoader(classPath.map(_.toIO.toURI.toURL).toArray) - val bridge = cl.loadClass("mill.scalajslib.bridge.ScalaJSLinkerBridge") - .getDeclaredConstructor().newInstance().asInstanceOf[ { - def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit - }] - val linker: ScalaJSLinkerBridge = (sources: Seq[File], - libraries: Seq[File], - dest: File, - main: Option[String], - mode: OptimizeMode) => - bridge.link(sources.toArray, libraries.toArray, dest, main.orNull, mode == FullOpt) - LinkerBridge.scalaInstanceCache = Some((classloaderSig, linker)) - linker - } - } - - def link(main: Option[String], - inputPaths: Seq[Path], - libraries: Loose.Agg[Path], - linker: ScalaJSLinkerBridge, - mode: OptimizeMode) - (implicit ctx: Ctx.DestCtx): PathRef = { - val outputPath = ctx.dest.copy(segments = ctx.dest.segments.init :+ (ctx.dest.segments.last + ".js")) - rm(outputPath) - if (inputPaths.nonEmpty) { - mkdir(outputPath / up) - val inputFiles: Vector[File] = inputPaths.map(ls).flatMap(_.filter(_.ext == "sjsir")).map(_.toIO)(breakOut) - val inputLibraries: Vector[File] = libraries.filter(_.ext == "jar").map(_.toIO).toVector - linker.link(inputFiles, inputLibraries, outputPath.toIO, main, mode) - } - PathRef(outputPath) - } - -} diff --git a/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala b/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala index 448cc16a..ae282152 100644 --- a/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala +++ b/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala @@ -1,12 +1,72 @@ package mill.scalajslib import java.io.File +import java.net.URLClassLoader + +import ammonite.ops.Path +import mill.{Agg, T} sealed trait OptimizeMode object FastOpt extends OptimizeMode object FullOpt extends OptimizeMode +class ScalaJSLinkerWorker { + var scalaInstanceCache = Option.empty[(Long, ScalaJSLinkerBridge)] + def link(toolsClasspath: Agg[Path], + sources: Agg[Path], + libraries: Agg[Path], + dest: File, + main: Option[String], + fullOpt: Boolean): Unit = { + + val classloaderSig = { + toolsClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum + } + + val bridge = scalaInstanceCache match{ + case Some((sig, bridge)) if sig == classloaderSig => bridge + case _ => + val outerClassLoader = getClass.getClassLoader + val cl = new URLClassLoader(toolsClasspath.map(_.toIO.toURI.toURL).toArray){ + override def findClass(name: String) = { + if (name.startsWith("mill.scalajslib.ScalaJSLinkerBridge")){ + outerClassLoader.loadClass(name) + }else{ + super.findClass(name) + } + } + } + val bridge = cl + .loadClass("mill.scalajslib.bridge.ScalaJSLinkerBridge") + .getDeclaredConstructor() + .newInstance() + .asInstanceOf[ScalaJSLinkerBridge] + scalaInstanceCache = Some((classloaderSig, bridge)) + bridge + } + bridge.link( + sources.items.map(_.toIO).toArray, + libraries.items.map(_.toIO).toArray, + dest, + main.orNull, + fullOpt + ) + } + +} + trait ScalaJSLinkerBridge { - def link(sources: Seq[File], libraries: Seq[File], dest: File, main: Option[String], mode: OptimizeMode): Unit + def link(sources: Array[File], + libraries: Array[File], + dest: File, + main: String, + fullOpt: Boolean): Unit } + +object ScalaJSLinkerBridge extends mill.define.BaseModule(ammonite.ops.pwd){ + + def scalaJSLinkerBridge = T.worker{ + new ScalaJSLinkerWorker() + } +}
\ No newline at end of file diff --git a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala index 5c964fd6..0286d573 100644 --- a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala +++ b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala @@ -3,13 +3,17 @@ package scalajslib import java.io.File -import ammonite.ops.Path +import mill.scalalib.DepSyntax +import ammonite.ops.{Path, ls, mkdir, rm} +import coursier.maven.MavenRepository +import mill.eval.PathRef import mill.eval.Result.Success -import mill.scalajslib.Lib._ import mill.scalalib.Lib.resolveDependencies -import mill.scalalib.{Dep, ScalaModule, PublishModule, TestModule} +import mill.scalalib.{Dep, PublishModule, ScalaModule, TestModule} import mill.util.Loose +import scala.collection.breakOut + trait ScalaJSModule extends scalalib.ScalaModule { outer => def scalaJSVersion: T[String] @@ -27,37 +31,55 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer => def scalaJSBridgeVersion = T{ scalaJSVersion().split('.').dropRight(1).mkString(".") } - def scalaJSLinkerClasspath: T[Loose.Agg[PathRef]] = T{ + def sjsLinkerBridgeClasspath = T { val jsBridgeKey = "MILL_SCALAJS_BRIDGE_" + scalaJSBridgeVersion().replace('.', '_') val jsBridgePath = sys.props(jsBridgeKey) - if (jsBridgePath != null) { - Success( - Loose.Agg.from( - jsBridgePath.split(File.pathSeparator).map(f => PathRef(Path(f), quick = true)) - ) - ) - } - else { - val dep = scalaJSLinkerIvyDep(scalaJSBridgeVersion()) - resolveDependencies( - repositories, - scalaVersion(), - scalaBinaryVersion(), - Seq(dep) - ) - } + if (jsBridgePath != null) Success( + PathRef(Path(jsBridgePath), quick = true) + ) else resolveDependencies( + Seq(MavenRepository("https://repo1.maven.org/maven2")), + "2.12.4", + "2.12", + Seq(Dep( + "com.lihaoyi", + s"mill-jsbridge_${scalaJSBridgeVersion().replace('.', '_')}", + "0.1-SNAPSHOT" + )) + ).map(_.find(_.path.toString.contains("mill-jsbridge")).get) } - def fastOpt = T{ - val linker = scalaJSLinkerBridge(scalaJSLinkerClasspath().map(_.path)) - link(mainClass(), Seq(compile().classes.path), compileDepClasspath().map(_.path), linker, FastOpt) + + def scalaJSLinkerClasspath: T[Loose.Agg[PathRef]] = T{ + resolveDependencies( + repositories, + "2.12.4", + "2.12", + Seq(ivy"org.scala-js::scalajs-tools:${scalaJSVersion()}") + ) } - def fullOpt = T{ - val linker = scalaJSLinkerBridge(scalaJSLinkerClasspath().map(_.path)) - link(mainClass(), Seq(compile().classes.path), compileDepClasspath().map(_.path), linker, FullOpt) + def genericOpt(mode: OptimizeMode) = T.task{ + val outputPath = T.ctx().dest / "out.js" + + mkdir(T.ctx().dest) + rm(outputPath) + val inputFiles = Agg.from(ls(compile().classes.path).filter(_.ext == "sjsir")) + val inputLibraries = compileDepClasspath().map(_.path).filter(_.ext == "jar") + mill.scalajslib.ScalaJSLinkerBridge.scalaJSLinkerBridge().link( + (Agg(sjsLinkerBridgeClasspath()) ++ scalaJSLinkerClasspath()).map(_.path), + inputFiles, + inputLibraries, + outputPath.toIO, + mainClass(), + mode == FullOpt + ) + PathRef(outputPath) } + def fastOpt = T{ genericOpt(FastOpt)() } + + def fullOpt = T{ genericOpt(FullOpt)() } + override def scalacPluginIvyDeps = T{ Loose.Agg(Dep.Point("org.scala-js", "scalajs-compiler", scalaJSVersion())) } override def ivyDeps = T{ Loose.Agg(Dep("org.scala-js", "scalajs-library", scalaJSVersion())) } diff --git a/scalaworker/src/mill/scalaworker/ScalaWorker.scala b/scalaworker/src/mill/scalaworker/ScalaWorker.scala index 6c6cb504..dfb8892a 100644 --- a/scalaworker/src/mill/scalaworker/ScalaWorker.scala +++ b/scalaworker/src/mill/scalaworker/ScalaWorker.scala @@ -32,7 +32,7 @@ case class MockedLookup(am: File => Optional[CompileAnalysis]) extends PerClassp Locate.definesClass(classpathEntry) } -object ScalaWorker{ +object ScalaWorker{ def main(args: Array[String]): Unit = { try{ |