Skip to content

Commit

Permalink
Support K2 Analysis in DGPv2 (#3743)
Browse files Browse the repository at this point in the history
* Support K2 Analysis in DGPv2

- Support toggling between K1 and K2 analysis when DGP is in V2 mode.
- Update DGPv1 to use PluginFeaturesService to query the `tryK2` flag.
- Add `org.jetbrains.dokka.experimental.tryK2.noWarn=true` to permit suppressing the K2 Analysis warning.
 - Add test for 'tryK2' messages.
- Fix & tidy Dokka feature flags in tests.
  • Loading branch information
adam-enko authored Aug 22, 2024
1 parent 0bdff4b commit 5b36ce6
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ internal class DokkaArtifacts(private val project: Project) {
private fun fromModuleName(name: String): Dependency =
project.dependencies.create("org.jetbrains.dokka:$name:${DokkaVersion.version}")

// TODO [beresnev] analysis switcher
/** K1 Analysis */
val analysisKotlinDescriptors get() = fromModuleName("analysis-kotlin-descriptors")

/** K2 Analysis */
val analysisKotlinSymbols get() = fromModuleName("analysis-kotlin-symbols")

val allModulesPage get() = fromModuleName("all-modules-page-plugin")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ open class DokkaClassicPlugin : Plugin<Project> {
project.logger.warn("Dokka: Build is using unsupported gradle version, expected at least 5.6 but got ${project.gradle.gradleVersion}. This may result in strange errors")
}

if (project.shouldUseK2())
project.logger.warn(
"Dokka's K2 Analysis is being used. " +
"It is still under active development and is thus experimental. " +
"It can be the cause of failed builds or incorrectly generated documentation. " +
"If you encounter an issue, please consider reporting it: https://github.com/Kotlin/dokka/issues"
)

project.setupDokkaTasks("dokkaHtml") {
description = "Generates documentation in 'html' format"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.attributes.Usage
import org.gradle.kotlin.dsl.named

internal fun Project.shouldUseK2() =
(findProperty("org.jetbrains.dokka.experimental.tryK2") as? String)?.toBoolean() ?: false
import org.jetbrains.dokka.gradle.internal.PluginFeaturesService.Companion.pluginFeaturesService

internal fun Project.maybeCreateDokkaDefaultPluginConfiguration(): Configuration {
return configurations.maybeCreate("dokkaPlugin") {
Expand All @@ -36,8 +34,11 @@ internal fun Project.maybeCreateDokkaPluginConfiguration(
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
isCanBeConsumed = false
dependencies.add(
if (shouldUseK2()) project.dokkaArtifacts.analysisKotlinSymbols
else project.dokkaArtifacts.analysisKotlinDescriptors
if (project.pluginFeaturesService.enableK2Analysis) {
project.dokkaArtifacts.analysisKotlinSymbols
} else {
project.dokkaArtifacts.analysisKotlinDescriptors
}
)
dependencies.add(project.dokkaArtifacts.dokkaBase)
dependencies.addAll(additionalDependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.jetbrains.dokka.gradle.dependencies.DokkaAttribute.Companion.DokkaCla
import org.jetbrains.dokka.gradle.dependencies.DokkaAttribute.Companion.DokkaFormatAttribute
import org.jetbrains.dokka.gradle.dependencies.FormatDependenciesManager
import org.jetbrains.dokka.gradle.internal.DokkaInternalApi
import org.jetbrains.dokka.gradle.internal.PluginFeaturesService.Companion.pluginFeaturesService
import javax.inject.Inject

/**
Expand Down Expand Up @@ -223,7 +224,13 @@ abstract class DokkaFormatPlugin(
dokkaPlugin(dokka("templating-plugin"))
dokkaPlugin(dokka("dokka-base"))

dokkaGenerator(dokka("analysis-kotlin-descriptors"))
dokkaGenerator(
if (project.pluginFeaturesService.enableK2Analysis) {
dokka("analysis-kotlin-symbols") // K2 analysis
} else {
dokka("analysis-kotlin-descriptors") // K1 analysis
}
)
dokkaGenerator(dokka("dokka-core"))
dokkaGenerator("org.freemarker:freemarker" version freemarker)
dokkaGenerator("org.jetbrains:markdown" version jetbrainsMarkdown)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.kotlin.dsl.extra
import kotlin.LazyThreadSafetyMode.SYNCHRONIZED

/**
* Internal utility service for managing Dokka Plugin features and warnings.
Expand All @@ -31,6 +30,12 @@ internal abstract class PluginFeaturesService : BuildService<PluginFeaturesServi

/** @see [PluginFeaturesService.primaryService] */
val primaryService: Property<Boolean>

/** If `true`, enable K2 analysis. */
val k2AnalysisEnabled: Property<Boolean>

/** If `true`, suppress the K2 analysis message. */
val k2AnalysisNoWarn: Property<Boolean>
}

/**
Expand All @@ -51,7 +56,7 @@ internal abstract class PluginFeaturesService : BuildService<PluginFeaturesServi
*
* Otherwise, fallback to V1 [org.jetbrains.dokka.gradle.DokkaClassicPlugin].
*/
internal val v2PluginEnabled: Boolean by lazy(SYNCHRONIZED) {
internal val v2PluginEnabled: Boolean by lazy {
val v2PluginEnabled = parameters.v2PluginEnabled.getOrElse(false)

if (v2PluginEnabled) {
Expand Down Expand Up @@ -112,6 +117,39 @@ internal abstract class PluginFeaturesService : BuildService<PluginFeaturesServi
}
}

internal val enableK2Analysis: Boolean by lazy {
// use lazy {} to ensure messages are only logged once

val enableK2Analysis = parameters.k2AnalysisEnabled.getOrElse(false)

if (enableK2Analysis) {
logK2AnalysisMessage()
}

enableK2Analysis
}

private fun logK2AnalysisMessage() {
if (primaryService && !parameters.k2AnalysisNoWarn.getOrElse(false)) {
logger.warn(
"""
|Dokka K2 Analysis is enabled
|
| This feature is Experimental and is still under active development.
| It can cause build failures or generate incorrect documentation.
|
| We would appreciate your feedback!
| Please report any feedback or problems to Dokka GitHub Issues
| https://github.com/Kotlin/dokka/issues/
|
| You can suppress this message by adding
| $K2_ANALYSIS_NO_WARN_FLAG_PRETTY=true
| to your project's `gradle.properties`
""".trimMargin().surroundWithBorder()
)
}
}

companion object {
private val logger = Logging.getLogger(PluginFeaturesService::class.java)

Expand All @@ -127,6 +165,15 @@ internal abstract class PluginFeaturesService : BuildService<PluginFeaturesServi
private const val V2_PLUGIN_NO_WARN_FLAG_PRETTY =
"$V2_PLUGIN_ENABLED_FLAG.noWarn"

private const val K2_ANALYSIS_ENABLED_FLAG =
"org.jetbrains.dokka.experimental.tryK2"

private const val K2_ANALYSIS_NO_WARN_FLAG =
"$K2_ANALYSIS_ENABLED_FLAG.nowarn"

private const val K2_ANALYSIS_NO_WARN_FLAG_PRETTY =
"$K2_ANALYSIS_ENABLED_FLAG.noWarn"

/**
* Register a new [PluginFeaturesService], or get an existing instance.
*/
Expand All @@ -135,6 +182,11 @@ internal abstract class PluginFeaturesService : BuildService<PluginFeaturesServi
val setFlags = Action<Params> {
v2PluginEnabled.set(getFlag(V2_PLUGIN_ENABLED_FLAG))
v2PluginNoWarn.set(getFlag(V2_PLUGIN_NO_WARN_FLAG_PRETTY).orElse(getFlag(V2_PLUGIN_NO_WARN_FLAG)))
k2AnalysisEnabled.set(getFlag(K2_ANALYSIS_ENABLED_FLAG))
k2AnalysisNoWarn.set(
getFlag(K2_ANALYSIS_NO_WARN_FLAG_PRETTY)
.orElse(getFlag(K2_ANALYSIS_NO_WARN_FLAG))
)
}

return try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ class GradleProjectTest(

/** Dokka specific options. */
data class DokkaArgs(
var enableV2Plugin: Boolean? = true,
var disableV2PluginWarning: Boolean? = enableV2Plugin,
var v2Plugin: Boolean? = true,
var v2PluginNoWarn: Boolean? = v2Plugin,
var k2Analysis: Boolean? = null,
var k2AnalysisNoWarn: Boolean? = null,
var enableLogHtmlPublicationLink: Boolean? = false,
)

Expand Down Expand Up @@ -119,8 +121,10 @@ class GradleProjectTest(
}

with(dokka) {
putNotNull("org.jetbrains.dokka.experimental.gradlePlugin.enableV2", enableV2Plugin)
putNotNull("org.jetbrains.dokka.experimental.gradlePlugin.enableV2.nowarn", enableV2Plugin)
putNotNull("org.jetbrains.dokka.experimental.gradlePlugin.enableV2", v2Plugin)
putNotNull("org.jetbrains.dokka.experimental.gradlePlugin.enableV2.noWarn", v2PluginNoWarn)
putNotNull("org.jetbrains.dokka.experimental.tryK2", k2Analysis)
putNotNull("org.jetbrains.dokka.experimental.tryK2.noWarn", k2AnalysisNoWarn)
putNotNull("org.jetbrains.dokka.gradle.enableLogHtmlPublicationLink", enableLogHtmlPublicationLink)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ private fun migrationMessagesTestProject(

gradleProperties {
dokka {
enableV2Plugin = null
disableV2PluginWarning = null
v2Plugin = null
v2PluginNoWarn = null
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package org.jetbrains.dokka.gradle

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.string.shouldContainOnlyOnce
import org.jetbrains.dokka.gradle.utils.addArguments
import org.jetbrains.dokka.gradle.utils.build
import org.jetbrains.dokka.gradle.utils.projects.initMultiModuleProject
import org.jetbrains.dokka.gradle.utils.shouldNotContainAnyOf

class TryK2MessagesTest : FunSpec({

context("given multi-module project") {

// Test with a multi-module project to verify that even though there
// are multiple subprojects with Dokka only one message is logged.
val project = initMultiModuleProject("TryK2MessagesTest")

context("when K2 enabled") {
project.runner

.addArguments(
":dokkaGenerate",
"-P$K2_ANALYSIS_ENABLED_FLAG=true",
)
.addArguments()
.build {
test("output should contain K2 analysis warning") {
output shouldContainOnlyOnce """
┌───────────────────────────────────────────────────────────────────────┐
│ Dokka K2 Analysis is enabled │
│ │
│ This feature is Experimental and is still under active development. │
│ It can cause build failures or generate incorrect documentation. │
│ │
│ We would appreciate your feedback! │
│ Please report any feedback or problems to Dokka GitHub Issues │
│ https://github.com/Kotlin/dokka/issues/ │
│ │
│ You can suppress this message by adding │
│ org.jetbrains.dokka.experimental.tryK2.noWarn=true │
│ to your project's `gradle.properties` │
└───────────────────────────────────────────────────────────────────────┘
""".trimIndent()
}
}

listOf(
K2_ANALYSIS_NO_WARN_FLAG,
K2_ANALYSIS_NO_WARN_FLAG_PRETTY,
).forEach { noWarnFlag ->
context("and message is suppressed with $noWarnFlag") {
project.runner
.addArguments(
":dokkaGenerate",
"-P$K2_ANALYSIS_ENABLED_FLAG=true",
"-P$noWarnFlag=true",
)
.build {
test("output should not contain any Dokka plugin message") {
output.shouldNotContainAnyOf(
"Dokka K2 Analysis",
"https://github.com/Kotlin/dokka/issues/",
"org.jetbrains.dokka.experimental.gradlePlugin",
K2_ANALYSIS_ENABLED_FLAG,
K2_ANALYSIS_NO_WARN_FLAG,
K2_ANALYSIS_NO_WARN_FLAG_PRETTY,
noWarnFlag,
)
}
}
}
}
}
}
}) {
companion object {

private const val K2_ANALYSIS_ENABLED_FLAG =
"org.jetbrains.dokka.experimental.tryK2"

private const val K2_ANALYSIS_NO_WARN_FLAG =
"$K2_ANALYSIS_ENABLED_FLAG.nowarn"

private const val K2_ANALYSIS_NO_WARN_FLAG_PRETTY =
"$K2_ANALYSIS_ENABLED_FLAG.noWarn"
}
}

0 comments on commit 5b36ce6

Please sign in to comment.