Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow analysisPlatform to be overridden #3902

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,12 @@ constructor(
sourceSetScopeConvention: Property<String>,
) {
configureEach dss@{

// Manually added sourceSets should not be suppressed by default.
// dokkaSourceSets that are automatically added by DokkaKotlinAdapter will have a sensible value for 'suppress'.
suppress.convention(false)
analysisPlatform.convention(KotlinPlatform.DEFAULT)

displayName.convention(
analysisPlatform.map { platform ->
// Match existing Dokka naming conventions. (This should probably be simplified!)
Expand All @@ -200,10 +205,6 @@ constructor(
skipEmptyPackages.convention(true)
sourceSetScope.convention(sourceSetScopeConvention)

// Manually added sourceSets should not be suppressed by default.
// dokkaSourceSets that are automatically added by DokkaKotlinAdapter will have a sensible value for 'suppress'.
suppress.convention(false)

suppressGeneratedFiles.convention(true)

sourceLinks.configureEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.gradle.api.tasks.Nested
import org.gradle.kotlin.dsl.newInstance
import org.jetbrains.dokka.gradle.dependencies.BaseDependencyManager
import org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceSetSpec
import org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceSetSpec.Companion.dokkaSourceSetSpecContainer
import org.jetbrains.dokka.gradle.formats.DokkaPublication
import org.jetbrains.dokka.gradle.internal.*
import org.jetbrains.dokka.gradle.workers.ClassLoaderIsolation
Expand Down Expand Up @@ -191,6 +192,7 @@ constructor(
* ```
*/
val dokkaSourceSets: NamedDomainObjectContainer<DokkaSourceSetSpec> =
//extensions.adding("dokkaSourceSets", objects.dokkaSourceSetSpecContainer())
extensions.adding("dokkaSourceSets", objects.domainObjectContainer())

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import org.gradle.kotlin.dsl.*
import org.jetbrains.dokka.gradle.DokkaBasePlugin
import org.jetbrains.dokka.gradle.DokkaExtension
import org.jetbrains.dokka.gradle.adapters.KotlinAdapter.Companion.currentKotlinToolingVersion
import org.jetbrains.dokka.gradle.engine.parameters.SourceSetIdSpec
import org.jetbrains.dokka.gradle.engine.parameters.SourceSetIdSpec.Companion.dokkaSourceSetIdSpec
import org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceSetSpec
import org.jetbrains.dokka.gradle.engine.parameters.KotlinPlatform
import org.jetbrains.dokka.gradle.engine.parameters.SourceSetIdSpec
import org.jetbrains.dokka.gradle.engine.parameters.SourceSetIdSpec.Companion.dokkaSourceSetIdSpec
import org.jetbrains.dokka.gradle.internal.*
import org.jetbrains.kotlin.commonizer.KonanDistribution
import org.jetbrains.kotlin.commonizer.platformLibsDir
Expand Down Expand Up @@ -139,23 +139,29 @@ abstract class KotlinAdapter @Inject constructor(
}
}

/** Register a single [DokkaSourceSetSpec] for [details] */
/** Register a single [DokkaSourceSetSpec] for [details]. */
private fun NamedDomainObjectContainer<DokkaSourceSetSpec>.register(
details: KotlinSourceSetDetails
) {
val kssPlatform = details.compilations.map { values: List<KotlinCompilationDetails> ->
values.map { it.kotlinPlatform }
.distinct()
.singleOrNull() ?: KotlinPlatform.Common
val all = values.map { it.kotlinPlatform }.distinct()
val r = all.singleOrNull()

println("[$dkaName] computed platform for ${details.name}: $r (from ${all})")

r ?: KotlinPlatform.Common
}

val kssClasspath = determineClasspath(details)

register(details.name) dss@{
suppress.set(!details.isPublishedSourceSet())
analysisPlatform.set(kssPlatform)
// suppress.convention(!details.isPublishedSourceSet())
// analysisPlatform.convention(kssPlatform)

sourceRoots.from(details.sourceDirectories)
classpath.from(kssClasspath)
analysisPlatform.set(kssPlatform)
dependentSourceSets.addAllLater(details.dependentSourceSetIds)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.gradle.api.tasks.PathSensitivity.RELATIVE
import org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceSetSpec.Companion.dokkaSourceSetSpecContainer
import org.jetbrains.dokka.gradle.internal.DokkaPluginParametersContainer
import org.jetbrains.dokka.gradle.internal.InternalDokkaGradlePluginApi
import org.jetbrains.dokka.gradle.internal.adding
Expand Down Expand Up @@ -82,11 +83,12 @@ constructor(
* Source sets used to generate a Dokka Module.
*
* The values are not used directly in this task, but they are required to be registered as a
* task input for up-to-date checks
* task input for up-to-date checks.
*/
@get:Nested
val dokkaSourceSets: NamedDomainObjectContainer<DokkaSourceSetSpec> =
extensions.adding("dokkaSourceSets", objects.domainObjectContainer())
// extensions.adding("dokkaSourceSets", objects.dokkaSourceSetSpecContainer())
extensions.adding("dokkaSourceSets", objects.domainObjectContainer())

/** Dokka Modules directories, containing the output, module descriptor, and module includes. */
@get:InputFiles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
*/
package org.jetbrains.dokka.gradle.engine.parameters

import org.gradle.api.Action
import org.gradle.api.DomainObjectSet
import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.*
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.ExtensionAware
Expand Down Expand Up @@ -445,4 +442,16 @@ constructor(
@Suppress("unused")
abstract val noJdkLink: Property<Boolean>
//endregion

companion object {
internal fun ObjectFactory.dokkaSourceSetSpecContainer(): NamedDomainObjectContainer<DokkaSourceSetSpec> =
domainObjectContainer { name ->
newInstance<DokkaSourceSetSpec>(name).apply {
// Manually added sourceSets should not be suppressed by default.
// dokkaSourceSets that are automatically added by DokkaKotlinAdapter will have a sensible value for 'suppress'.
//suppress.convention(false)
//analysisPlatform.convention(KotlinPlatform.DEFAULT)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* 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.engine.parameters

import io.kotest.core.spec.style.FunSpec
import io.kotest.inspectors.shouldForAll
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.shouldBe
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.gradle.testfixtures.ProjectBuilder
import org.jetbrains.dokka.gradle.DokkaExtension
import org.jetbrains.dokka.gradle.utils.configureEach_
import org.jetbrains.dokka.gradle.utils.create_
import org.jetbrains.dokka.gradle.utils.enableV2Plugin
import org.jetbrains.dokka.gradle.utils.shouldContainExactly
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension

class DokkaSourceSetSpecTest : FunSpec({

context("given a KMP project") {

test("expect Dokka registers KMP source sets") {
val project = createKmpProject()
val dokka = project.extensions.getByType<DokkaExtension>()
dokka.dokkaSourceSets.names shouldContainExactly listOf(
"commonMain",
"commonTest",
"jvmMain",
"jvmTest",
"linuxX64Main",
"linuxX64Test",
)
}

test("expect test source sets are suppressed by default") {

val project = createKmpProject()
val dokka = project.extensions.getByType<DokkaExtension>()
val mapDssNameToSuppress = dokka.dokkaSourceSets.associate { it.name to it.suppress.orNull }

mapDssNameToSuppress.shouldContainExactly(
"commonMain" to false,
"jvmMain" to false,
"linuxX64Main" to false,

"commonTest" to true,
"jvmTest" to true,
"linuxX64Test" to true,
)
}

context("DokkaSourceSetSpec.suppress") {

test("expect convention is 'false'") {
val dss = createDokkaSourceSet()
dss.suppress.orNull shouldBe false
}

listOf(
true,
false,
).forEach { newValue ->
test("can be set to '$newValue'") {
val project = createKmpProject()
val dokkaSourceSets = project.extensions.getByType<DokkaExtension>().dokkaSourceSets

dokkaSourceSets.configureEach_ {
suppress.set(newValue)
}

dokkaSourceSets.shouldForAll {
it.suppress.orNull shouldBe newValue
}
}
}
}

context("DokkaSourceSetSpec.analysisPlatform") {
test("expect convention is 'KotlinPlatform.DEFAULT'") {
val dss = createDokkaSourceSet()
dss.analysisPlatform.orNull shouldBe KotlinPlatform.DEFAULT
}

KotlinPlatform.values().forEach { newValue ->

test("can be set to '$newValue'") {
val project = createKmpProject()
val dokkaSourceSets = project.extensions.getByType<DokkaExtension>().dokkaSourceSets

dokkaSourceSets.configureEach_ {
analysisPlatform.set(newValue)
}

dokkaSourceSets.shouldForAll {
it.analysisPlatform.orNull shouldBe newValue
}
}

// test("can be set to '$newValue'") {
// val project = createProject()
// val dss = project.extensions.getByType<DokkaExtension>().dokkaSourceSets.getByName("commonMain")
// dss.analysisPlatform.set(newValue)
// dss.analysisPlatform.orNull shouldBe newValue
// }
}
}
}
})

private fun createKmpProject(): Project =
ProjectBuilder.builder().build()
.enableV2Plugin(v2MigrationHelpers = false)
.also {

// Apply KGP, because this will trigger Dokka's KotlinAdapter,
// which used to be bugged and would prevent overriding 'suppress' and 'analysisPlatform'.
// it.plugins.apply("org.jetbrains.kotlin.jvm")
it.plugins.apply("org.jetbrains.kotlin.multiplatform")

it.extensions.configure<KotlinMultiplatformExtension> {
jvm().apply {
// compilations.create_("dummyAndroid") {
// this
// }
}
linuxX64()
//androidTarget()
}

//it.plugins.apply("com.android.library")

it.plugins.apply("org.jetbrains.dokka")

// it.plugins.apply(KotlinAdapter::class)
}

private fun createDokkaSourceSet(
project: Project = createKmpProject(),
configure: DokkaSourceSetSpec.() -> Unit = {}
): DokkaSourceSetSpec {
val extension = project.extensions.getByType<DokkaExtension>()

return extension.dokkaSourceSets.create_("Test", configure)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* 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.inspectors.shouldForAll
import io.kotest.matchers.shouldBe
import org.jetbrains.dokka.gradle.engine.parameters.KotlinPlatform
import org.jetbrains.dokka.gradle.internal.DokkaConstants.DOKKA_VERSION
import org.jetbrains.dokka.gradle.utils.*
import kotlin.io.path.readLines

class DokkaSourceSetTest : FunSpec({

context("given an Android KMP project") {

val project = initAndroidKmpProject()

context("DokkaSourceSetSpec.analysisPlatform") {

KotlinPlatform.values().forEach { newValue ->

test("can be set to '$newValue'") {

project.runner
.addArguments(
":dokkaGenerate",
"-PanalysisPlatformOverride=$newValue",
)
.build {

val dokkaConfigJson =
project.file("build/tmp/dokkaGeneratePublicationHtml/dokka-configuration.json")

dokkaConfigJson.readLines()
.filter { it.contains("analysisPlatform") }
.shouldForAll { line ->
line shouldBe """
"analysisPlatform": "$newValue",
""".trimIndent()
}
}

// val project = createKmpProject()
// val dokkaSourceSets = project.extensions.getByType<DokkaExtension>().dokkaSourceSets
//
// dokkaSourceSets.configureEach_ {
// analysisPlatform.set(newValue)
// }
//
// dokkaSourceSets.shouldForAll {
// it.analysisPlatform.orNull shouldBe newValue
// }
}

// test("can be set to '$newValue'") {
// val project = createProject()
// val dss = project.extensions.getByType<DokkaExtension>().dokkaSourceSets.getByName("commonMain")
// dss.analysisPlatform.set(newValue)
// dss.analysisPlatform.orNull shouldBe newValue
// }
}
}
}
})


private fun initAndroidKmpProject(
config: GradleProjectTest.() -> Unit = {},
): GradleProjectTest {
return gradleKtsProjectTest("dokka-source-sets-test") {

settingsGradleKts = settingsGradleKts.replace("mavenCentral()", "mavenCentral(); google()")

buildGradleKts = """
|plugins {
| kotlin("multiplatform") version embeddedKotlinVersion
| id("com.android.library") version "8.7.2"
| id("org.jetbrains.dokka") version "$DOKKA_VERSION"
|}
|
|kotlin {
| jvmToolchain(17)
| jvm()
| linuxX64()
| androidTarget()
|}
|
|android {
| namespace = "x.y.z.demo"
|}
|
|dokka {
| dokkaSourceSets.configureEach {
| providers.gradleProperty("analysisPlatformOverride").orNull?.let { newValue ->
| analysisPlatform.set(newValue)
| }
| }
|}
|
""".trimMargin()

dir("src/commonMain/kotlin") {
createFile("Foo.kt", "class Foo")
}

config()
}
}
Loading