Skip to content

Commit c8a2ab6

Browse files
authored
Split up docJar into javadoc/scaladoc generation and jar creation (#5565)
`JavaModule`, `ScalaModule` and `KoltinModule` currently implement the `docJar` task to produce an Javadoc-compatible JAR ready for publishing and consumption by IDEs. Unfortunately, this JAR is rather unsuited for direct consumption by a browser, e.g. to read the API documentation directly. It either needs to be extracted (Mill doesn't provide any convenience task for that) or users can use the implementation detail like the `javadoc` directory in the `javaDoc.dest` directory, which is not documented and can change at any time. This PR splits the generation of the API documentation from the `docJar` packaging. As a result, users can use the result of `javadocGenerated`, `scalaDocGenerated` and `dokkaGenerated` tasks to directly access the exploded API documentation. The names were choosed to have the same prefix as the tools and other already existing configuration tasks, like `javadocOptions`, `scalaDocOptions` and `dokkaOptions`. As a neat side effect, in Kotlin or Scala modules, users can generate the pure Java API part with `javadocGenerated`. Since some documentation processors support advanced features like static site generation, the `scalaDocGenerated` task can later split up further, to improve the incremental build speed. Pull request: #5565
1 parent ff836cd commit c8a2ab6

File tree

6 files changed

+78
-53
lines changed

6 files changed

+78
-53
lines changed

libs/javalib/src/mill/javalib/JavaModule.scala

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ import mill.api.daemon.internal.bsp.{
1818
}
1919
import mill.javalib.*
2020
import mill.api.daemon.internal.idea.GenIdeaInternalApi
21-
import mill.api.{ModuleRef, PathRef, Segment, Task, TaskCtx, DefaultTaskModule}
21+
import mill.api.{DefaultTaskModule, ModuleRef, PathRef, Segment, Task, TaskCtx}
2222
import mill.javalib.api.CompilationResult
2323
import mill.javalib.bsp.{BspJavaModule, BspModule}
2424
import mill.javalib.internal.ModuleUtils
2525
import mill.javalib.publish.Artifact
2626
import mill.util.{JarManifest, Jvm}
2727
import os.Path
28+
2829
import scala.util.chaining.scalaUtilChainingOps
2930
import scala.util.matching.Regex
3031

@@ -1085,11 +1086,7 @@ trait JavaModule
10851086
*/
10861087
def docJarUseArgsFile: T[Boolean] = Task { scala.util.Properties.isWin }
10871088

1088-
/**
1089-
* The documentation jar, containing all the Javadoc/Scaladoc HTML files, for
1090-
* publishing to Maven Central
1091-
*/
1092-
def docJar: T[PathRef] = Task[PathRef] {
1089+
def javadocGenerated: T[PathRef] = Task[PathRef] {
10931090
val outDir = Task.dest
10941091

10951092
val javadocDir = outDir / "javadoc"
@@ -1141,8 +1138,15 @@ trait JavaModule
11411138
stdout = os.Inherit
11421139
)
11431140
}
1141+
PathRef(javadocDir)
1142+
}
11441143

1145-
PathRef(Jvm.createJar(Task.dest / "out.jar", Seq(javadocDir)))
1144+
/**
1145+
* The documentation jar, containing all the Javadoc/Scaladoc HTML files, for
1146+
* publishing to Maven Central
1147+
*/
1148+
def docJar: T[PathRef] = Task[PathRef] {
1149+
PathRef(Jvm.createJar(Task.dest / "out.jar", Seq(javadocGenerated().path)))
11461150
}
11471151

11481152
/**

libs/kotlinlib/src/mill/kotlinlib/KotlinModule.scala

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,12 @@ trait KotlinModule extends JavaModule { outer =>
181181
}
182182

183183
/**
184-
* The documentation jar, containing all the Dokka HTML files, for
184+
* The generated documentation, containing all the Dokka HTML files, for
185185
* publishing to Maven Central. You can control Dokka version by using [[dokkaVersion]]
186186
* and option by using [[dokkaOptions]].
187187
*/
188-
override def docJar: T[PathRef] = Task[PathRef] {
189-
val outDir = Task.dest
190-
191-
val dokkaDir = outDir / "dokka"
188+
def dokkaGenerated: T[PathRef] = Task[PathRef] {
189+
val dokkaDir = Task.dest / "dokka"
192190
os.makeDir.all(dokkaDir)
193191

194192
val files = Lib.findSourceFiles(docSources(), Seq("java", "kt"))
@@ -232,7 +230,16 @@ trait KotlinModule extends JavaModule { outer =>
232230
)
233231
}
234232

235-
PathRef(Jvm.createJar(outDir / "out.jar", Seq(dokkaDir)))
233+
PathRef(dokkaDir)
234+
}
235+
236+
/**
237+
* The documentation jar, containing all the Dokka HTML files, for
238+
* publishing to Maven Central. You can control Dokka version by using [[dokkaVersion]]
239+
* and option by using [[dokkaOptions]].
240+
*/
241+
override def docJar: T[PathRef] = Task[PathRef] {
242+
PathRef(Jvm.createJar(Task.dest / "out.jar", Seq(dokkaGenerated().path)))
236243
}
237244

238245
/**

libs/scalalib/src/mill/scalalib/ScalaModule.scala

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import mill.util.JarManifest
55
import mill.api.{BuildCtx, DummyInputStream, ModuleRef, PathRef, Result, Task}
66
import mill.util.BuildInfo
77
import mill.util.Jvm
8-
import mill.util.Jvm.createJar
98
import mill.javalib.api.{CompilationResult, JvmWorkerUtil, Versions}
109
import mainargs.Flag
1110
import mill.api.daemon.internal.bsp.{BspBuildTarget, BspModuleApi, ScalaBuildTarget}
@@ -303,7 +302,7 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
303302
else allSources()
304303
}
305304

306-
override def docJar: T[PathRef] = Task {
305+
def scalaDocGenerated: T[PathRef] = Task {
307306
val compileCp = Seq(
308307
"-classpath",
309308
compileClasspath()
@@ -313,9 +312,13 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
313312
.mkString(java.io.File.pathSeparator)
314313
)
315314

316-
def packageWithZinc(options: Seq[String], files: Seq[os.Path], javadocDir: os.Path) = {
315+
def generateWithZinc(
316+
options: Seq[String],
317+
files: Seq[os.Path],
318+
javadocDir: os.Path
319+
): PathRef = {
317320
if (files.isEmpty) {
318-
Result.Success(PathRef(createJar(Task.dest / "out.jar", Seq(javadocDir))))
321+
PathRef(javadocDir)
319322
} else {
320323
jvmWorker()
321324
.worker()
@@ -328,8 +331,8 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
328331
options ++ compileCp ++ scalaDocOptions() ++
329332
files.map(_.toString())
330333
) match {
331-
case true => Result.Success(PathRef(createJar(Task.dest / "out.jar", Seq(javadocDir))))
332-
case false => Result.Failure("docJar generation failed")
334+
case true => PathRef(javadocDir)
335+
case false => Task.fail("scaladoc generation failed")
333336
}
334337
}
335338
}
@@ -352,7 +355,7 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
352355
createFolders = true
353356
)
354357
}
355-
packageWithZinc(
358+
generateWithZinc(
356359
Seq("-siteroot", javadocDir.toNIO.toString),
357360
Lib.findSourceFiles(docSources(), Seq("java", "scala")),
358361
javadocDir / "_site"
@@ -384,7 +387,7 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
384387
)
385388
}
386389

387-
packageWithZinc(
390+
generateWithZinc(
388391
Seq(
389392
"-d",
390393
javadocDir.toNIO.toString,
@@ -398,7 +401,7 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
398401
val javadocDir = Task.dest / "javadoc"
399402
os.makeDir.all(javadocDir)
400403

401-
packageWithZinc(
404+
generateWithZinc(
402405
Seq("-d", javadocDir.toNIO.toString),
403406
Lib.findSourceFiles(docSources(), Seq("java", "scala")),
404407
javadocDir
@@ -407,6 +410,10 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase
407410

408411
}
409412

413+
override def docJar: T[PathRef] = Task {
414+
PathRef(Jvm.createJar(Task.dest / "out.jar", Seq(scalaDocGenerated().path)))
415+
}
416+
410417
/**
411418
* Command-line options to pass to the Scala console
412419
*/

libs/scalalib/test/src/mill/scalalib/DottyDocTests.scala

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,39 @@ object DottyDocTests extends TestSuite {
4040
def tests: Tests = Tests {
4141
test("static") - UnitTester(StaticDocsModule, resourcePath).scoped { eval =>
4242
val Right(_) = eval.apply(StaticDocsModule.static.docJar): @unchecked
43-
val dest = eval.outPath / "static/docJar.dest"
43+
val scaladoc = eval.outPath / "static/scalaDocGenerated.dest"
44+
val docJar = eval.outPath / "static/docJar.dest"
4445
assert(
45-
os.exists(dest / "out.jar"), // final jar should exist
4646
// check if extra markdown files have been included and translated to html
47-
os.exists(dest / "javadoc/_site/index.html"),
48-
os.exists(dest / "javadoc/_site/nested/extra.html"),
47+
os.exists(scaladoc / "javadoc/_site/index.html"),
48+
os.exists(scaladoc / "javadoc/_site/nested/extra.html"),
4949
// also check that API docs have been generated
50-
os.exists(dest / "javadoc/_site/api/pkg/SomeClass.html")
50+
os.exists(scaladoc / "javadoc/_site/api/pkg/SomeClass.html"),
51+
// final jar should exist
52+
os.exists(docJar / "out.jar")
5153
)
5254
}
5355
test("empty") - UnitTester(EmptyDocsModule, resourcePath).scoped { eval =>
5456
val Right(_) = eval.apply(EmptyDocsModule.empty.docJar): @unchecked
55-
val dest = eval.outPath / "empty/docJar.dest"
57+
val scaladoc = eval.outPath / "empty/scalaDocGenerated.dest"
58+
val docJar = eval.outPath / "empty/docJar.dest"
5659
assert(
57-
os.exists(dest / "out.jar"),
58-
os.exists(dest / "javadoc/_site/api/pkg/SomeClass.html")
60+
os.exists(scaladoc / "javadoc/_site/api/pkg/SomeClass.html"),
61+
os.exists(docJar / "out.jar")
5962
)
6063
}
6164
test("multiple") - UnitTester(MultiDocsModule, resourcePath).scoped { eval =>
6265
val Right(_) = eval.apply(MultiDocsModule.multidocs.docJar): @unchecked
63-
val dest = eval.outPath / "multidocs/docJar.dest"
66+
val scaladoc = eval.outPath / "multidocs/scalaDocGenerated.dest"
67+
val docJar = eval.outPath / "multidocs/docJar.dest"
6468
assert(
65-
os.exists(dest / "out.jar"), // final jar should exist
66-
os.exists(dest / "javadoc/_site/api/pkg/SomeClass.html"),
67-
os.exists(dest / "javadoc/_site/index.html"),
68-
os.exists(dest / "javadoc/_site/nested/original.html"),
69-
os.exists(dest / "javadoc/_site/nested/extra.html"),
69+
os.exists(docJar / "out.jar"), // final jar should exist
70+
os.exists(scaladoc / "javadoc/_site/api/pkg/SomeClass.html"),
71+
os.exists(scaladoc / "javadoc/_site/index.html"),
72+
os.exists(scaladoc / "javadoc/_site/nested/original.html"),
73+
os.exists(scaladoc / "javadoc/_site/nested/extra.html"),
7074
// check that later doc sources overwrite earlier ones
71-
os.read(dest / "javadoc/_site/index.html").contains("overwritten")
75+
os.read(scaladoc / "javadoc/_site/index.html").contains("overwritten")
7276
)
7377
}
7478
}

libs/scalalib/test/src/mill/scalalib/ScalaDoc3Tests.scala

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,35 +41,38 @@ object ScalaDoc3Tests extends TestSuite {
4141
def tests: Tests = Tests {
4242
test("static") - UnitTester(StaticDocsModule, resourcePath).scoped { eval =>
4343
val Right(_) = eval.apply(StaticDocsModule.static.docJar): @unchecked
44-
val dest = eval.outPath / "static/docJar.dest"
44+
val docjar = eval.outPath / "static/docJar.dest"
45+
val scaladoc = eval.outPath / "static/scalaDocGenerated.dest"
4546
assert(
46-
os.exists(dest / "out.jar"), // final jar should exist
47+
os.exists(docjar / "out.jar"), // final jar should exist
4748
// check if extra markdown files have been included and translated to html
48-
os.exists(dest / "javadoc/index.html"),
49-
os.exists(dest / "javadoc/nested/extra.html"),
49+
os.exists(scaladoc / "javadoc/index.html"),
50+
os.exists(scaladoc / "javadoc/nested/extra.html"),
5051
// also check that API docs have been generated
51-
os.exists(dest / "javadoc/api/pkg/SomeClass.html")
52+
os.exists(scaladoc / "javadoc/api/pkg/SomeClass.html")
5253
)
5354
}
5455
test("empty") - UnitTester(EmptyDocsModule, resourcePath).scoped { eval =>
5556
val Right(_) = eval.apply(EmptyDocsModule.empty.docJar): @unchecked
56-
val dest = eval.outPath / "empty/docJar.dest"
57+
val scaladoc = eval.outPath / "empty/scalaDocGenerated.dest"
58+
val docJar = eval.outPath / "empty/docJar.dest"
5759
assert(
58-
os.exists(dest / "out.jar"),
59-
os.exists(dest / "javadoc/api/pkg/SomeClass.html")
60+
os.exists(docJar / "out.jar"),
61+
os.exists(scaladoc / "javadoc/api/pkg/SomeClass.html")
6062
)
6163
}
6264
test("multiple") - UnitTester(MultiDocsModule, resourcePath).scoped { eval =>
6365
val Right(_) = eval.apply(MultiDocsModule.multidocs.docJar): @unchecked
64-
val dest = eval.outPath / "multidocs/docJar.dest"
66+
val docJar = eval.outPath / "multidocs/docJar.dest"
67+
val scaladoc = eval.outPath / "multidocs/scalaDocGenerated.dest"
6568
assert(
66-
os.exists(dest / "out.jar"), // final jar should exist
67-
os.exists(dest / "javadoc/api/pkg/SomeClass.html"),
68-
os.exists(dest / "javadoc/index.html"),
69-
os.exists(dest / "javadoc/docs/nested/original.html"),
70-
os.exists(dest / "javadoc/docs/nested/extra.html"),
69+
os.exists(docJar / "out.jar"), // final jar should exist
70+
os.exists(scaladoc / "javadoc/api/pkg/SomeClass.html"),
71+
os.exists(scaladoc / "javadoc/index.html"),
72+
os.exists(scaladoc / "javadoc/docs/nested/original.html"),
73+
os.exists(scaladoc / "javadoc/docs/nested/extra.html"),
7174
// check that later doc sources overwrite earlier ones
72-
os.read(dest / "javadoc/index.html").contains("overwritten")
75+
os.read(scaladoc / "javadoc/index.html").contains("overwritten")
7376
)
7477
}
7578
}

libs/scalalib/test/src/mill/scalalib/ScalaScaladocTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ object ScalaScaladocTests extends TestSuite {
6767
val Right(result) = eval.apply(HelloWorldDocTitle.core.docJar): @unchecked
6868
assert(
6969
result.evalCount > 0,
70-
os.read(eval.outPath / "core/docJar.dest/javadoc/index.html").contains(
70+
os.read(eval.outPath / "core/scalaDocGenerated.dest/javadoc/index.html").contains(
7171
"<span id=\"doc-title\">Hello World"
7272
)
7373
)

0 commit comments

Comments
 (0)