Dokka GP v2 excludes the local module if submodules are added as dependencies
Describe the bug
I have a project with many subproject. The root project hosts the entrypoint of the entire application.
When generating documentation for the root project, if no subproject is added through dependency, only the local module's documentation is produced (as expected).
When, instead,
dependencies {
subprojects.forEach { dokka(it) }
}
is used, the documentation for all modules but the current is produced.
If
dependencies {
allprojects.forEach { dokka(it) }
}
is used instead, the local module is included, but the left menu has broken links
Expected behaviour
Either the local module is always included, or it can be included in the dependencies without breaking the website
Screenshots
This is the documentation generated with
dependencies {
allprojects.forEach { dokka(it) }
}
Links on the right work correctly, links in the left bar are broken.
To Reproduce
- Create a mutlimodule project
- Apply dokka
- add sources to the root project and to the subprojects
- Enable dokka v2
- run
dokkaGenerate
Dokka configuration
The following is my convention plugin for dokka. Looks complicated , but all the complexity is just linking source from GitHub and linking libraries from javadoc.io.
import Util.currentCommitHash
import Util.fetchJavadocIOForDependency
import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask
import org.jetbrains.dokka.gradle.tasks.DokkaBaseTask
import java.time.Duration
/*
* Copyright (C) 2010-2024, Danilo Pianini and contributors
* listed, for each module, in the respective subproject's build.gradle.kts file.
*
* This file is part of Alchemist, and is distributed under the terms of the
* GNU General Public License, with a linking exception,
* as described in the file LICENSE in the Alchemist distribution's top directory.
*/
plugins {
id("org.jetbrains.dokka")
}
val minJavaVersion: String by properties
dokka {
dokkaSourceSets.configureEach {
enableKotlinStdLibDocumentationLink.set(true)
enableJdkDocumentationLink.set(true)
jdkVersion.set(minJavaVersion.toInt())
skipDeprecated.set(false)
skipEmptyPackages.set(true)
/*
* Source links to GitHub
*/
listOf("kotlin", "java")
.flatMap { listOf("main/$it", "commonMain/$it", "jsMain/$it", "jvmMain/$it") }
.map { "src/$it" }
.associateWith { File(projectDir, it) }
.filterValues { it.exists() }
.forEach { (path, file) ->
sourceLink {
localDirectory.set(file)
val project = if (project == rootProject) "" else project.name
val url = "https://github.com/AlchemistSimulator/Alchemist/${
currentCommitHash?.let { "tree/$it" } ?: "blob/master"
}/$project/$path"
remoteUrl.set(uri(url))
remoteLineSuffix.set("#L")
}
}
/*
* Javadoc.io links for external dependencies
*/
val configured = mutableSetOf<ExternalDependency>()
configurations.configureEach {
val newDependencies = dependencies.withType<ExternalDependency>() - configured
configured += newDependencies
newDependencies.forEach { dependency ->
val javadocIOURLs = fetchJavadocIOForDependency(dependency)
if (javadocIOURLs != null) {
val (javadoc, packageList) = javadocIOURLs
externalDocumentationLinks.register(dependency.name) {
url.set(javadoc)
packageListUrl.set(packageList)
}
}
}
}
pluginsConfiguration.html {
customAssets.from(rootProject.file("site/static/images/logo.svg"))
customStyleSheets.from(rootProject.file("site/logo-styles.css"))
footerMessage.set("(c) Danilo Pianini and contributors listed in the Alchemist build files")
homepageLink = "https://alchemistsimulator.github.io/"
}
}
}
tasks.withType<DokkaBaseTask>().configureEach {
timeout.set(Duration.ofMinutes(5))
}
Installation
- Operating system: Linux
- Build tool: Gradle v8.11
- Dokka version: 2.0.0
It looks like there's a bug (not sure where, it could be DGP or Dokka Generator?) which removes a path element from the URL, so when opening the page locally the html dir is missing.
Expected:
<http://localhost:63342/dokka/examples/gradle-v2/multimodule-example/build/dokka/html/[root]/index.html>
Actual:
<http://localhost:63342/dokka/examples/gradle-v2/multimodule-example/build/dokka//index.html>
There's a little info in the duplicate here: https://github.com/Kotlin/dokka/issues/3992
Which of the two solutions has been adopted? Is the root module always included, or should the root module be declared as a dokka dependency?
Which of the two solutions has been adopted?
The actual reported issue is fixed by setting a distinct modulePath for the root project - see the KDoc for more info about modulePath.
The default modulePath used to be the project path, which for the root project is : - effectively a blank string. This means some files from the root project would overwrite the 'multi-module landing page' generated by Dokka. The fix was to use a more sensible (non-blank) default for modulePath, meaning the root project won't overwrite files.
Is the root module always included, or should the root module be declared as a dokka dependency?
It depends.
-
If there are no subprojects, then Dokka automatically generates a 'single module publication'. Don't write
dependencies { dokka(project(":") } } -
If there are multiple subprojects, and the root project is not a 'code' project with sources, then the root project shouldn't be included in the aggregated publication. Don't write
dependencies { dokka(project(":") } } -
If there are multiple subprojects, and the root project is a 'code' project, then yes, the root project needs to be included. Write
dependencies { dokka(project(":") } }to include the root project in the aggregated publication.
(Note that adding sources files to the root project is a discouraged practice https://docs.gradle.org/9.0.0/userguide/best_practices_general.html#no_source_in_root)
I hope that helps! If you have more questions, please ask.
Very clear. Thank you for the examples.