summaryrefslogtreecommitdiff
path: root/scalalib
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-09-20 14:15:50 +0800
committerGitHub <noreply@github.com>2018-09-20 14:15:50 +0800
commitd551ee9d751201491a1d64e4da76ab03e3815df6 (patch)
tree60471609f0957401fa1a7002578ad8c1acd6bc75 /scalalib
parentc8fd6bd9e1dc18c24e64147fcd221e0bf91c2d06 (diff)
downloadmill-d551ee9d751201491a1d64e4da76ab03e3815df6.tar.gz
mill-d551ee9d751201491a1d64e4da76ab03e3815df6.tar.bz2
mill-d551ee9d751201491a1d64e4da76ab03e3815df6.zip
Include scaladoc as part of mill inspect (#435)
Diffstat (limited to 'scalalib')
-rw-r--r--scalalib/src/mill/scalalib/JavaModule.scala161
-rw-r--r--scalalib/src/mill/scalalib/ScalaModule.scala49
-rw-r--r--scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala18
3 files changed, 217 insertions, 11 deletions
diff --git a/scalalib/src/mill/scalalib/JavaModule.scala b/scalalib/src/mill/scalalib/JavaModule.scala
index fc01dceb..b15e0bdb 100644
--- a/scalalib/src/mill/scalalib/JavaModule.scala
+++ b/scalalib/src/mill/scalalib/JavaModule.scala
@@ -34,6 +34,11 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
Lib.depToDependencyJava(_: Dep)
}
+ /**
+ * Allows you to specify an explicit main class to use for the `run` command.
+ * If none is specified, the classpath is searched for an appropriate main
+ * class to use if one exists
+ */
def mainClass: T[Option[String]] = None
def finalMainClassOpt: T[Either[String, String]] = T{
@@ -59,10 +64,29 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
}
}
+ /**
+ * Any ivy dependencies you want to add to this Module, in the format
+ * ivy"org::name:version" for Scala dependencies or ivy"org:name:version"
+ * for Java dependencies
+ */
def ivyDeps = T{ Agg.empty[Dep] }
+
+ /**
+ * Same as `ivyDeps`, but only present at compile time. Useful for e.g.
+ * macro-related dependencies like `scala-reflect` that doesn't need to be
+ * present at runtime
+ */
def compileIvyDeps = T{ Agg.empty[Dep] }
+ /**
+ * Same as `ivyDeps`, but only present at runtime. Useful for e.g.
+ * selecting different versions of a dependency to use at runtime after your
+ * code has already been compiled
+ */
def runIvyDeps = T{ Agg.empty[Dep] }
+ /**
+ * Options to pass to the java compiler
+ */
def javacOptions = T{ Seq.empty[String] }
/** The direct dependencies of this module */
@@ -78,17 +102,30 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
Seq(this) ++ recursiveModuleDeps
}
+ /**
+ * Additional jars, classfiles or resources to add to the classpath directly
+ * from disk rather than being downloaded from Maven Central or other package
+ * repositories
+ */
def unmanagedClasspath = T{ Agg.empty[PathRef] }
-
+ /**
+ * The transitive ivy dependencies of this module and all it's upstream modules
+ */
def transitiveIvyDeps: T[Agg[Dep]] = T{
ivyDeps() ++ Task.traverse(moduleDeps)(_.transitiveIvyDeps)().flatten
}
+ /**
+ * The upstream compilation output of all this module's upstream modules
+ */
def upstreamCompileOutput = T{
Task.traverse(recursiveModuleDeps)(_.compile)
}
+ /**
+ * The transitive version of `localClasspath`
+ */
def transitiveLocalClasspath: T[Agg[PathRef]] = T{
Task.traverse(moduleDeps)(m =>
T.task{m.localClasspath() ++ m.transitiveLocalClasspath()}
@@ -110,10 +147,19 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
def repositories: Seq[Repository] = zincWorker.repositories
+ /**
+ * What platform suffix to use for publishing, e.g. `_sjs` for Scala.js
+ * projects
+ */
def platformSuffix = T{ "" }
private val Milestone213 = raw"""2.13.(\d+)-M(\d+)""".r
+ /**
+ * What shell script to use to launch the executable generated by `assembly`.
+ * Defaults to a generic "universal" launcher that should work for Windows,
+ * OS-X and Linux
+ */
def prependShellScript: T[String] = T{
mainClass() match{
case None => ""
@@ -129,11 +175,29 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
def assemblyRules: Seq[Assembly.Rule] = Assembly.defaultRules
+ /**
+ * The folders where the source files for this module live
+ */
def sources = T.sources{ millSourcePath / 'src }
+ /**
+ * The folders where the resource files for this module live
+ */
def resources = T.sources{ millSourcePath / 'resources }
+ /**
+ * Folders containing source files that are generated rather than
+ * hand-written; these files can be generated in this target itself,
+ * or can refer to files generated from other targets
+ */
def generatedSources = T{ Seq.empty[PathRef] }
+
+ /**
+ * The folders containing all source files fed into the compiler
+ */
def allSources = T{ sources() ++ generatedSources() }
+ /**
+ * All individual source files fed into the compiler
+ */
def allSourceFiles = T{
def isHiddenFile(path: Path) = path.segments.last.startsWith(".")
for {
@@ -144,6 +208,9 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
} yield PathRef(path)
}
+ /**
+ * Compiles the current module to generate compiled classfiles/bytecode
+ */
def compile: T[CompilationResult] = T.persistent{
zincWorker.worker().compileJava(
upstreamCompileOutput(),
@@ -153,9 +220,18 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
)
}
+ /**
+ * The output classfiles/resources from this module, excluding upstream
+ * modules and third-party dependencies
+ */
def localClasspath = T{
resources() ++ Agg(compile().classes)
}
+
+ /**
+ * All classfiles and resources from upstream modules and dependencies
+ * necessary to compile this module
+ */
def compileClasspath = T{
transitiveLocalClasspath() ++
resources() ++
@@ -163,19 +239,28 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
resolveDeps(T.task{compileIvyDeps() ++ transitiveIvyDeps()})()
}
+ /**
+ * All upstream classfiles and resources necessary to build and executable
+ * assembly, but without this module's contribution
+ */
def upstreamAssemblyClasspath = T{
transitiveLocalClasspath() ++
unmanagedClasspath() ++
resolveDeps(T.task{runIvyDeps() ++ transitiveIvyDeps()})()
}
+ /**
+ * All classfiles and resources from upstream modules and dependencies
+ * necessary to run this module's code after compilation
+ */
def runClasspath = T{
localClasspath() ++
upstreamAssemblyClasspath()
}
/**
- * Build the assembly for upstream dependencies separate from the current classpath
+ * 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
@@ -188,6 +273,10 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
)
}
+ /**
+ * An executable uber-jar/assembly containing all the resources and compiled
+ * classfiles from this module and all it's upstream modules and dependencies
+ */
def assembly = T{
createAssembly(
Agg.from(localClasspath().map(_.path)),
@@ -198,6 +287,10 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
)
}
+ /**
+ * A jar containing only this module's resources and compiled classfiles,
+ * without those from upstream modules and dependencies
+ */
def jar = T{
createJar(
localClasspath().map(_.path).filter(exists),
@@ -205,6 +298,10 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
)
}
+ /**
+ * The documentation jar, containing all the Javadoc/Scaladoc HTML files, for
+ * publishing to Maven Central
+ */
def docJar = T[PathRef] {
val outDir = T.ctx().dest
@@ -239,14 +336,30 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
createJar(Agg(javadocDir))(outDir)
}
+ /**
+ * The source jar, containing only source code for publishing to Maven Central
+ */
def sourceJar = T {
createJar((allSources() ++ resources()).map(_.path).filter(exists))
}
+ /**
+ * Any command-line parameters you want to pass to the forked JVM under `run`,
+ * `test` or `repl`
+ */
def forkArgs = T{ Seq.empty[String] }
+ /**
+ * Any environment variables you want to pass to the forked JVM under `run`,
+ * `test` or `repl`
+ */
def forkEnv = T{ sys.env.toMap }
+ /**
+ * Builds a command-line "launcher" file that can be used to run this module's
+ * code, without the Mill process. Useful for deployment & other places where
+ * you do not want a build tool running
+ */
def launcher = T{
Result.Success(
Jvm.createLauncher(
@@ -271,6 +384,12 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
Result.Success()
}
+ /**
+ * Runs this module's code in-process within an isolated classloader. This is
+ * faster than `run`, but in exchange you have less isolation between runs
+ * since the code can dirty the parent Mill process and potentially leave it
+ * in a bad state.
+ */
def runLocal(args: String*) = T.command {
Jvm.runLocal(
finalMainClass(),
@@ -279,6 +398,9 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
)
}
+ /**
+ * Runs this module's code in a subprocess and waits for it to finish
+ */
def run(args: String*) = T.command{
try Result.Success(Jvm.interactiveSubprocess(
finalMainClass(),
@@ -324,6 +446,18 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
write(procTombstone, token)
(procId, procTombstone, token)
}
+
+ /**
+ * Runs this module's code in a background process, until it dies or
+ * `runBackground` is used again. This lets you continue using Mill while
+ * the process is running in the background: editing files, compiling, and
+ * only re-starting the background process when you're ready.
+ *
+ * You can also use `-w foo.runBackground` to make Mill watch for changes
+ * and automatically recompile your code & restart the background process
+ * when ready. This is useful when working on long-running server processes
+ * that would otherwise run forever
+ */
def runBackground(args: String*) = T.command{
val (procId, procTombstone, token) = backgroundSetup(T.ctx().dest)
try Result.Success(Jvm.interactiveSubprocess(
@@ -339,6 +473,9 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
}
}
+ /**
+ * Same as `runBackground`, but lets you specify a main class to run
+ */
def runMainBackground(mainClass: String, args: String*) = T.command{
val (procId, procTombstone, token) = backgroundSetup(T.ctx().dest)
try Result.Success(Jvm.interactiveSubprocess(
@@ -354,6 +491,9 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
}
}
+ /**
+ * Same as `runLocal`, but lets you specify a main class to run
+ */
def runMainLocal(mainClass: String, args: String*) = T.command {
Jvm.runLocal(
mainClass,
@@ -362,6 +502,9 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
)
}
+ /**
+ * Same as `run`, but lets you specify a main class to run
+ */
def runMain(mainClass: String, args: String*) = T.command{
try Result.Success(Jvm.interactiveSubprocess(
mainClass,
@@ -388,8 +531,14 @@ trait JavaModule extends mill.Module with TaskModule { outer =>
trait TestModule extends JavaModule with TaskModule {
override def defaultCommandName() = "test"
+ /**
+ * What test frameworks to use.
+ */
def testFrameworks: T[Seq[String]]
-
+ /**
+ * Discovers and runs the module's tests in a subprocess, reporting the
+ * results to the console
+ */
def test(args: String*) = T.command{
val outputPath = T.ctx().dest/"out.json"
@@ -418,6 +567,11 @@ trait TestModule extends JavaModule with TaskModule {
}
}
+
+ /**
+ * Discovers and runs the module's tests in-process in an isolated classloader,
+ * reporting the results to the console
+ */
def testLocal(args: String*) = T.command{
val outputPath = T.ctx().dest/"out.json"
@@ -448,3 +602,4 @@ object TestModule{
}
}
}
+
diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala
index 3a4a9d45..74656818 100644
--- a/scalalib/src/mill/scalalib/ScalaModule.scala
+++ b/scalalib/src/mill/scalalib/ScalaModule.scala
@@ -27,6 +27,10 @@ trait ScalaModule extends JavaModule { outer =>
override def moduleDeps: Seq[JavaModule] = Seq(outer)
}
+ /**
+ * What Scala organization to use
+ * @return
+ */
def scalaOrganization: T[String] = T {
if (isDotty(scalaVersion()))
"ch.epfl.lamp"
@@ -34,6 +38,9 @@ trait ScalaModule extends JavaModule { outer =>
"org.scala-lang"
}
+ /**
+ * What version of Scala to use
+ */
def scalaVersion: T[String]
override def mapDependencies = T.task{ d: coursier.Dependency =>
@@ -59,10 +66,16 @@ trait ScalaModule extends JavaModule { outer =>
)
}
+ /**
+ * Allows you to make use of Scala compiler plugins from maven central
+ */
def scalacPluginIvyDeps = T{ Agg.empty[Dep] }
def scalaDocPluginIvyDeps = T{ scalacPluginIvyDeps() }
+ /**
+ * Command-line options to pass to the Scala compiler
+ */
def scalacOptions = T{ Seq.empty[String] }
def scalaDocOptions = T{ scalacOptions() }
@@ -98,22 +111,33 @@ trait ScalaModule extends JavaModule { outer =>
)
}
+ /**
+ * The local classpath of Scala compiler plugins on-disk; you can add
+ * additional jars here if you have some copiler plugin that isn't present
+ * on maven central
+ */
def scalacPluginClasspath: T[Agg[PathRef]] = T {
resolveDeps(scalacPluginIvyDeps)()
}
+ /**
+ * The ivy coordinates of Scala's own standard library
+ */
def scalaDocPluginClasspath: T[Agg[PathRef]] = T {
resolveDeps(scalaDocPluginIvyDeps)()
}
def scalaLibraryIvyDeps = T{ scalaRuntimeIvyDeps(scalaOrganization(), scalaVersion()) }
+
/**
* Classpath of the Scala Compiler & any compiler plugins
*/
def scalaCompilerClasspath: T[Agg[PathRef]] = T{
resolveDeps(
- T.task{scalaCompilerIvyDeps(scalaOrganization(), scalaVersion()) ++
- scalaRuntimeIvyDeps(scalaOrganization(), scalaVersion())}
+ T.task{
+ scalaCompilerIvyDeps(scalaOrganization(), scalaVersion()) ++
+ scalaRuntimeIvyDeps(scalaOrganization(), scalaVersion())
+ }
)()
}
override def compileClasspath = T{
@@ -168,6 +192,10 @@ trait ScalaModule extends JavaModule { outer =>
createJar(Agg(javadocDir))(outDir)
}
+ /**
+ * Opens up a Scala console with your module and all dependencies present,
+ * for you to test and operate your code interactively
+ */
def console() = T.command{
if (T.ctx().log.inStream == DummyInputStream){
Result.Failure("repl needs to be run with the -i/--interactive flag")
@@ -186,6 +214,9 @@ trait ScalaModule extends JavaModule { outer =>
}
}
+ /**
+ * Dependencies that are necessary to run the Ammonite Scala REPL
+ */
def ammoniteReplClasspath = T{
localClasspath() ++
transitiveLocalClasspath() ++
@@ -196,6 +227,10 @@ trait ScalaModule extends JavaModule { outer =>
})()
}
+ /**
+ * Opens up an Ammonite Scala REPL with your module and all dependencies present,
+ * for you to test and operate your code interactively
+ */
def repl(replOptions: String*) = T.command{
if (T.ctx().log.inStream == DummyInputStream){
Result.Failure("repl needs to be run with the -i/--interactive flag")
@@ -211,14 +246,22 @@ trait ScalaModule extends JavaModule { outer =>
}
- // publish artifact with name "mill_2.12.4" instead of "mill_2.12"
+ /**
+ * Whether to publish artifacts with name "mill_2.12.4" instead of "mill_2.12"
+ */
def crossFullScalaVersion: T[Boolean] = false
+ /**
+ * What Scala version string to use when publishing
+ */
def artifactScalaVersion: T[String] = T {
if (crossFullScalaVersion()) scalaVersion()
else Lib.scalaBinaryVersion(scalaVersion())
}
+ /**
+ * The suffix appended to the artifact IDs during publishing
+ */
def artifactSuffix: T[String] = s"_${artifactScalaVersion()}"
override def artifactId: T[String] = artifactName() + artifactSuffix()
diff --git a/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala b/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala
index 6b21de84..d2be35e9 100644
--- a/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala
+++ b/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala
@@ -125,12 +125,20 @@ class ZincWorkerImpl(ctx0: mill.util.Ctx,
compilerClasspath: Agg[Path],
scalacPluginClasspath: Agg[Path])
(implicit ctx: mill.util.Ctx): mill.eval.Result[CompilationResult] = {
- val compilerJars = compilerClasspath.toArray.map(_.toIO)
+ val combinedCompilerClasspath = compilerClasspath ++ scalacPluginClasspath
+ val combinedCompilerJars = combinedCompilerClasspath.toArray.map(_.toIO)
- val compilerBridge = compileZincBridgeIfNeeded(scalaVersion, compilerBridgeSources, compilerJars)
+ val compilerBridge = compileZincBridgeIfNeeded(
+ scalaVersion,
+ compilerBridgeSources,
+ compilerClasspath.toArray.map(_.toIO)
+ )
val compilerBridgeSig = compilerBridge.mtime.toMillis
- val compilersSig = compilerBridgeSig + compilerClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
+ val compilersSig =
+ compilerBridgeSig +
+ combinedCompilerClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
+
val compilers = mixedCompilersCache match {
case Some((k, v)) if k == compilersSig => v
case _ =>
@@ -141,10 +149,10 @@ class ZincWorkerImpl(ctx0: mill.util.Ctx,
"scala-compiler"
val scalaInstance = new ScalaInstance(
version = scalaVersion,
- loader = mill.util.ClassLoader.create(compilerJars.map(_.toURI.toURL), null),
+ loader = mill.util.ClassLoader.create(combinedCompilerJars.map(_.toURI.toURL), null),
libraryJar = grepJar(compilerClasspath, "scala-library", scalaVersion).toIO,
compilerJar = grepJar(compilerClasspath, compilerName, scalaVersion).toIO,
- allJars = compilerJars,
+ allJars = combinedCompilerJars,
explicitActual = None
)
val compilers = ic.compilers(