diff --git a/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt b/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt index b2caac6..5b26575 100644 --- a/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt +++ b/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt @@ -1,18 +1,16 @@ package opensavvy.dokka.gradle import org.gradle.api.Project -import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.Usage import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.provider.Provider import org.gradle.api.tasks.Sync -import org.gradle.kotlin.dsl.* -import org.jetbrains.dokka.gradle.DokkaExtension +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getValue +import org.gradle.kotlin.dsl.provideDelegate +import org.gradle.kotlin.dsl.registering import org.jetbrains.dokka.gradle.formats.DokkaFormatPlugin import org.jetbrains.dokka.gradle.internal.InternalDokkaGradlePluginApi import org.jetbrains.dokka.gradle.tasks.DokkaGenerateModuleTask -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import java.io.File abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { @@ -25,39 +23,6 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { dokkaPlugin("dev.opensavvy.dokka.mkdocs:renderer:$DokkaMkDocsVersion") } - // all-modules-page-plugin goes into dokkaMkdocsPublicationPlugin (added in apply() below). - // It is an external Maven artifact with no Dokka-specific Gradle metadata, so Gradle - // resolves it directly as a JAR without any attribute-matching issues. - - // The aggregator is a local project that also applies DokkaMkDocsPlugin. If it were added to - // dokkaMkdocsPublicationPlugin (DokkaClasspathAttribute=dokka-publication-plugins), Gradle - // would select the aggregator project's empty dokkaMkdocsPublicationPluginApiOnlyConsumable - // instead of its JAR (because that consumable matches DokkaClasspathAttribute=dokka-publication-plugins). - // - // Fix: use a separate configuration with DokkaClasspathAttribute=dokka-plugins. That value has - // no matching consumable on the aggregator project, so Gradle falls back to runtimeElements → JAR. - val aggregatorBucket = project.configurations.create("dokkaMkdocsAggregatorPlugin~internal") { - isCanBeResolved = false - isCanBeConsumed = false - } - project.dependencies.add("dokkaMkdocsAggregatorPlugin~internal", "dev.opensavvy.dokka.mkdocs:aggregator:$DokkaMkDocsVersion") - - val aggregatorResolver = project.configurations.create("dokkaMkdocsAggregatorPluginResolver~internal") { - isCanBeResolved = true - isCanBeConsumed = false - isTransitive = false - extendsFrom(aggregatorBucket) - attributes { - attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME)) - attribute(Attribute.of("org.jetbrains.dokka.format", String::class.java), formatName) - attribute(Attribute.of("org.jetbrains.dokka.classpath", String::class.java), "dokka-plugins") - } - } - - dokkaTasks.generatePublication.configure { - generator.pluginsClasspath.from(aggregatorResolver) - } - moduleOutputFiles = project.layout.buildDirectory.dir("dokka/mkdocs").map { listOf(it.asFile) } } @@ -69,8 +34,8 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { // "dokkaMkdocsPublicationPlugin" is used only by dokkaGeneratePublicationMkdocs, // not by the per-module dokkaGenerateModuleMkdocs task. // This prevents all-modules-page-plugin from suppressing singleGeneration in module tasks. - // (The aggregator is handled differently in configure() above.) target.dependencies.add("dokkaMkdocsPublicationPlugin", "org.jetbrains.dokka:all-modules-page-plugin:$DokkaVersion") + target.dependencies.add("dokkaMkdocsPublicationPlugin", "dev.opensavvy.dokka.mkdocs:aggregator:$DokkaMkDocsVersion") // Use the Gradle project's leaf name (e.g. "example-core") as the module path instead of // the full project path (e.g. "example/example-core"). This gives clean output URLs. @@ -78,14 +43,6 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { modulePath.set(target.name) } - // Fix: DGP v2's KotlinAdapter excludes the metadata compilation when building classpath lists. - // This leaves shared KMP source sets (e.g. commonMain) with only source directories on their - // analysis classpath, causing "Unresolved reference" errors for stdlib symbols. - // Detect these source sets and supply the JVM compilation classpath. - target.plugins.withId("org.jetbrains.kotlin.multiplatform") { - fixKmpCommonSourceSetClasspath(target) - } - val siteOutput = target.layout.projectDirectory.dir("docs/api") val navOutput = target.layout.buildDirectory.file("mkdocs/navigation.yaml") @@ -293,42 +250,6 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { } } - @OptIn(InternalDokkaGradlePluginApi::class) - private fun fixKmpCommonSourceSetClasspath(target: Project) { - val kmpExtension = target.extensions.getByType(KotlinMultiplatformExtension::class.java) - val dokkaExtension = target.extensions.getByType(DokkaExtension::class.java) - - // configureEach fires lazily during task-graph resolution, after all build files have been - // evaluated, so kmpExtension.targets and compilations are fully populated at that point. - dokkaExtension.dokkaSourceSets.configureEach { - val ksName = name - - // Non-metadata main compilations (e.g. jvmMain, jsMain) - val nonMetadataMain = kmpExtension.targets - .filter { it.platformType != KotlinPlatformType.common } - .mapNotNull { it.compilations.findByName("main") } - if (nonMetadataMain.isEmpty()) return@configureEach - - // Source sets directly owned by a compilation already have a classpath from DGP - val ownedNames = nonMetadataMain - .flatMapTo(mutableSetOf()) { it.kotlinSourceSets.map { s -> s.name } } - if (ksName in ownedNames) return@configureEach - - // For a shared/common source set, find the compilations that include it transitively - val kss = kmpExtension.sourceSets.findByName(ksName) ?: return@configureEach - val compilation = nonMetadataMain - .filter { kss in it.allKotlinSourceSets } - .let { list -> - // Prefer JVM — its stdlib JAR also contains common stdlib declarations - list.firstOrNull { it.target.platformType == KotlinPlatformType.jvm } - ?: list.firstOrNull() - } - ?: return@configureEach - - classpath.from(compilation.compileDependencyFiles) - } - } - companion object { private const val startMarker = "# !!! EMBEDDED DOKKA START, DO NOT COMMIT !!! #" private const val endMarker = "# !!! EMBEDDED DOKKA END, DO NOT COMMIT !!! #" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0da014c..deef868 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ java-lowestGradle = "17" # https://docs.gradle.org/current/userguide/compatibili coroutines = "1.10.2" # https://github.com/Kotlin/kotlinx.coroutines/releases -dokka = "2.1.0" # https://github.com/Kotlin/dokka/releases +dokka = "2.2.0" # https://github.com/Kotlin/dokka/releases [plugins] -- 2.51.2 From 2ef5c568aada588b499fd312f9fab578b63b7d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Fri, 27 Mar 2026 12:06:53 +0100 Subject: [PATCH 2/3] feat(dokka-mkdocs): Refuse to overwrite files --- dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt b/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt index 5b26575..2b45b1c 100644 --- a/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt +++ b/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt @@ -62,7 +62,7 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { } includeEmptyDirs = true - duplicatesStrategy = DuplicatesStrategy.WARN // TODO make each module generate files in its own directory, afterwards remove this + duplicatesStrategy = DuplicatesStrategy.FAIL } val generateMkDocsNavigation by target.tasks.registering { -- 2.51.2 From fea0f0892b5ffa903996a646747381ef15af43f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Fri, 27 Mar 2026 12:07:24 +0100 Subject: [PATCH 3/3] docs(dokka-mkdocs): Fix task descriptions that mentioned Dokkatoo --- dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt b/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt index 2b45b1c..e27ea99 100644 --- a/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt +++ b/dokka-mkdocs/src/main/kotlin/DokkaMkDocsPlugin.kt @@ -48,7 +48,7 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { val dokkaCopyIntoMkDocs by target.tasks.registering(Sync::class) { group = GROUP - description = "Copies the Dokkatoo pages into the website." + description = "Copies the Dokka pages into the website." val dokkaTasks = target.tasks.matching { it.name.startsWith("dokkaGenerate") && it.name.endsWith("Mkdocs") } dependsOn(dokkaTasks) @@ -240,7 +240,7 @@ abstract class DokkaMkDocsPlugin : DokkaFormatPlugin(formatName = "mkdocs") { val embedDokkaIntoMkDocs by target.tasks.registering { group = GROUP - description = "Lifecycle task to embed configured Dokkatoo modules into a Material for MkDocs website" + description = "Lifecycle task to embed configured Dokka modules into a Material for MkDocs website" dependsOn(dokkaCopyIntoMkDocs, embedMkDocsNavigation) }