Skip to content

Commit d96e9e3

Browse files
committed
Eliminate duplicate sidebar.yml files, generate it when building docs using sidebar.reference.yml and sidebar.nightly.template.yml.
Regenerate reference-expected-links Ensure the warnings emitted during `generateScalaDocumentation` are pointing to original sources Improve generateScalaDocumentation task description
1 parent 5c51b7b commit d96e9e3

File tree

8 files changed

+396
-514
lines changed

8 files changed

+396
-514
lines changed

docs/_layouts/static-site-main.html

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,7 @@
44

55
<div class="site-container">
66
<div id="site-header"></div>
7-
{% if page.nightlyOf %}
8-
<aside class="warning">
9-
<div class='icon'></div>
10-
<div class='content'>
11-
This is a nightly documentation. The content of this page may not be
12-
consistent with the current stable version of language. Click
13-
<a href="{{ page.nightlyOf }}">here</a> to find the stable version of this
14-
page.
15-
</div>
16-
</aside>
17-
{% endif %} {{ content }}
7+
{{ content }}
188
<div class="divider" />
199
<nav class="arrow-navigation" aria-label="Page navigation">
2010
{% if page.previous %}

docs/sidebar.nightly.template.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
index: index.md
2+
subsection:
3+
- title: Reference
4+
directory: docs/reference
5+
# Embed sidebar.reference.yml, performed by `generateScalaDocumentation` sbt task
6+
- title: Contributing
7+
directory: docs/contributing
8+
index: contributing/index.md
9+
subsection:
10+
- page: contributing/getting-started.md
11+
- page: contributing/setting-up-your-ide.md
12+
- index: contributing/issues/diagnosing-your-issue.md
13+
subsection:
14+
- page: contributing/issues/reproduce.md
15+
- page: contributing/issues/cause.md
16+
- page: contributing/issues/areas.md
17+
- index: contributing/debugging/debugging.md
18+
subsection:
19+
- page: contributing/debugging/ide-debugging.md
20+
- page: contributing/debugging/inspection.md
21+
- page: contributing/debugging/other-debugging.md
22+
- page: contributing/testing.md
23+
- page: contributing/scaladoc.md
24+
- page: contributing/community-build.md
25+
- page: contributing/sending-in-a-pr.md
26+
- page: contributing/cheatsheet.md
27+
- title: Procedures
28+
directory: procedures
29+
index: contributing/procedures/index.md
30+
subsection:
31+
- page: contributing/procedures/release.md
32+
- page: contributing/procedures/vulpix.md
33+
- title: High Level Architecture
34+
directory: architecture
35+
index: contributing/architecture/index.md
36+
subsection:
37+
- page: contributing/architecture/lifecycle.md
38+
- page: contributing/architecture/context.md
39+
- page: contributing/architecture/phases.md
40+
- page: contributing/architecture/types.md
41+
- page: contributing/architecture/time.md
42+
- page: contributing/architecture/symbols.md
43+
- title: Internals
44+
directory: docs/internals
45+
index: internals/index.md
46+
subsection:
47+
- page: internals/backend.md
48+
- page: internals/classpaths.md
49+
- page: internals/contexts.md
50+
- page: internals/dotc-scalac.md
51+
- page: internals/higher-kinded-v2.md
52+
- page: internals/overall-structure.md
53+
- page: internals/explicit-nulls.md
54+
- page: internals/periods.md
55+
- page: internals/syntax.md
56+
- page: internals/type-system.md
57+
- page: internals/dotty-internals-1-notes.md
58+
- page: internals/debug-macros.md
59+
- page: internals/gadts.md
60+
- page: internals/coverage.md
61+
- page: internals/best-effort-compilation.md
62+
- page: release-notes-0.1.2.md # Referenced from https://www.scala-lang.org/blog/2017/05/31/first-dotty-milestone-release.html
63+
hidden: true

docs/sidebar.yml

Lines changed: 185 additions & 247 deletions
Large diffs are not rendered by default.

project/Build.scala

