summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-04-06 23:02:29 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2018-04-07 09:04:55 -0700
commit953321ead7b278912529ef34b50e403d1e533c05 (patch)
tree6cfcba4688c107e0b67e72d19cb6e4db5e80ebd5
parent35d3c4bb09d198225c5419d7ee61e626770cec90 (diff)
downloadmill-953321ead7b278912529ef34b50e403d1e533c05.tar.gz
mill-953321ead7b278912529ef34b50e403d1e533c05.tar.bz2
mill-953321ead7b278912529ef34b50e403d1e533c05.zip
First pass splitting `JavaModule` out of `ScalaModule`
-rw-r--r--scalalib/src/mill/scalalib/GenIdea.scala30
-rw-r--r--scalalib/src/mill/scalalib/JavaModule.scala274
-rw-r--r--scalalib/src/mill/scalalib/Lib.scala2
-rw-r--r--scalalib/src/mill/scalalib/ScalaModule.scala208
4 files changed, 300 insertions, 214 deletions
diff --git a/scalalib/src/mill/scalalib/GenIdea.scala b/scalalib/src/mill/scalalib/GenIdea.scala
index b118f29b..a67668e4 100644
--- a/scalalib/src/mill/scalalib/GenIdea.scala
+++ b/scalalib/src/mill/scalalib/GenIdea.scala
@@ -62,7 +62,7 @@ object GenIdea {
fetchMillModules: Boolean = true): Seq[(RelPath, scala.xml.Node)] = {
val modules = rootModule.millInternal.segmentsToModules.values
- .collect{ case x: scalalib.ScalaModule => (x.millModuleSegments, x)}
+ .collect{ case x: scalalib.JavaModule => (x.millModuleSegments, x)}
.toSeq
val buildLibraryPaths =
@@ -70,7 +70,7 @@ object GenIdea {
else sys.props.get("MILL_BUILD_LIBRARIES") match {
case Some(found) => Agg.from(found.split(',').map(Path(_)).distinct)
case None =>
- val repos = modules.foldLeft(Set.empty[Repository]) { _ ++ _._2.scalaWorker.repositories }
+ val repos = modules.foldLeft(Set.empty[Repository]) { _ ++ _._2.repositories }
val artifactNames = Seq("moduledefs", "core", "scalalib", "scalajslib")
val Result.Success(res) = scalalib.Lib.resolveDependencies(
repos.toList,
@@ -82,7 +82,7 @@ object GenIdea {
}
val resolved = for((path, mod) <- modules) yield {
- val allIvyDeps = T.task{mod.transitiveIvyDeps() ++ mod.scalaLibraryIvyDeps() ++ mod.compileIvyDeps()}
+ val allIvyDeps = T.task{mod.transitiveIvyDeps() ++ mod.compileIvyDeps()}
val externalDependencies = T.task{
mod.resolveDeps(allIvyDeps)() ++
Task.traverse(mod.transitiveModuleDeps)(_.unmanagedClasspath)().flatten
@@ -92,8 +92,10 @@ object GenIdea {
mod.resolveDeps(allIvyDeps, sources = true)()
}
- val scalacPluginsIvyDeps = T.task{mod.scalacPluginIvyDeps()}
- val scalacOptions = T.task{mod.scalacOptions()}
+ val (scalacPluginsIvyDeps, scalacOptions) = mod match{
+ case mod: ScalaModule => T.task{mod.scalacPluginIvyDeps()} -> T.task{mod.scalacOptions()}
+ case _ => T.task(Loose.Agg[Dep]()) -> T.task(Seq())
+ }
val scalacPluginDependencies = T.task{
mod.resolveDeps(scalacPluginsIvyDeps)()
}
@@ -134,7 +136,7 @@ object GenIdea {
.toMap
val compilerSettings = resolved
- .foldLeft(Map[(Loose.Agg[Path], Seq[String]), Vector[ScalaModule]]()) {
+ .foldLeft(Map[(Loose.Agg[Path], Seq[String]), Vector[JavaModule]]()) {
(r, q) =>
val key = (q._4, q._5)
r + (key -> (r.getOrElse(key, Vector()) :+ q._3))
@@ -190,7 +192,10 @@ object GenIdea {
evaluator.outPath,
mod.compile.ctx.segments
)
- val Seq(scalaVersion: String) = evaluator.evaluate(Agg(mod.scalaVersion)).values
+ val scalaVersionOpt = mod match {
+ case x: ScalaModule => Some(evaluator.evaluate(Agg(x.scalaVersion)).values.head.asInstanceOf[String])
+ case _ => None
+ }
val generatedSourceOutPath = Evaluator.resolveDestPaths(
evaluator.outPath,
mod.generatedSources.ctx.segments
@@ -198,7 +203,7 @@ object GenIdea {
val elem = moduleXmlTemplate(
mod.millModuleBasePath.value,
- scalaVersion,
+ scalaVersionOpt,
Strict.Agg.from(resourcesPathRefs.map(_.path)),
Strict.Agg.from(normalSourcePaths),
Strict.Agg.from(generatedSourcePaths),
@@ -293,7 +298,7 @@ object GenIdea {
</component>
}
def moduleXmlTemplate(basePath: Path,
- scalaVersion: String,
+ scalaVersionOpt: Option[String],
resourcePaths: Strict.Agg[Path],
normalSourcePaths: Strict.Agg[Path],
generatedSourcePaths: Strict.Agg[Path],
@@ -326,7 +331,10 @@ object GenIdea {
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name={s"scala-sdk-$scalaVersion"} level="application" />
+ {
+ for(scalaVersion <- scalaVersionOpt.toSeq)
+ yield <orderEntry type="library" name={s"scala-sdk-$scalaVersion"} level="application" />
+ }
{
for(name <- libNames.toSeq.sorted)
@@ -340,7 +348,7 @@ object GenIdea {
</component>
</module>
}
- def scalaCompilerTemplate(settings: Map[(Loose.Agg[Path], Seq[String]), Seq[ScalaModule]]) = {
+ def scalaCompilerTemplate(settings: Map[(Loose.Agg[Path], Seq[String]), Seq[JavaModule]]) = {
<project version="4">
<component name="ScalaCompilerConfiguration">
diff --git a/scalalib/src/mill/scalalib/JavaModule.scala b/scalalib/src/mill/scalalib/JavaModule.scala
new file mode 100644
index 00000000..0b043bb4
--- /dev/null
+++ b/scalalib/src/mill/scalalib/JavaModule.scala
@@ -0,0 +1,274 @@
+package mill
+package scalalib
+
+import ammonite.ops._
+import coursier.{Dependency, Repository}
+import mill.define.Task
+import mill.define.TaskModule
+import mill.eval.{PathRef, Result}
+import mill.modules.Jvm
+import mill.modules.Jvm.{createAssembly, createJar, subprocess}
+import Lib._
+import mill.util.Loose.Agg
+import mill.util.DummyInputStream
+
+/**
+ * Core configuration required to compile a single Scala compilation target
+ */
+trait JavaModule extends mill.Module with TaskModule { outer =>
+ def defaultCommandName() = "run"
+
+ def mainClass: T[Option[String]] = None
+
+ def finalMainClassOpt: T[Either[String, String]] = T{
+ mainClass() match{
+ case Some(m) => Right(m)
+ case None => Left("No main class specified or found")
+ }
+ }
+
+ def finalMainClass: T[String] = T{
+ finalMainClassOpt() match {
+ case Right(main) => Result.Success(main)
+ case Left(msg) => Result.Failure(msg)
+ }
+ }
+
+ def ivyDeps = T{ Agg.empty[Dep] }
+ def compileIvyDeps = T{ Agg.empty[Dep] }
+ def runIvyDeps = T{ Agg.empty[Dep] }
+
+ def javacOptions = T{ Seq.empty[String] }
+
+ def moduleDeps = Seq.empty[JavaModule]
+
+
+ def transitiveModuleDeps: Seq[JavaModule] = {
+ Seq(this) ++ moduleDeps.flatMap(_.transitiveModuleDeps).distinct
+ }
+ def unmanagedClasspath = T{ Agg.empty[PathRef] }
+
+
+ def transitiveIvyDeps: T[Agg[Dep]] = T{
+ ivyDeps() ++ Task.traverse(moduleDeps)(_.transitiveIvyDeps)().flatten
+ }
+
+ def upstreamCompileOutput = T{
+ Task.traverse(moduleDeps)(_.compile)
+ }
+
+ def transitiveLocalClasspath: T[Agg[PathRef]] = T{
+ Task.traverse(moduleDeps)(m =>
+ T.task{m.localClasspath() ++ m.transitiveLocalClasspath()}
+ )().flatten
+ }
+
+ def mapDependencies(d: coursier.Dependency) = d
+
+ def resolveDeps(deps: Task[Agg[Dep]], sources: Boolean = false) = T.task{
+ resolveDependencies(
+ repositories,
+ "???",
+ deps(),
+ platformSuffix(),
+ sources,
+ mapDependencies = Some(mapDependencies)
+ )
+ }
+
+
+ def repositories: Seq[Repository] = ScalaWorkerModule.repositories
+
+ def platformSuffix = T{ "" }
+
+ private val Milestone213 = raw"""2.13.(\d+)-M(\d+)""".r
+
+ def prependShellScript: T[String] = T{
+ mainClass() match{
+ case None => ""
+ case Some(cls) =>
+ val isWin = scala.util.Properties.isWin
+ mill.modules.Jvm.launcherUniversalScript(
+ cls,
+ Agg("$0"), Agg("%~dpnx0"),
+ forkArgs()
+ )
+ }
+ }
+
+ def sources = T.sources{ millSourcePath / 'src }
+ def resources = T.sources{ millSourcePath / 'resources }
+ def generatedSources = T{ Seq.empty[PathRef] }
+ def allSources = T{ sources() ++ generatedSources() }
+
+ def allSourceFiles = T{
+ for {
+ root <- allSources()
+ if exists(root.path)
+ path <- ls.rec(root.path)
+ if path.isFile && (path.ext == "scala" || path.ext == "java")
+ } yield PathRef(path)
+ }
+
+ def compile: T[CompilationResult] = T.persistent{
+// scalaWorker.worker().compileScala(
+// scalaVersion(),
+// allSourceFiles().map(_.path),
+// scalaCompilerBridgeSources(),
+// compileClasspath().map(_.path),
+// scalaCompilerClasspath().map(_.path),
+// scalacOptions(),
+// scalacPluginClasspath().map(_.path),
+// javacOptions(),
+// upstreamCompileOutput()
+// )
+ Result.Failure[CompilationResult]("???", None)
+ }
+ def localClasspath = T{
+ resources() ++ Agg(compile().classes)
+ }
+ def compileClasspath = T{
+ transitiveLocalClasspath() ++
+ resources() ++
+ unmanagedClasspath() ++
+ resolveDeps(T.task{compileIvyDeps() ++ transitiveIvyDeps()})()
+ }
+
+ def upstreamAssemblyClasspath = T{
+ transitiveLocalClasspath() ++
+ unmanagedClasspath() ++
+ resolveDeps(T.task{runIvyDeps() ++ transitiveIvyDeps()})()
+ }
+
+ def runClasspath = T{
+ localClasspath() ++
+ upstreamAssemblyClasspath()
+ }
+
+ /**
+ * Build the assembly for upstream dependencies separate from the current classpath
+ *
+ * This should allow much faster assembly creation in the common case where
+ * upstream dependencies do not change
+ */
+ def upstreamAssembly = T{
+ createAssembly(upstreamAssemblyClasspath().map(_.path), mainClass())
+ }
+
+ def assembly = T{
+ createAssembly(
+ Agg.from(localClasspath().map(_.path)),
+ mainClass(),
+ prependShellScript(),
+ Some(upstreamAssembly().path)
+ )
+ }
+
+
+ def jar = T{
+ createJar(
+ localClasspath().map(_.path).filter(exists),
+ mainClass()
+ )
+ }
+
+ def docJar = T[PathRef] {
+// val outDir = T.ctx().dest
+//
+// val javadocDir = outDir / 'javadoc
+// mkdir(javadocDir)
+//
+// val files = for{
+// ref <- allSources()
+// if exists(ref.path)
+// p <- ls.rec(ref.path)
+// if p.isFile
+// } yield p.toNIO.toString
+//
+// val options = Seq("-d", javadocDir.toNIO.toString, "-usejavacp")
+//
+// if (files.nonEmpty) subprocess(
+// "scala.tools.nsc.ScalaDoc",
+// scalaCompilerClasspath().map(_.path) ++ compileClasspath().filter(_.path.ext != "pom").map(_.path),
+// mainArgs = (files ++ options).toSeq
+// )
+//
+//
+// createJar(Agg(javadocDir))(outDir)
+ Result.Failure[PathRef]("", None)
+ }
+
+ def sourceJar = T {
+ createJar((allSources() ++ resources()).map(_.path).filter(exists))
+ }
+
+ def forkArgs = T{ Seq.empty[String] }
+
+ def forkEnv = T{ sys.env.toMap }
+
+ def launcher = T{
+ Result.Success(
+ Jvm.createLauncher(
+ finalMainClass(),
+ runClasspath().map(_.path),
+ forkArgs()
+ )
+ )
+ }
+
+ def ivyDepsTree(inverse: Boolean = false) = T.command {
+ val (flattened, resolution) = Lib.resolveDependenciesMetadata(
+ repositories, "???", ivyDeps(), platformSuffix(), Some(mapDependencies)
+ )
+
+ println(coursier.util.Print.dependencyTree(flattened, resolution,
+ printExclusions = false, reverse = inverse))
+
+ Result.Success()
+ }
+
+ def runLocal(args: String*) = T.command {
+ Jvm.runLocal(
+ finalMainClass(),
+ runClasspath().map(_.path),
+ args
+ )
+ }
+
+ def run(args: String*) = T.command{
+ Jvm.interactiveSubprocess(
+ finalMainClass(),
+ runClasspath().map(_.path),
+ forkArgs(),
+ forkEnv(),
+ args,
+ workingDir = ammonite.ops.pwd
+ )
+ }
+
+
+ def runMainLocal(mainClass: String, args: String*) = T.command {
+ Jvm.runLocal(
+ mainClass,
+ runClasspath().map(_.path),
+ args
+ )
+ }
+
+ def runMain(mainClass: String, args: String*) = T.command{
+ Jvm.interactiveSubprocess(
+ mainClass,
+ runClasspath().map(_.path),
+ forkArgs(),
+ forkEnv(),
+ args,
+ workingDir = ammonite.ops.pwd
+ )
+ }
+
+ // publish artifact with name "mill_2.12.4" instead of "mill_2.12"
+
+ def artifactName: T[String] = millModuleSegments.parts.mkString("-")
+
+ def artifactSuffix: T[String] = T { "" }
+} \ No newline at end of file
diff --git a/scalalib/src/mill/scalalib/Lib.scala b/scalalib/src/mill/scalalib/Lib.scala
index 46296333..26c9a0df 100644
--- a/scalalib/src/mill/scalalib/Lib.scala
+++ b/scalalib/src/mill/scalalib/Lib.scala
@@ -97,7 +97,7 @@ object Lib{
* `import $ivy` syntax.
*/
def resolveDependencies(repositories: Seq[Repository],
- scalaVersion: String,
+ scalaVersion: => String,
deps: TraversableOnce[Dep],
platformSuffix: String = "",
sources: Boolean = false,
diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala
index c0ef6cce..6997c368 100644
--- a/scalalib/src/mill/scalalib/ScalaModule.scala
+++ b/scalalib/src/mill/scalalib/ScalaModule.scala
@@ -15,8 +15,7 @@ import mill.util.DummyInputStream
/**
* Core configuration required to compile a single Scala compilation target
*/
-trait ScalaModule extends mill.Module with TaskModule { outer =>
- def defaultCommandName() = "run"
+trait ScalaModule extends JavaModule { outer =>
trait Tests extends TestModule{
def scalaVersion = outer.scalaVersion()
override def repositories = outer.repositories
@@ -28,11 +27,9 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
}
def scalaVersion: T[String]
- def mainClass: T[Option[String]] = None
-
def scalaWorker: ScalaWorkerModule = mill.scalalib.ScalaWorkerModule
- def finalMainClassOpt: T[Either[String, String]] = T{
+ override def finalMainClassOpt: T[Either[String, String]] = T{
mainClass() match{
case Some(m) => Right(m)
case None =>
@@ -48,61 +45,12 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
}
}
- def finalMainClass: T[String] = T{
- finalMainClassOpt() match {
- case Right(main) => Result.Success(main)
- case Left(msg) => Result.Failure(msg)
- }
- }
- def ivyDeps = T{ Agg.empty[Dep] }
- def compileIvyDeps = T{ Agg.empty[Dep] }
def scalacPluginIvyDeps = T{ Agg.empty[Dep] }
- def runIvyDeps = T{ Agg.empty[Dep] }
def scalacOptions = T{ Seq.empty[String] }
- def javacOptions = T{ Seq.empty[String] }
-
- def moduleDeps = Seq.empty[ScalaModule]
-
-
- def transitiveModuleDeps: Seq[ScalaModule] = {
- Seq(this) ++ moduleDeps.flatMap(_.transitiveModuleDeps).distinct
- }
- def unmanagedClasspath = T{ Agg.empty[PathRef] }
-
-
- def transitiveIvyDeps: T[Agg[Dep]] = T{
- ivyDeps() ++ Task.traverse(moduleDeps)(_.transitiveIvyDeps)().flatten
- }
-
- def upstreamCompileOutput = T{
- Task.traverse(moduleDeps)(_.compile)
- }
-
- def transitiveLocalClasspath: T[Agg[PathRef]] = T{
- Task.traverse(moduleDeps)(m =>
- T.task{m.localClasspath() ++ m.transitiveLocalClasspath()}
- )().flatten
- }
-
- def mapDependencies(d: coursier.Dependency) = d
-
- def resolveDeps(deps: Task[Agg[Dep]], sources: Boolean = false) = T.task{
- resolveDependencies(
- repositories,
- scalaVersion(),
- deps(),
- platformSuffix(),
- sources,
- mapDependencies = Some(mapDependencies)
- )
- }
-
- def repositories: Seq[Repository] = scalaWorker.repositories
-
- def platformSuffix = T{ "" }
+ override def repositories: Seq[Repository] = scalaWorker.repositories
private val Milestone213 = raw"""2.13.(\d+)-M(\d+)""".r
@@ -134,35 +82,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
)()
}
-
- def prependShellScript: T[String] = T{
- mainClass() match{
- case None => ""
- case Some(cls) =>
- val isWin = scala.util.Properties.isWin
- mill.modules.Jvm.launcherUniversalScript(
- cls,
- Agg("$0"), Agg("%~dpnx0"),
- forkArgs()
- )
- }
- }
-
- def sources = T.sources{ millSourcePath / 'src }
- def resources = T.sources{ millSourcePath / 'resources }
- def generatedSources = T{ Seq.empty[PathRef] }
- def allSources = T{ sources() ++ generatedSources() }
-
- def allSourceFiles = T{
- for {
- root <- allSources()
- if exists(root.path)
- path <- ls.rec(root.path)
- if path.isFile && (path.ext == "scala" || path.ext == "java")
- } yield PathRef(path)
- }
-
- def compile: T[CompilationResult] = T.persistent{
+ override def compile: T[CompilationResult] = T.persistent{
scalaWorker.worker().compileScala(
scalaVersion(),
allSourceFiles().map(_.path),
@@ -175,55 +95,8 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
upstreamCompileOutput()
)
}
- def localClasspath = T{
- resources() ++ Agg(compile().classes)
- }
- def compileClasspath = T{
- transitiveLocalClasspath() ++
- resources() ++
- unmanagedClasspath() ++
- resolveDeps(T.task{compileIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps()})()
- }
-
- def upstreamAssemblyClasspath = T{
- transitiveLocalClasspath() ++
- unmanagedClasspath() ++
- resolveDeps(T.task{runIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps()})()
- }
-
- def runClasspath = T{
- localClasspath() ++
- upstreamAssemblyClasspath()
- }
-
- /**
- * Build the assembly for upstream dependencies separate from the current classpath
- *
- * This should allow much faster assembly creation in the common case where
- * upstream dependencies do not change
- */
- def upstreamAssembly = T{
- createAssembly(upstreamAssemblyClasspath().map(_.path), mainClass())
- }
-
- def assembly = T{
- createAssembly(
- Agg.from(localClasspath().map(_.path)),
- mainClass(),
- prependShellScript(),
- Some(upstreamAssembly().path)
- )
- }
-
- def jar = T{
- createJar(
- localClasspath().map(_.path).filter(exists),
- mainClass()
- )
- }
-
- def docJar = T {
+ override def docJar = T {
val outDir = T.ctx().dest
val javadocDir = outDir / 'javadoc
@@ -247,74 +120,6 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
createJar(Agg(javadocDir))(outDir)
}
- def sourceJar = T {
- createJar((allSources() ++ resources()).map(_.path).filter(exists))
- }
-
- def forkArgs = T{ Seq.empty[String] }
-
- def forkEnv = T{ sys.env.toMap }
-
- def launcher = T{
- Result.Success(
- Jvm.createLauncher(
- finalMainClass(),
- runClasspath().map(_.path),
- forkArgs()
- )
- )
- }
-
- def ivyDepsTree(inverse: Boolean = false) = T.command {
- val (flattened, resolution) = Lib.resolveDependenciesMetadata(
- repositories, scalaVersion(), ivyDeps(), platformSuffix(), Some(mapDependencies)
- )
-
- println(coursier.util.Print.dependencyTree(flattened, resolution,
- printExclusions = false, reverse = inverse))
-
- Result.Success()
- }
-
- def runLocal(args: String*) = T.command {
- Jvm.runLocal(
- finalMainClass(),
- runClasspath().map(_.path),
- args
- )
- }
-
- def run(args: String*) = T.command{
- Jvm.interactiveSubprocess(
- finalMainClass(),
- runClasspath().map(_.path),
- forkArgs(),
- forkEnv(),
- args,
- workingDir = ammonite.ops.pwd
- )
- }
-
-
- def runMainLocal(mainClass: String, args: String*) = T.command {
- Jvm.runLocal(
- mainClass,
- runClasspath().map(_.path),
- args
- )
- }
-
- def runMain(mainClass: String, args: String*) = T.command{
- Jvm.interactiveSubprocess(
- mainClass,
- runClasspath().map(_.path),
- forkArgs(),
- forkEnv(),
- args,
- workingDir = ammonite.ops.pwd
- )
- }
-
def console() = T.command{
if (T.ctx().log.inStream == DummyInputStream){
Result.Failure("repl needs to be run with the -i/--interactive flag")
@@ -361,9 +166,8 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
if (crossFullScalaVersion()) scalaVersion()
else Lib.scalaBinaryVersion(scalaVersion())
}
- def artifactName: T[String] = millModuleSegments.parts.mkString("-")
- def artifactSuffix: T[String] = T { s"_${artifactScalaVersion()}" }
+ override def artifactSuffix: T[String] = T { s"_${artifactScalaVersion()}" }
}