From b559131ddda8efea3394a0ea641460c4189769db Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Fri, 4 Aug 2023 18:57:00 +0200 Subject: Make the compatibility metadata variant check more specific (#3103) --- .../dokka/gradle/kotlin/kotlinClasspathUtils.kt | 13 --------- .../dokka/gradle/kotlin/kotlinCompilationUtils.kt | 34 +++++++++++++++++++++- 2 files changed, 33 insertions(+), 14 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin/org/jetbrains') diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt index b534dcc4..1d1d18fc 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt @@ -5,25 +5,12 @@ import org.gradle.api.file.FileCollection import org.jetbrains.dokka.gradle.isAndroidTarget import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -val Project.isHMPPEnabled - // [KotlinCommonCompilation.isKlibCompilation] is internal, so we use this - get() = (this.findProperty("kotlin.mpp.enableGranularSourceSetsMetadata") as? String)?.toBoolean() ?: false - internal fun Project.classpathOf(sourceSet: KotlinSourceSet): FileCollection { val compilations = compilationsOf(sourceSet) return if (compilations.isNotEmpty()) { compilations - /** - * If the project has enabled Compatibility Metadata Variant (produces legacy variant), - * we don't touch it due to some dependant library - * might be published without Compatibility Metadata Variant. - * Dokka needs only HMPP variant - * Ignore [org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation] for `commonMain` sourceSet with name `main` - */ - .filterNot { compilation -> isHMPPEnabled && compilation is KotlinCommonCompilation && compilation.name == "main" } .map { compilation -> compilation.compileClasspathOf(project = this) } .reduce { acc, fileCollection -> acc + fileCollection } } else { diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinCompilationUtils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinCompilationUtils.kt index 1d06e608..ab781432 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinCompilationUtils.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinCompilationUtils.kt @@ -6,15 +6,47 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation internal typealias KotlinCompilation = org.jetbrains.kotlin.gradle.plugin.KotlinCompilation internal fun Project.compilationsOf(sourceSet: KotlinSourceSet): List { //KT-45412 Make sure .kotlinSourceSets and .allKotlinSourceSets include the default source set - return allCompilationsOf(sourceSet).filter { compilation -> + val compilations = allCompilationsOf(sourceSet).filter { compilation -> sourceSet in compilation.kotlinSourceSets || sourceSet == compilation.defaultSourceSet } + + val hasAdditionalCommonCompatibilityMetadataVariant = compilations.size >= 2 + && this.isHmppEnabled() + && compilations.any { it is KotlinCommonCompilation && it.compilationName == "main" } + && compilations.any { it is KotlinCommonCompilation && it.compilationName == "commonMain" } + + return if (hasAdditionalCommonCompatibilityMetadataVariant) { + // If the project has `kotlin.mpp.enableCompatibilityMetadataVariant` set to `true` + // and it produces a legacy variant for common, we filter it out because one of the dependencies + // might be published without it, and it would lead to the following error: + // + // > Execution failed for task ':project:dokkaHtmlPartial'. + // > Could not resolve all files for configuration ':project:metadataCompileClasspath'. + // > Could not resolve com.example.dependency:0.1.0. + // > The consumer was configured to find a usage of 'kotlin-api' of a library, preferably optimized for + // non-jvm, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common'. However we + // cannot choose between the following variants of com.example.dependency:0.1.0: + // + // This can be reproduced consistently on Ktor of version 2.3.2 + compilations.filterNot { it is KotlinCommonCompilation && it.compilationName == "main" } + } else { + compilations + } +} + +private fun Project.isHmppEnabled(): Boolean { + // [KotlinCommonCompilation.isKlibCompilation] is internal, so we use this property instead. + // The property name might seem misleading, but it's set by KGP if HMPP is enabled: + // https://github.com/JetBrains/kotlin/blob/1.9.0/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/internal/hierarchicalStructureMigrationHandling.kt#L33 + return (this.findProperty("kotlin.mpp.enableGranularSourceSetsMetadata") as? String)?.toBoolean() + ?: false } internal fun Project.allCompilationsOf( -- cgit