Skip to content

Commit d04fd66

Browse files
committed
Configure SBT build
1 parent 385182a commit d04fd66

File tree

4 files changed

+182
-13
lines changed

4 files changed

+182
-13
lines changed

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ val `stdlib-bootstrapped-tasty-tests` = Build.`stdlib-bootstrapped-tasty-tests`
2020
val `tasty-core` = Build.`tasty-core`
2121
val `tasty-core-bootstrapped` = Build.`tasty-core-bootstrapped`
2222
val `tasty-core-scala2` = Build.`tasty-core-scala2`
23+
val scala3doc = Build.scala3doc
24+
val `scala3doc-example-project` = Build.`scala3doc-example-project`
2325
val `scala3-bench-run` = Build.`scala3-bench-run`
2426
val dist = Build.dist
2527
val `community-build` = Build.`community-build`

project/Build.scala

Lines changed: 152 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ object Build {
136136

137137
val fetchScalaJSSource = taskKey[File]("Fetch the sources of Scala.js")
138138

139+
// Scala3doc specific tasks
140+
val buildDokkaApi = taskKey[File]("Compile dokka wrapper and put jar in lib")
141+
val generateSelfDocumentation = taskKey[Unit]("Generate example documentation")
142+
val generateDottyLibDocumentation = taskKey[Unit]("Generate documentation for dotty lib")
143+
139144
lazy val SourceDeps = config("sourcedeps")
140145

141146
// Settings shared by the build (scoped in ThisBuild). Used in build.sbt
@@ -221,11 +226,6 @@ object Build {
221226
resourceDirectory in Compile := baseDirectory.value / "resources",
222227
resourceDirectory in Test := baseDirectory.value / "test-resources",
223228

224-
// Disable scaladoc generation, it's way too slow and we'll replace it
225-
// by dottydoc anyway. We still publish an empty -javadoc.jar to make
226-
// sonatype happy.
227-
sources in (Compile, doc) := Seq(),
228-
229229
// Prevent sbt from rewriting our dependencies
230230
scalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(false))),
231231

@@ -236,6 +236,12 @@ object Build {
236236
sourcesInBase := false,
237237
)
238238

