Skip to content

Commit d5cda61

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 b1a5500 commit d5cda61

File tree

8 files changed

+397
-516
lines changed

8 files changed

+397
-516
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: 186 additions & 248 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
@@ -3396,11 +3396,17 @@ object Build {
33963396
val testcasesSourceRoot = taskKey[String]("Root directory where tests sources are generated")
33973397
val testDocumentationRoot = taskKey[String]("Root directory where tests documentation are stored")
33983398
val generateSelfDocumentation = taskKey[Unit]("Generate example documentation")
3399-
// Note: the two tasks below should be one, but a bug in Tasty prevents that
3400-
val generateScalaDocumentation = inputKey[Unit]("Generate documentation for dotty lib")
3401-
val generateStableScala3Documentation = inputKey[Unit]("Generate documentation for stable dotty lib")
34023399
val generateTestcasesDocumentation = taskKey[Unit]("Generate documentation for testcases, useful for debugging tests")
34033400

3401+
// Published on https://dotty.epfl.ch/ by nightly builds
3402+
// Contains additional internal/contributing docs
3403+
val generateScalaDocumentation = inputKey[Unit]("Generate documentation for snapshot release")
3404+
3405+
// Published on https://docs.scala-lang.org/api/all.html
3406+
val generateStableScala3Documentation = inputKey[Unit]("Generate documentation for stable release")
3407+
3408+
// Published on https://docs.scala-lang.org/scala3/reference/
3409+
// Does not produce API docs, contains additional redirects for improved stablity
34043410
val generateReferenceDocumentation = inputKey[Unit]("Generate language reference documentation for Scala 3")
34053411

34063412
lazy val `scaladoc-testcases` = project.in(file("scaladoc-testcases")).
@@ -3527,31 +3533,135 @@ object Build {
35273533
val outputDirOverride = extraArgs.headOption.fold(identity[GenerationConfig](_))(newDir => {
35283534
config: GenerationConfig => config.add(OutputDir(newDir))
35293535
})
3530-
val justAPIArg: Option[String] = extraArgs.drop(1).find(_ == "--justAPI")
3531-
val justAPI = justAPIArg.fold(identity[GenerationConfig](_))(_ => {
3532-
config: GenerationConfig => config.remove[SiteRoot]
3533-
})
3534-
val overrideFunc = outputDirOverride.andThen(justAPI)
3536+
val justAPI = extraArgs.contains("--justAPI")
3537+
def justAPIOverride(config: GenerationConfig): GenerationConfig = {
3538+
if (!justAPI) config
3539+
else {
3540+
val siteRoot = IO.createTemporaryDirectory.getAbsolutePath()
3541+
config.add(SiteRoot(siteRoot))
3542+
}
3543+
}
3544+
3545+
// It would be the easiest to create a temp directory and apply patches there, but this task would be used frequently during development
3546+
// 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.
3547+
// Instead let's apply revertable patches to the files as part snapshot doc generation process
3548+
abstract class SourcePatch(val file: File) {
3549+
def apply(): Unit
3550+
def revert(): Unit
3551+
}
3552+
val docs = file("docs")
3553+
val sourcePatches = if (justAPI) Nil else Seq(
3554+
// Generate full sidebar.yml based on template and reference content
3555+
new SourcePatch(docs / "sidebar.yml") {
3556+
val referenceSideBarCopy = IO.temporaryDirectory / "sidebar.yml.copy"
3557+
IO.copyFile(file, referenceSideBarCopy)
3558+
3559+
override def apply(): Unit = {
3560+
val yaml = new org.yaml.snakeyaml.Yaml()
3561+
type YamlObject = java.util.Map[String, AnyRef]
3562+
type YamlList[T] = java.util.List[T]
3563+
def loadYaml(file: File): YamlObject = {
3564+
val reader = Files.newBufferedReader(file.toPath)
3565+
try yaml.load(reader).asInstanceOf[YamlObject]
3566+
finally reader.close()
3567+
}
3568+
// Ensure to always operate on original (Map, List) instances
3569+
val template = loadYaml(docs / "sidebar.nightly.template.yml")
3570+
template.get("subsection")
3571+
.asInstanceOf[YamlList[YamlObject]]
3572+
.stream()
3573+
.filter(_.get("title") == "Reference")
3574+
.findFirst()
3575+
.orElseThrow(() => new IllegalStateException("Reference subsection not found in sidebar.nightly.template.yml"))
3576+
.putAll(loadYaml(referenceSideBarCopy))
3577+
3578+
val sidebarWriter = Files.newBufferedWriter(this.file.toPath)
3579+
try yaml.dump(template, sidebarWriter)
3580+
finally sidebarWriter.close()
3581+
}
3582+
override def revert(): Unit = IO.move(referenceSideBarCopy, file)
3583+
},
3584+
// Add patch about nightly version usage
3585+
new SourcePatch(docs / "_layouts" / "static-site-main.html") {
3586+
lazy val originalContent = IO.read(file)
3587+
3588+
val warningMessage = """{% if page.nightlyOf %}
3589+
| <aside class="warning">
3590+
| <div class='icon'></div>
3591+
| <div class='content'>
3592+
| This is a nightly documentation. The content of this page may not be consistent with the current stable version of language.
3593+
| Click <a href="{{ page.nightlyOf }}">here</a> to find the stable version of this page.
3594+
| </div>
3595+
| </aside>
3596+
|{% endif %}""".stripMargin
3597+
3598+
override def apply(): Unit = {
3599+
IO.write(file,
3600+
originalContent
3601+
.replace("{{ content }}", s"$warningMessage {{ content }}")
3602+
.ensuring(_.contains(warningMessage), "patch to static-site-main layout not applied!")
3603+
)
3604+
}
3605+
override def revert(): Unit = IO.write(file, originalContent)
3606+
}
3607+
)
35353608

35363609
val config = Def.task {
3537-
overrideFunc(Scala3.value)
3610+
outputDirOverride
3611+
.andThen(justAPIOverride)
3612+
.apply(Scala3.value)
35383613
}
35393614

35403615
val writeAdditionalFiles = Def.task {
35413616
val dest = file(config.value.get[OutputDir].get.value)
3542-
if (justAPIArg.isEmpty) {
3617+
if (!justAPI) {
35433618
IO.write(dest / "versions" / "latest-nightly-base", majorVersion)
35443619
// This file is used by GitHub Pages when the page is available in a custom domain
35453620
IO.write(dest / "CNAME", "dotty.epfl.ch")
35463621
}
35473622
}
3623+
val applyPatches = Def.task {
3624+
streams.value.log.info(s"Generating snapshot scaladoc, would apply patches to ${sourcePatches.map(_.file)}")
3625+
sourcePatches.foreach(_.apply())
3626+
}
3627+
val revertPatches = Def.task {
3628+
streams.value.log.info(s"Generated snapshot scaladoc, reverting changes made to ${sourcePatches.map(_.file)}")
3629+
sourcePatches.foreach(_.revert())
3630+
}
35483631

3549-
writeAdditionalFiles.dependsOn(generateDocumentation(config))
3632+
writeAdditionalFiles.dependsOn(
3633+
revertPatches.dependsOn(
3634+
generateDocumentation(config)
3635+
.dependsOn(applyPatches)
3636+
)
3637+
)
35503638
}.evaluated,
35513639

35523640
generateStableScala3Documentation := Def.inputTaskDyn {
35533641
val extraArgs = spaceDelimited("<version>").parsed
3554-
val config = stableScala3(extraArgs.head)
3642+
val version = baseVersion
3643+
// In the early days of scaladoc there was a practice to precompile artifacts of Scala 3 and generate docs using different version of scaladoc
3644+
// It's no longer needed after its stablisation.
3645+
// Allow to use explcit version check to detect using incorrect revision during release process
3646+
extraArgs.headOption.foreach { explicitVersion =>
3647+
assert(
3648+
explicitVersion == version,
3649+
s"Version of the build ($version) does not match the explicit verion ($explicitVersion)"
3650+
)
3651+
}
3652+
3653+
val docs = IO.createTemporaryDirectory
3654+
IO.copyDirectory(file("docs"), docs)
3655+
IO.delete(docs / "_blog")
3656+
3657+
val config = Def.task {
3658+
Scala3.value
3659+
.add(ProjectVersion(version))
3660+
.add(Revision(version))
3661+
.add(OutputDir(s"scaladoc/output/${version}"))
3662+
.add(SiteRoot(docs.getAbsolutePath))
3663+
.remove[ApiSubdirectory]
3664+
}
35553665
generateDocumentation(config)
35563666
}.evaluated,
35573667

@@ -3566,20 +3676,13 @@ object Build {
35663676
generateStaticAssetsTask.value
35673677

35683678
// Move all the source files to a temporary directory and apply some changes specific to the reference documentation
3569-
val temp = IO.createTemporaryDirectory
3570-
IO.copyDirectory(file("docs"), temp / "docs")
3571-
IO.delete(temp / "docs" / "_blog")
3572-
3573-
// Overwrite the main layout and the sidebar
3574-
IO.copyDirectory(
3575-
file("project") / "resources" / "referenceReplacements",
3576-
temp / "docs",
3577-
overwrite = true
3578-
)
3679+
val docs = IO.createTemporaryDirectory
3680+
IO.copyDirectory(file("docs"), docs)
3681+
IO.delete(docs / "_blog")
35793682

35803683
// Add redirections from previously supported URLs, for some pages
35813684
for (name <- Seq("changed-features", "contextual", "dropped-features", "metaprogramming", "other-new-features")) {
3582-
val path = temp / "docs" / "_docs" / "reference" / name / s"${name}.md"
3685+
val path = docs / "_docs" / "reference" / name / s"${name}.md"
35833686
val contentLines = IO.read(path).linesIterator.to[collection.mutable.ArrayBuffer]
35843687
contentLines.insert(1, s"redirectFrom: /${name}.html") // Add redirection
35853688
val newContent = contentLines.mkString("\n")
@@ -3589,12 +3692,12 @@ object Build {
35893692
val languageReferenceConfig = Def.task {
35903693
Scala3.value
35913694
.add(OutputDir("scaladoc/output/reference"))
3592-
.add(SiteRoot(s"${temp.getAbsolutePath}/docs"))
3695+
.add(SiteRoot(docs.getAbsolutePath))
35933696
.add(ProjectName("Scala 3 Reference"))
35943697
.add(ProjectVersion(baseVersion))
35953698
.remove[VersionsDictionaryUrl]
35963699
.add(SourceLinks(List(
3597-
s"${temp.getAbsolutePath}=github://scala/scala3/language-reference-stable"
3700+
s"${docs.getParentFile().getAbsolutePath}=github://scala/scala3/language-reference-stable"
35983701
)))
35993702
.withTargets(List("___fake___.scala"))
36003703
}
@@ -4081,6 +4184,7 @@ object ScaladocConfigs {
40814184
.add(DocumentSyntheticTypes(true))
40824185
//.add(SnippetCompiler(List(
40834186
//s"$dottyLibRoot/src/scala=compile",
4187+
//s"$dottyLibRoot/src/scala/quoted=compile",
40844188
//s"$dottyLibRoot/src/scala/compiletime=compile",
40854189
//s"$dottyLibRoot/src/scala/util=compile",
40864190
//s"$dottyLibRoot/src/scala/util/control=compile"
@@ -4090,33 +4194,4 @@ object ScaladocConfigs {
40904194
.withTargets((`scala-library-bootstrapped` / Compile / products).value.map(_.getAbsolutePath))
40914195
}
40924196

4093-
def stableScala3(version: String) = Def.task {
4094-
val scalaLibrarySrc = s"out/bootstrap/scala2-library-bootstrapped/scala-$version-bin-SNAPSHOT-nonbootstrapped/src_managed"
4095-
val dottyLibrarySrc = "library/src"
4096-
Scala3.value
4097-
.add(defaultSourceLinks(version = version))
4098-
.add(ProjectVersion(version))
4099-
.add(SnippetCompiler(
4100-
List(
4101-
s"$dottyLibrarySrc/scala/quoted=compile",
4102-
s"$dottyLibrarySrc/scala/compiletime=compile",
4103-
s"$dottyLibrarySrc/scala/util=compile",
4104-
s"$dottyLibrarySrc/scala/util/control=compile"
4105-
)
4106-
))
4107-
.add(CommentSyntax(List(
4108-
s"$dottyLibrarySrc=markdown",
4109-
s"$scalaLibrarySrc=wiki",
4110-
"wiki"
4111-
)))
4112-
.add(DocRootContent(s"$scalaLibrarySrc/rootdoc.txt"))
4113-
.withTargets(
4114-
Seq(
4115-
s"tmp/interfaces/target/classes",
4116-
s"out/bootstrap/tasty-core-bootstrapped/scala-$version-bin-SNAPSHOT-nonbootstrapped/classes"
4117-
)
4118-
)
4119-
.remove[SiteRoot]
4120-
.remove[ApiSubdirectory]
4121-
}
41224197
}

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)