summaryrefslogtreecommitdiff
path: root/scalalib
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-04-07 07:24:47 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2018-04-07 09:04:55 -0700
commit3e43a5f3b56ed65ec9ce0d68b28033b71da5a06f (patch)
treea39394ea100eca1bafb551c793075e475a26ddd3 /scalalib
parent953321ead7b278912529ef34b50e403d1e533c05 (diff)
downloadmill-3e43a5f3b56ed65ec9ce0d68b28033b71da5a06f.tar.gz
mill-3e43a5f3b56ed65ec9ce0d68b28033b71da5a06f.tar.bz2
mill-3e43a5f3b56ed65ec9ce0d68b28033b71da5a06f.zip
First unit tests for `JavaModule`
Diffstat (limited to 'scalalib')
-rw-r--r--scalalib/src/mill/scalalib/GenIdea.scala33
-rw-r--r--scalalib/src/mill/scalalib/JavaModule.scala79
-rw-r--r--scalalib/src/mill/scalalib/ScalaModule.scala36
-rw-r--r--scalalib/src/mill/scalalib/ScalaWorkerApi.scala6
-rw-r--r--scalalib/test/resources/hello-java/core/src/hello/Core.java8
-rw-r--r--scalalib/test/resources/hello-java/main/src/hello/Main.java7
-rw-r--r--scalalib/test/src/mill/scalalib/HelloJavaTests.scala60
7 files changed, 181 insertions, 48 deletions
diff --git a/scalalib/src/mill/scalalib/GenIdea.scala b/scalalib/src/mill/scalalib/GenIdea.scala
index a67668e4..183d4a79 100644
--- a/scalalib/src/mill/scalalib/GenIdea.scala
+++ b/scalalib/src/mill/scalalib/GenIdea.scala
@@ -68,7 +68,7 @@ object GenIdea {
val buildLibraryPaths =
if (!fetchMillModules) Nil
else sys.props.get("MILL_BUILD_LIBRARIES") match {
- case Some(found) => Agg.from(found.split(',').map(Path(_)).distinct)
+ case Some(found) => found.split(',').map(Path(_)).distinct.toList
case None =>
val repos = modules.foldLeft(Set.empty[Repository]) { _ ++ _._2.repositories }
val artifactNames = Seq("moduledefs", "core", "scalalib", "scalajslib")
@@ -78,11 +78,15 @@ object GenIdea {
for(name <- artifactNames)
yield ivy"com.lihaoyi::mill-$name:${sys.props("MILL_VERSION")}"
)
- res.items.toSeq.map(_.path)
+ res.items.toList.map(_.path)
}
val resolved = for((path, mod) <- modules) yield {
- val allIvyDeps = T.task{mod.transitiveIvyDeps() ++ mod.compileIvyDeps()}
+ val scalaLibraryIvyDeps = mod match{
+ case x: ScalaModule => x.scalaLibraryIvyDeps
+ case _ => T.task{Nil}
+ }
+ val allIvyDeps = T.task{mod.transitiveIvyDeps() ++ scalaLibraryIvyDeps() ++ mod.compileIvyDeps()}
val externalDependencies = T.task{
mod.resolveDeps(allIvyDeps)() ++
Task.traverse(mod.transitiveModuleDeps)(_.unmanagedClasspath)().flatten
@@ -105,18 +109,27 @@ object GenIdea {
val resolvedSp: Loose.Agg[PathRef] = evalOrElse(evaluator, scalacPluginDependencies, Loose.Agg.empty)
val scalacOpts: Seq[String] = evalOrElse(evaluator, scalacOptions, Seq())
- (path, resolvedCp.map(_.path).filter(_.ext == "jar") ++ resolvedSrcs.map(_.path), mod,
- resolvedSp.map(_.path).filter(_.ext == "jar"), scalacOpts)
+ (
+ path,
+ resolvedCp.map(_.path).filter(_.ext == "jar") ++ resolvedSrcs.map(_.path),
+ mod,
+ resolvedSp.map(_.path).filter(_.ext == "jar"),
+ scalacOpts
+ )
}
val moduleLabels = modules.map(_.swap).toMap
val allResolved = resolved.flatMap(_._2) ++ buildLibraryPaths
- val minResolvedLength = allResolved.map(_.segments.length).min
- val commonPrefix = allResolved.map(_.segments.take(minResolvedLength))
- .transpose
- .takeWhile(_.distinct.length == 1)
- .length
+ val commonPrefix =
+ if (allResolved.isEmpty) 0
+ else {
+ val minResolvedLength = allResolved.map(_.segments.length).min
+ allResolved.map(_.segments.take(minResolvedLength))
+ .transpose
+ .takeWhile(_.distinct.length == 1)
+ .length
+ }
// only resort to full long path names if the jar name is a duplicate
val pathShortLibNameDuplicate = allResolved
diff --git a/scalalib/src/mill/scalalib/JavaModule.scala b/scalalib/src/mill/scalalib/JavaModule.scala
index 0b043bb4..19b81d43 100644
--- a/scalalib/src/mill/scalalib/JavaModule.scala
+++ b/scalalib/src/mill/scalalib/JavaModule.scala
@@ -1,12 +1,16 @@
package mill
package scalalib
+import java.nio.charset.Charset
+import java.util
+import javax.tools.{JavaFileObject, SimpleJavaFileObject, StandardJavaFileManager, ToolProvider}
+
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, Util}
import mill.modules.Jvm.{createAssembly, createJar, subprocess}
import Lib._
import mill.util.Loose.Agg
@@ -16,6 +20,8 @@ import mill.util.DummyInputStream
* Core configuration required to compile a single Scala compilation target
*/
trait JavaModule extends mill.Module with TaskModule { outer =>
+ def scalaWorker: ScalaWorkerModule = mill.scalalib.ScalaWorkerModule
+
def defaultCommandName() = "run"
def mainClass: T[Option[String]] = None
@@ -110,19 +116,13 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
} 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 compile: T[CompilationResult] = T{
+ scalaWorker.worker().compileJava(
+ allSourceFiles().map(_.path.toIO).toArray,
+ compileClasspath().map(_.path.toIO).toArray,
+ javacOptions(),
+ upstreamCompileOutput()
+ )
}
def localClasspath = T{
resources() ++ Agg(compile().classes)
@@ -173,29 +173,34 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
}
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)
+ 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)
+
+ if (files.nonEmpty) Jvm.baseInteractiveSubprocess(
+ commandArgs = Seq(
+ "javadoc"
+ ) ++ options ++
+ Seq(
+ "-classpath",
+ compileClasspath().filter(_.path.ext != "pom").mkString(java.io.File.pathSeparator)
+ ) ++
+ files.map(_.toString),
+ envArgs = Map(),
+ workingDir = T.ctx().dest
+ )
+
+ createJar(Agg(javadocDir))(outDir)
}
def sourceJar = T {
diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala
index 6997c368..b3013d57 100644
--- a/scalalib/src/mill/scalalib/ScalaModule.scala
+++ b/scalalib/src/mill/scalalib/ScalaModule.scala
@@ -27,7 +27,7 @@ trait ScalaModule extends JavaModule { outer =>
}
def scalaVersion: T[String]
- def scalaWorker: ScalaWorkerModule = mill.scalalib.ScalaWorkerModule
+
override def finalMainClassOpt: T[Either[String, String]] = T{
mainClass() match{
@@ -81,6 +81,18 @@ trait ScalaModule extends JavaModule { outer =>
T.task{scalaCompilerIvyDeps(scalaVersion()) ++ scalaRuntimeIvyDeps(scalaVersion())}
)()
}
+ override def compileClasspath = T{
+ transitiveLocalClasspath() ++
+ resources() ++
+ unmanagedClasspath() ++
+ resolveDeps(T.task{compileIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps()})()
+ }
+
+ override def upstreamAssemblyClasspath = T{
+ transitiveLocalClasspath() ++
+ unmanagedClasspath() ++
+ resolveDeps(T.task{runIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps()})()
+ }
override def compile: T[CompilationResult] = T.persistent{
scalaWorker.worker().compileScala(
@@ -96,6 +108,17 @@ trait ScalaModule extends JavaModule { outer =>
)
}
+ override 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()
+ }
+
override def docJar = T {
val outDir = T.ctx().dest
@@ -134,6 +157,17 @@ trait ScalaModule extends JavaModule { outer =>
}
}
+ override def resolveDeps(deps: Task[Agg[Dep]], sources: Boolean = false) = T.task{
+ resolveDependencies(
+ repositories,
+ scalaVersion(),
+ deps(),
+ platformSuffix(),
+ sources,
+ mapDependencies = Some(mapDependencies)
+ )
+ }
+
def ammoniteReplClasspath = T{
localClasspath() ++
transitiveLocalClasspath() ++
diff --git a/scalalib/src/mill/scalalib/ScalaWorkerApi.scala b/scalalib/src/mill/scalalib/ScalaWorkerApi.scala
index 9739089a..7b8f2a20 100644
--- a/scalalib/src/mill/scalalib/ScalaWorkerApi.scala
+++ b/scalalib/src/mill/scalalib/ScalaWorkerApi.scala
@@ -56,6 +56,12 @@ trait ScalaWorkerModule extends mill.Module{
}
trait ScalaWorkerApi {
+ def compileJava(sources: Array[java.io.File],
+ classpath: Array[java.io.File],
+ javaOpts: Seq[String],
+ upstreamCompileOutput: Seq[CompilationResult])
+ (implicit ctx: mill.util.Ctx): mill.eval.Result[CompilationResult]
+
def compileScala(scalaVersion: String,
sources: Agg[Path],
compilerBridgeSources: Path,
diff --git a/scalalib/test/resources/hello-java/core/src/hello/Core.java b/scalalib/test/resources/hello-java/core/src/hello/Core.java
new file mode 100644
index 00000000..bef1a5a0
--- /dev/null
+++ b/scalalib/test/resources/hello-java/core/src/hello/Core.java
@@ -0,0 +1,8 @@
+package hello;
+
+public class Core{
+ public static String msg(){
+ return "Hello World";
+ }
+
+} \ No newline at end of file
diff --git a/scalalib/test/resources/hello-java/main/src/hello/Main.java b/scalalib/test/resources/hello-java/main/src/hello/Main.java
new file mode 100644
index 00000000..44b927bd
--- /dev/null
+++ b/scalalib/test/resources/hello-java/main/src/hello/Main.java
@@ -0,0 +1,7 @@
+package hello;
+
+public class Main{
+ public static void main(String[] args){
+ System.out.println(Core.msg() + " " + args[0]);
+ }
+} \ No newline at end of file
diff --git a/scalalib/test/src/mill/scalalib/HelloJavaTests.scala b/scalalib/test/src/mill/scalalib/HelloJavaTests.scala
new file mode 100644
index 00000000..7794d5a5
--- /dev/null
+++ b/scalalib/test/src/mill/scalalib/HelloJavaTests.scala
@@ -0,0 +1,60 @@
+package mill.scalalib
+
+
+import ammonite.ops.{%, %%, cp, ls, mkdir, pwd, rm, up}
+import ammonite.ops.ImplicitWd._
+import mill.util.{TestEvaluator, TestUtil}
+import utest._
+import utest.framework.TestPath
+
+
+object HelloJavaTests extends TestSuite {
+
+ object HelloJava extends TestUtil.BaseModule{
+ def millSourcePath = TestUtil.getSrcPathBase() / millOuterCtx.enclosing.split('.')
+ object core extends JavaModule
+ object main extends JavaModule{
+ def moduleDeps = Seq(core)
+ }
+ }
+ val resourcePath = pwd / 'scalalib / 'test / 'resources / "hello-java"
+
+ def init()(implicit tp: TestPath) = {
+ val eval = new TestEvaluator(HelloJava)
+ rm(HelloJava.millSourcePath)
+ rm(eval.outPath)
+ mkdir(HelloJava.millSourcePath / up)
+ cp(resourcePath, HelloJava.millSourcePath)
+ eval
+ }
+ def tests: Tests = Tests {
+ 'scalaVersion - {
+ val eval = init()
+
+ val Right((res1, n1)) = eval.apply(HelloJava.core.compile)
+ val Right((res2, 0)) = eval.apply(HelloJava.core.compile)
+ val Right((res3, n2)) = eval.apply(HelloJava.main.compile)
+
+ assert(
+ res1 == res2,
+ n1 != 0,
+ n2 != 0,
+ ls.rec(res1.classes.path).exists(_.last == "Core.class"),
+ !ls.rec(res1.classes.path).exists(_.last == "Main.class"),
+ ls.rec(res3.classes.path).exists(_.last == "Main.class"),
+ !ls.rec(res3.classes.path).exists(_.last == "Core.class")
+ )
+ }
+ 'docJar - {
+ val eval = init()
+
+ val Right((ref1, _)) = eval.apply(HelloJava.core.docJar)
+ val Right((ref2, _)) = eval.apply(HelloJava.main.docJar)
+
+ assert(
+ %%("jar", "tf", ref1.path).out.lines.contains("hello/Core.html"),
+ %%("jar", "tf", ref2.path).out.lines.contains("hello/Main.html")
+ )
+ }
+ }
+}