239+
lazy val disableDocSetting =
240+
// Disable scaladoc generation, it's way too slow and we'll replace it
241+
// by dottydoc anyway. We still publish an empty -javadoc.jar to make
242+
// sonatype happy.
243+
sources in (Compile, doc) := Seq()
244+
239245
// Settings used for projects compiled only with Java
240246
lazy val commonJavaSettings = commonSettings ++ Seq(
241247
version := dottyVersion,
@@ -244,7 +250,9 @@ object Build {
244250
crossPaths := false,
245251
// Do not depend on the Scala library
246252
autoScalaLibrary := false,
247-
excludeFromIDE := true
253+
excludeFromIDE := true,
254+
255+
disableDocSetting,
248256
)
249257

250258
// Settings used when compiling dotty (both non-bootstrapped and bootstrapped)
@@ -258,6 +266,8 @@ object Build {
258266
moduleName ~= { _.stripSuffix("-scala2") },
259267
version := dottyVersion,
260268
target := baseDirectory.value / ".." / "out" / "scala-2" / name.value,
269+
270+
disableDocSetting,
261271
)
262272

263273
// Settings used when compiling dotty with the reference compiler
@@ -267,10 +277,17 @@ object Build {
267277
version := dottyNonBootstrappedVersion,
268278
scalaVersion := referenceVersion,
269279
excludeFromIDE := true,
280+
281+
disableDocSetting,
270282
)
271283

272284
// Settings used when compiling dotty with a non-bootstrapped dotty
273-
lazy val commonBootstrappedSettings = commonDottySettings ++ Seq(
285+
lazy val commonBootstrappedSettings = commonBootstrappedSettings0 ++ Seq(
286+
// sbt-dotty defines `scalaInstance in doc` so we need to override it manually
287+
scalaInstance in doc := scalaInstance.value,
288+
disableDocSetting,
289+
)
290+
lazy val commonBootstrappedSettings0 = commonDottySettings ++ Seq(
274291
unmanagedSourceDirectories in Compile += baseDirectory.value / "src-bootstrapped",
275292

276293
version := dottyVersion,
@@ -326,8 +343,6 @@ object Build {
326343
allJars
327344
)
328345
},
329-
// sbt-dotty defines `scalaInstance in doc` so we need to override it manually
330-
scalaInstance in doc := scalaInstance.value,
331346
)
332347

333348
lazy val commonBenchmarkSettings = Seq(
@@ -1153,6 +1168,9 @@ object Build {
11531168
lazy val `scala3-bench-bootstrapped` = project.in(file("bench")).asDottyBench(Bootstrapped)
11541169
lazy val `scala3-bench-run` = project.in(file("bench-run")).asDottyBench(Bootstrapped)
11551170

1171+
lazy val `scala3doc` = project.in(file("scala3doc")).asScala3doc
1172+
lazy val `scala3doc-example-project` = project.in(file("scala3doc-example-project")).asDocExampleProject
1173+
11561174
// sbt plugin to use Dotty in your own build, see
11571175
// https://github.com/lampepfl/scala3-example-project for usage.
11581176
lazy val `sbt-dotty` = project.in(file("sbt-dotty")).
@@ -1192,6 +1210,7 @@ object Build {
11921210
publishLocal in `scala3-staging`,
11931211
publishLocal in `scala3-tasty-inspector`,
11941212
publishLocal in `scala3-doc-bootstrapped`,
1213+
publishLocal in `scala3doc`,
11951214
publishLocal in `scala3-bootstrapped` // Needed because sbt currently hardcodes the dotty artifact
11961215
).evaluated
11971216
)
@@ -1392,8 +1411,7 @@ object Build {
13921411
// FIXME: we do not aggregate `bin` because its tests delete jars, thus breaking other tests
13931412
def asDottyRoot(implicit mode: Mode): Project = project.withCommonSettings.
13941413
aggregate(`scala3-interfaces`, dottyLibrary, dottyCompiler, tastyCore, dottyDoc, `scala3-sbt-bridge`).
1395-
bootstrappedAggregate(`scala3-language-server`, `scala3-staging`, `scala3-tasty-inspector`,
1396-
`scala3-library-bootstrappedJS`).
1414+
bootstrappedAggregate(`scala3-language-server`, `scala3-staging`, `scala3-tasty-inspector`, `scala3-library-bootstrappedJS`, scala3doc).
13971415
dependsOn(tastyCore).
13981416
dependsOn(dottyCompiler).
13991417
dependsOn(dottyLibrary).
@@ -1440,6 +1458,129 @@ object Build {
14401458
settings(commonBenchmarkSettings).
14411459
enablePlugins(JmhPlugin)
14421460

1461+
def asScala3doc: Project = {
1462+
val dokkaVersion = "1.4.10.2"
1463+
val kotlinxVersion = "0.7.2" // upgrade when upgrading dokka
1464+
val flexmarkVersion = "0.42.12"
1465+
val jacksonVersion = "2.9.8"
1466+
val scalaTagsVersion = "0.9.1"
1467+
val dokkaSiteVersion = "0.1.9"
1468+
1469+
project.
1470+
settings(commonBootstrappedSettings).
1471+
dependsOn(`scala3-compiler-bootstrapped`).
1472+
settings(
1473+
Compile/scalaSource := baseDirectory.value / "src/main/scala",
1474+
Test/scalaSource := baseDirectory.value / "src/test/scala",
1475+
Compile/resourceDirectory := baseDirectory.value / "src/main/resources",
1476+
Test/resourceDirectory := baseDirectory.value / "src/test/resources",
1477+
1478+
scalaVersion := dottyVersion,
1479+
resolvers ++= Seq(
1480+
Resolver.jcenterRepo,
1481+
Resolver.bintrayRepo("kotlin", "kotlin-dev"),
1482+
Resolver.bintrayRepo("virtuslab", "dokka"),
1483+
),
1484+
libraryDependencies ++= Seq(
1485+
"org.jetbrains.dokka" % "dokka-test-api" % dokkaVersion % "test",
1486+
1487+
"org.scala-lang" %% "scala3-tasty-inspector" % dottyVersion,
1488+
1489+
"org.jetbrains.dokka" % "dokka-base" % dokkaVersion,
1490+
"org.jetbrains.dokka" % "dokka-core" % dokkaVersion,
1491+
"org.jetbrains.dokka" % "dokka-test-api" % dokkaVersion,
1492+
"org.jetbrains.kotlinx" % "kotlinx-html-jvm" % kotlinxVersion,
1493+
"com.virtuslab.dokka" % "dokka-site" % dokkaSiteVersion,
1494+
1495+
"org.scala-sbt" % "io_2.13" % "1.3.4",
1496+
1497+
"com.vladsch.flexmark" % "flexmark-all" % flexmarkVersion,
1498+
"com.lihaoyi" % "scalatags_2.13" % scalaTagsVersion,
1499+
"nl.big-o" % "liqp" % "0.6.7",
1500+
"args4j" % "args4j" % "2.33",
1501+
),
1502+
1503+
run / fork := true,
1504+
Test / fork := true,
1505+
Test / parallelExecution := false,
1506+
Compile / mainClass := Some("dotty.dokka.Main"),
1507+
1508+
Test / envVars := Map(
1509+
"scala3doc.classroot" -> (Compile/target/classDirectory).value.getAbsolutePath.toString,
1510+
),
1511+
1512+
// hack, we cannot build documentation so we need this to publish locally
1513+
Compile / packageDoc / publishArtifact := false,
1514+
1515+
generateSelfDocumentation := Def.taskDyn {
1516+
val classdir = (Compile/target/classDirectory).value
1517+
(Compile/run).toTask(s" -o output/self -t ${classdir} -d documentation -n scala3doc -s src/main/scala=https://github.com/lampepfl/scala3doc/tree/master/src/main/scala#L")
1518+
}.value,
1519+
1520+
generateDottyLibDocumentation := Def.taskDyn {
1521+
val dottyLib = (Compile/fullClasspath).value.find{ a =>
1522+
val info = a.get(moduleID.key)
1523+
info.nonEmpty &&
1524+
info.get.organization == "ch.epfl.lamp" &&
1525+
info.get.name.startsWith("dotty-library")
1526+
}
1527+
if (dottyLib.isEmpty) Def.task {
1528+
streams.value.log.error("Dotty lib wasn't found")
1529+
} else Def.task {
1530+
(Compile/run).toTask(s" -o output/stdLib -t ${dottyLib.get.data} -d dotty-docs/docs -n dotty-lib -s library/src=https://github.com/lampepfl/dotty/tree/master/library/src#L").value
1531+
}
1532+
}.value,
1533+
1534+
)
1535+
}
1536+
1537+
def asDocExampleProject: Project = project.
1538+
settings(commonBootstrappedSettings0).
1539+
dependsOn(`scala3-compiler-bootstrapped`).
1540+
settings(
1541+
Compile/scalaSource := baseDirectory.value / "src/main/scala",
1542+
Test/scalaSource := baseDirectory.value / "src/test/scala",
1543+
Compile/resourceDirectory := baseDirectory.value / "src/main/resources",
1544+
Test/resourceDirectory := baseDirectory.value / "src/test/resources",
1545+
1546+
name := "scala3doc-example-project",
1547+
description := "Example SBT project that is documented using Scala3doc",
1548+
version := "0.1.0-SNAPSHOT",
1549+
scalaVersion := dottyVersion,
1550+
1551+
useScala3doc := true,
1552+
scala3docOptions ++= Seq("--name", "example-project"),
1553+
Compile / doc / target := file("out/doc/example-project"),
1554+
1555+
// we cannot set
1556+
doc/scalaInstance := {
1557+
val externalNonBootstrappedDeps = externalDependencyClasspath.in(`scala3doc`, Compile).value
1558+
val scalaLibrary = findArtifact(externalNonBootstrappedDeps, "scala-library")
1559+
1560+
// IMPORTANT: We need to use actual jars to form the ScalaInstance and not
1561+
// just directories containing classfiles because sbt maintains a cache of
1562+
// compiler instances. This cache is invalidated based on timestamps
1563+
// however this is only implemented on jars, directories are never
1564+
// invalidated.
1565+
val tastyCore = packageBin.in(`tasty-core`, Compile).value
1566+
val dottyLibrary = packageBin.in(`scala3-library-bootstrapped`, Compile).value
1567+
val dottyInterfaces = packageBin.in(`scala3-interfaces`, Compile).value
1568+
val dottyCompiler = packageBin.in(`scala3-compiler-bootstrapped`, Compile).value
1569+
val doctool = packageBin.in(`scala3doc`, Compile).value
1570+
1571+
val allJars = Seq(tastyCore, dottyLibrary, dottyInterfaces, dottyCompiler, doctool) ++ externalNonBootstrappedDeps.map(_.data)
1572+
1573+
makeScalaInstance(
1574+
state.value,
1575+
scalaVersion.value,
1576+
scalaLibrary,
1577+
dottyLibrary,
1578+
dottyCompiler,
1579+
allJars
1580+
)
1581+
},
1582+
)
1583+
14431584
def asDist(implicit mode: Mode): Project = project.
14441585
enablePlugins(PackPlugin).
14451586
withCommonSettings.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
> run
22
> doc
3+
> clean
4+
> 'set useScala3doc := true'
5+
> doc
36
> 'set initialCommands := "1 + 1" '
47
# FIXME: does not work on the CI
58
#> console

sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ object DottyPlugin extends AutoPlugin {
1818
val isDotty = settingKey[Boolean]("Is this project compiled with Dotty?")
1919
val isDottyJS = settingKey[Boolean]("Is this project compiled with Dotty and Scala.js?")
2020

21+
val useScala3doc = settingKey[Boolean]("Use Scala3doc as the documentation tool")
22+
val scala3docOptions = settingKey[Seq[String]]("Options for Scala3doc")
23+
2124
// NOTE:
2225
// - this is a def to support `scalaVersion := dottyLatestNightlyBuild`
2326
// - if this was a taskKey, then you couldn't do `scalaVersion := dottyLatestNightlyBuild`
@@ -353,10 +356,30 @@ object DottyPlugin extends AutoPlugin {
353356
Def.valueStrict { scalaInstance.taskValue }
354357
}.value,
355358

356-
// We need more stuff on the classpath to run the `doc` task.
359+
// Configuration for the doctool
360+
resolvers ++= Seq(
361+
Resolver.jcenterRepo,
362+
Resolver.bintrayRepo("kotlin", "kotlin-dev"),
363+
Resolver.bintrayRepo("virtuslab", "dokka"),
364+
),
365+
useScala3doc := false,
366+
scala3docOptions := Seq.empty,
367+
Compile / doc / scalacOptions := {
368+
val s3dOpts = scala3docOptions.value.map("--+DOC+" + _)
369+
val s3cOpts = (Compile / doc / scalacOptions).value
370+
if (isDotty.value && useScala3doc.value) {
371+
s3dOpts ++ s3cOpts
372+
} else {
373+
s3cOpts
374+
}
375+
},
376+
// We need to add doctool classes to the classpath so they can be called
357377
scalaInstance in doc := Def.taskDyn {
358378
if (isDotty.value)
359-
dottyScalaInstanceTask(scala3Artefact(scalaVersion.value, "doc"))
379+
if (useScala3doc.value)
380+
dottyScalaInstanceTask("scala3doc")
381+
else
382+
dottyScalaInstanceTask(scala3Artefact(scalaVersion.value, "doc"))
360383
else
361384
Def.valueStrict { (scalaInstance in doc).taskValue }
362385
}.value,

0 commit comments

Comments
 (0)