Lines changed: 129 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3323,11 +3323,17 @@ object Build {
33233323
val testcasesSourceRoot = taskKey[String]("Root directory where tests sources are generated")
33243324
val testDocumentationRoot = taskKey[String]("Root directory where tests documentation are stored")
33253325
val generateSelfDocumentation = taskKey[Unit]("Generate example documentation")
3326-
// Note: the two tasks below should be one, but a bug in Tasty prevents that
3327-
val generateScalaDocumentation = inputKey[Unit]("Generate documentation for dotty lib")
3328-
val generateStableScala3Documentation = inputKey[Unit]("Generate documentation for stable dotty lib")
33293326
val generateTestcasesDocumentation = taskKey[Unit]("Generate documentation for testcases, useful for debugging tests")
33303327

3328+
// Published on https://dotty.epfl.ch/ by nightly builds
3329+
// Contains additional internal/contributing docs
3330+
val generateScalaDocumentation = inputKey[Unit]("Generate documentation for snapshot release")
3331+
3332+
// Published on https://docs.scala-lang.org/api/all.html
3333+
val generateStableScala3Documentation = inputKey[Unit]("Generate documentation for stable release")
3334+
3335+
// Published on https://docs.scala-lang.org/scala3/reference/
3336+
// Does not produce API docs, contains additional redirects for improved stablity
33313337
val generateReferenceDocumentation = inputKey[Unit]("Generate language reference documentation for Scala 3")
33323338

33333339
lazy val `scaladoc-testcases` = project.in(file("scaladoc-testcases")).
@@ -3454,31 +3460,135 @@ object Build {
34543460
val outputDirOverride = extraArgs.headOption.fold(identity[GenerationConfig](_))(newDir => {
34553461
config: GenerationConfig => config.add(OutputDir(newDir))
34563462
})
3457-
val justAPIArg: Option[String] = extraArgs.drop(1).find(_ == "--justAPI")
3458-
val justAPI = justAPIArg.fold(identity[GenerationConfig](_))(_ => {
3459-
config: GenerationConfig => config.remove[SiteRoot]
3460-
})
3461-
val overrideFunc = outputDirOverride.andThen(justAPI)
3463+
val justAPI = extraArgs.contains("--justAPI")
3464+
def justAPIOverride(config: GenerationConfig): GenerationConfig = {
3465+
if (!justAPI) config
3466+
else {
3467+
val siteRoot = IO.createTemporaryDirectory.getAbsolutePath()
3468+
config.add(SiteRoot(siteRoot))
3469+
}
3470+
}
3471+
3472+
// It would be the easiest to create a temp directory and apply patches there, but this task would be used frequently during development
3473+
// If we'd build using copy the emitted warnings would point developers to copies instead of original sources. Any fixes made in there would be lost.
3474+
// Instead let's apply revertable patches to the files as part snapshot doc generation process
3475+
abstract class SourcePatch(val file: File) {
3476+
def apply(): Unit
3477+
def revert(): Unit
3478+
}
3479+
val docs = file("docs")
3480+
val sourcePatches = if (justAPI) Nil else Seq(
3481+
// Generate full sidebar.yml based on template and reference content
3482+
new SourcePatch(docs / "sidebar.yml") {
3483+
val referenceSideBarCopy = IO.temporaryDirectory / "sidebar.yml.copy"
3484+
IO.copyFile(file, referenceSideBarCopy)
3485+
3486+
override def apply(): Unit = {
3487+
val yaml = new org.yaml.snakeyaml.Yaml()
3488+
type YamlObject = java.util.Map[String, AnyRef]
3489+
type YamlList[T] = java.util.List[T]
3490+
def loadYaml(file: File): YamlObject = {
3491+
val reader = Files.newBufferedReader(file.toPath)
3492+
try yaml.load(reader).asInstanceOf[YamlObject]
3493+
finally reader.close()
3494+
}
3495+
// Ensure to always operate on original (Map, List) instances
3496+
val template = loadYaml(docs / "sidebar.nightly.template.yml")
3497+
template.get("subsection")
3498+
.asInstanceOf[YamlList[YamlObject]]
3499+
.stream()
3500+
.filter(_.get("title") == "Reference")
3501+
.findFirst()
3502+
.orElseThrow(() => new IllegalStateException("Reference subsection not found in sidebar.nightly.template.yml"))
3503+
.putAll(loadYaml(referenceSideBarCopy))
3504+
3505+
val sidebarWriter = Files.newBufferedWriter(this.file.toPath)
3506+
try yaml.dump(template, sidebarWriter)
3507+
finally sidebarWriter.close()
3508+
}
3509+
override def revert(): Unit = IO.move(referenceSideBarCopy, file)
3510+
},
3511+
// Add patch about nightly version usage
3512+
new SourcePatch(docs / "_layouts" / "static-site-main.html") {
3513+
lazy val originalContent = IO.read(file)
3514+
3515+
val warningMessage = """{% if page.nightlyOf %}
3516+
| <aside class="warning">
3517+
| <div class='icon'></div>
3518+
| <div class='content'>
3519+
| This is a nightly documentation. The content of this page may not be consistent with the current stable version of language.
3520+
| Click <a href="{{ page.nightlyOf }}">here</a> to find the stable version of this page.
3521+
| </div>
3522+
| </aside>
3523+
|{% endif %}""".stripMargin
3524+
3525+
override def apply(): Unit = {
3526+
IO.write(file,
3527+
originalContent
3528+
.replace("{{ content }}", s"$warningMessage {{ content }}")
3529+
.ensuring(_.contains(warningMessage), "patch to static-site-main layout not applied!")
3530+
)
3531+
}
3532+
override def revert(): Unit = IO.write(file, originalContent)
3533+
}
3534+
)
34623535

34633536
val config = Def.task {
3464-
overrideFunc(Scala3.value)
3537+
outputDirOverride
3538+
.andThen(justAPIOverride)
3539+
.apply(Scala3.value)
34653540
}
34663541

34673542
val writeAdditionalFiles = Def.task {
34683543
val dest = file(config.value.get[OutputDir].get.value)
3469-
if (justAPIArg.isEmpty) {
3544+
if (!justAPI) {
34703545
IO.write(dest / "versions" / "latest-nightly-base", majorVersion)
34713546
// This file is used by GitHub Pages when the page is available in a custom domain
34723547
IO.write(dest / "CNAME", "dotty.epfl.ch")
34733548
}
34743549
}
3550+
val applyPatches = Def.task {
3551+
streams.value.log.info(s"Generating snapshot scaladoc, would apply patches to ${sourcePatches.map(_.file)}")
3552+
sourcePatches.foreach(_.apply())
3553+
}
3554+
val revertPatches = Def.task {
3555+
streams.value.log.info(s"Generated snapshot scaladoc, reverting changes made to ${sourcePatches.map(_.file)}")
3556+
sourcePatches.foreach(_.revert())
3557+
}
34753558

3476-
writeAdditionalFiles.dependsOn(generateDocumentation(config))
3559+
writeAdditionalFiles.dependsOn(
3560+
revertPatches.dependsOn(
3561+
generateDocumentation(config)
3562+
.dependsOn(applyPatches)
3563+
)
3564+
)
34773565
}.evaluated,
34783566

34793567
generateStableScala3Documentation := Def.inputTaskDyn {
34803568
val extraArgs = spaceDelimited("<version>").parsed
3481-
val config = stableScala3(extraArgs.head)
3569+
val version = baseVersion
3570+
// In the early days of scaladoc there was a practice to precompile artifacts of Scala 3 and generate docs using different version of scaladoc
3571+
// It's no longer needed after its stablisation.
3572+
// Allow to use explcit version check to detect using incorrect revision during release process
3573+
extraArgs.headOption.foreach { explicitVersion =>
3574+
assert(
3575+
explicitVersion == version,
3576+
s"Version of the build ($version) does not match the explicit verion ($explicitVersion)"
3577+
)
3578+
}
3579+
3580+
val docs = IO.createTemporaryDirectory
3581+
IO.copyDirectory(file("docs"), docs)
3582+
IO.delete(docs / "_blog")
3583+
3584+
val config = Def.task {
3585+
Scala3.value
3586+
.add(ProjectVersion(version))
3587+
.add(Revision(version))
3588+
.add(OutputDir(s"scaladoc/output/${version}"))
3589+
.add(SiteRoot(docs.getAbsolutePath))
3590+
.remove[ApiSubdirectory]
3591+
}
34823592
generateDocumentation(config)
34833593
}.evaluated,
34843594

@@ -3493,20 +3603,13 @@ object Build {
34933603
generateStaticAssetsTask.value
34943604

34953605
// Move all the source files to a temporary directory and apply some changes specific to the reference documentation
3496-
val temp = IO.createTemporaryDirectory
3497-
IO.copyDirectory(file("docs"), temp / "docs")
3498-
IO.delete(temp / "docs" / "_blog")
3499-
3500-
// Overwrite the main layout and the sidebar
3501-
IO.copyDirectory(
3502-
file("project") / "resources" / "referenceReplacements",
3503-
temp / "docs",
3504-
overwrite = true
3505-
)
3606+
val docs = IO.createTemporaryDirectory
3607+
IO.copyDirectory(file("docs"), docs)
3608+
IO.delete(docs / "_blog")
35063609

35073610
// Add redirections from previously supported URLs, for some pages
35083611
for (name <- Seq("changed-features", "contextual", "dropped-features", "metaprogramming", "other-new-features")) {
3509-
val path = temp / "docs" / "_docs" / "reference" / name / s"${name}.md"
3612+
val path = docs / "_docs" / "reference" / name / s"${name}.md"
35103613
val contentLines = IO.read(path).linesIterator.to[collection.mutable.ArrayBuffer]
35113614
contentLines.insert(1, s"redirectFrom: /${name}.html") // Add redirection
35123615
val newContent = contentLines.mkString("\n")
@@ -3516,12 +3619,12 @@ object Build {
35163619
val languageReferenceConfig = Def.task {
35173620
Scala3.value
35183621
.add(OutputDir("scaladoc/output/reference"))
3519-
.add(SiteRoot(s"${temp.getAbsolutePath}/docs"))
3622+
.add(SiteRoot(docs.getAbsolutePath))
35203623
.add(ProjectName("Scala 3 Reference"))
35213624
.add(ProjectVersion(baseVersion))
35223625
.remove[VersionsDictionaryUrl]
35233626
.add(SourceLinks(List(
3524-
s"${temp.getAbsolutePath}=github://scala/scala3/language-reference-stable"
3627+
s"${docs.getParentFile().getAbsolutePath}=github://scala/scala3/language-reference-stable"
35253628
)))
35263629
.withTargets(List("___fake___.scala"))
35273630
}
@@ -4007,6 +4110,7 @@ object ScaladocConfigs {
40074110
.add(DocumentSyntheticTypes(true))
40084111
//.add(SnippetCompiler(List(
40094112
//s"$dottyLibRoot/src/scala=compile",
4113+
//s"$dottyLibRoot/src/scala/quoted=compile",
40104114
//s"$dottyLibRoot/src/scala/compiletime=compile",
40114115
//s"$dottyLibRoot/src/scala/util=compile",
40124116
//s"$dottyLibRoot/src/scala/util/control=compile"
@@ -4016,33 +4120,4 @@ object ScaladocConfigs {
40164120
.withTargets((`scala-library-bootstrapped` / Compile / products).value.map(_.getAbsolutePath))
40174121
}
40184122

4019-
def stableScala3(version: String) = Def.task {
4020-
val scalaLibrarySrc = s"out/bootstrap/scala2-library-bootstrapped/scala-$version-bin-SNAPSHOT-nonbootstrapped/src_managed"
4021-
val dottyLibrarySrc = "library/src"
4022-
Scala3.value
4023-
.add(defaultSourceLinks(version = version))
4024-
.add(ProjectVersion(version))
4025-
.add(SnippetCompiler(
4026-
List(
4027-
s"$dottyLibrarySrc/scala/quoted=compile",
4028-
s"$dottyLibrarySrc/scala/compiletime=compile",
4029-
s"$dottyLibrarySrc/scala/util=compile",
4030-
s"$dottyLibrarySrc/scala/util/control=compile"
4031-
)
4032-
))
4033-
.add(CommentSyntax(List(
4034-
s"$dottyLibrarySrc=markdown",
4035-
s"$scalaLibrarySrc=wiki",
4036-
"wiki"
4037-
)))
4038-
.add(DocRootContent(s"$scalaLibrarySrc/rootdoc.txt"))
4039-
.withTargets(
4040-
Seq(
4041-
s"tmp/interfaces/target/classes",
4042-
s"out/bootstrap/tasty-core-bootstrapped/scala-$version-bin-SNAPSHOT-nonbootstrapped/classes"
4043-
)
4044-
)
4045-
.remove[SiteRoot]
4046-
.remove[ApiSubdirectory]
4047-
}
40484123
}

project/build.sbt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit" % "4.11.0.201803080745-r"
33

44
libraryDependencies += Dependencies.`jackson-databind`
5+
6+
// Used for manipulating YAML files in sidebar generation script
7+
libraryDependencies += "org.yaml" % "snakeyaml" % "2.4"

project/resources/referenceReplacements/_layouts/static-site-main.html

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)