[mpp] Warn about using pre-HMPP dependencies
^KT-58086 Fixed
This commit is contained in:
committed by
Space Team
parent
a98c2c178f
commit
da073c9cc3
+105
@@ -0,0 +1,105 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.mpp
|
||||||
|
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
|
@MppGradlePluginTests
|
||||||
|
class PreHmppDependenciesDeprecationIT : KGPBaseTest() {
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun testSimpleReport(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
|
||||||
|
publishLibrary("preHmppLibrary", gradleVersion, tempDir)
|
||||||
|
checkDiagnostics(gradleVersion, "simpleReport", tempDir, expectReportForDependency = "preHmppLibrary")
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun testTransitiveDependencyUpgradesVersion(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
|
||||||
|
// 0.1
|
||||||
|
publishLibrary("preHmppLibrary", gradleVersion, tempDir)
|
||||||
|
|
||||||
|
// 0.2 -- still pre-HMPP
|
||||||
|
publishLibrary("preHmppLibrary", gradleVersion, tempDir) {
|
||||||
|
buildGradleKts.replaceText("0.1", "0.2")
|
||||||
|
}
|
||||||
|
publishLibrary("hmppLibraryWithPreHmppInDependencies", gradleVersion, tempDir) {
|
||||||
|
buildGradleKts.replaceText("0.1", "0.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that even though the version of requested dependency is different from resolved, the report warning is still emitted
|
||||||
|
checkDiagnostics(gradleVersion, "transitiveDependencyUpgradesVersion", tempDir, expectReportForDependency = "preHmppLibrary")
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun noReportFromTransitiveDependencies(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
|
||||||
|
publishLibrary("preHmppLibrary", gradleVersion, tempDir)
|
||||||
|
publishLibrary("hmppLibraryWithPreHmppInDependencies", gradleVersion, tempDir)
|
||||||
|
checkDiagnostics(gradleVersion, "reportFromTransitiveDependencies", tempDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun noReportWhenSuppressed(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
|
||||||
|
publishLibrary("preHmppLibrary", gradleVersion, tempDir)
|
||||||
|
checkDiagnostics(gradleVersion, "simpleReport", tempDir) {
|
||||||
|
gradleProperties.writeText("kotlin.mpp.allow.legacy.dependencies=true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun testNoWarningsOnPopularDependencies(gradleVersion: GradleVersion) {
|
||||||
|
checkDiagnostics(gradleVersion, "noWarningsOnPopularDependencies")
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun testNoWarningsOnProjectDependencies(gradleVersion: GradleVersion) {
|
||||||
|
checkDiagnostics(gradleVersion, "noWarningsOnProjectDependencies", taskToCall = ":consumer:dependencies")
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun testNoWarningsInPlatformSpecificSourceSets(gradleVersion: GradleVersion) {
|
||||||
|
checkDiagnostics(gradleVersion, "noWarningsInPlatformSpecificSourceSets")
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun testNoWarningsInPreHmppProjects(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
|
||||||
|
publishLibrary("preHmppLibrary", gradleVersion, tempDir)
|
||||||
|
checkDiagnostics(gradleVersion, "simpleReport", tempDir) {
|
||||||
|
gradleProperties.writeText("kotlin.internal.mpp.hierarchicalStructureByDefault=false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkDiagnostics(
|
||||||
|
gradleVersion: GradleVersion,
|
||||||
|
projectName: String,
|
||||||
|
tempDir: Path? = null,
|
||||||
|
taskToCall: String = "dependencies",
|
||||||
|
expectReportForDependency: String? = null,
|
||||||
|
preBuildAction: TestProject.() -> Unit = {}
|
||||||
|
) {
|
||||||
|
project("preHmppDependenciesDeprecation/$projectName", gradleVersion, localRepoDir = tempDir?.resolve("repo")) {
|
||||||
|
preBuildAction()
|
||||||
|
build(taskToCall) {
|
||||||
|
if (expectReportForDependency != null) {
|
||||||
|
assertOutputContainsExactlyTimes(
|
||||||
|
DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE.replace("{0}", ".*$expectReportForDependency.*").toRegex()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
assertOutputDoesNotContain(
|
||||||
|
DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE.replace("{0}", ".*").toRegex()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun publishLibrary(name: String, gradleVersion: GradleVersion, tempDir: Path, prePublishAction: TestProject.() -> Unit = {}) {
|
||||||
|
project("preHmppDependenciesDeprecation/$name", gradleVersion, localRepoDir = tempDir.resolve("repo")) {
|
||||||
|
prePublishAction()
|
||||||
|
build("publish")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-2
@@ -135,7 +135,14 @@ fun BuildResult.assertOutputContainsExactlyTimes(
|
|||||||
expected: String,
|
expected: String,
|
||||||
expectedCount: Int = 1
|
expectedCount: Int = 1
|
||||||
) {
|
) {
|
||||||
val occurrenceCount = expected.toRegex(RegexOption.LITERAL).findAll(output).count()
|
assertOutputContainsExactlyTimes(expected.toRegex(RegexOption.LITERAL), expectedCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BuildResult.assertOutputContainsExactlyTimes(
|
||||||
|
expected: Regex,
|
||||||
|
expectedCount: Int = 1
|
||||||
|
) {
|
||||||
|
val occurrenceCount = expected.findAll(output).count()
|
||||||
assert(occurrenceCount == expectedCount) {
|
assert(occurrenceCount == expectedCount) {
|
||||||
printBuildOutput()
|
printBuildOutput()
|
||||||
|
|
||||||
@@ -228,4 +235,4 @@ fun findParameterInOutput(name: String, output: String): String? =
|
|||||||
output.lineSequence().mapNotNull { line ->
|
output.lineSequence().mapNotNull { line ->
|
||||||
val (key, value) = line.split('=', limit = 2).takeIf { it.size == 2 } ?: return@mapNotNull null
|
val (key, value) = line.split('=', limit = 2).takeIf { it.size == 2 } ?: return@mapNotNull null
|
||||||
if (key.endsWith(name)) value else null
|
if (key.endsWith(name)) value else null
|
||||||
}.firstOrNull()
|
}.firstOrNull()
|
||||||
|
|||||||
+8
-2
@@ -447,6 +447,8 @@ internal fun Path.addDefaultBuildFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun Path.addPluginManagementToSettings() {
|
internal fun Path.addPluginManagementToSettings() {
|
||||||
|
val buildGradle = resolve("build.gradle")
|
||||||
|
val buildGradleKts = resolve("build.gradle.kts")
|
||||||
val settingsGradle = resolve("settings.gradle")
|
val settingsGradle = resolve("settings.gradle")
|
||||||
val settingsGradleKts = resolve("settings.gradle.kts")
|
val settingsGradleKts = resolve("settings.gradle.kts")
|
||||||
when {
|
when {
|
||||||
@@ -474,7 +476,11 @@ internal fun Path.addPluginManagementToSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> settingsGradle.toFile().writeText(DEFAULT_GROOVY_SETTINGS_FILE)
|
Files.exists(buildGradle) -> settingsGradle.toFile().writeText(DEFAULT_GROOVY_SETTINGS_FILE)
|
||||||
|
|
||||||
|
Files.exists(buildGradleKts) -> settingsGradleKts.toFile().writeText(DEFAULT_KOTLIN_SETTINGS_FILE)
|
||||||
|
|
||||||
|
else -> error("No build-file or settings file found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Files.exists(resolve("buildSrc"))) {
|
if (Files.exists(resolve("buildSrc"))) {
|
||||||
@@ -653,4 +659,4 @@ internal fun TestProject.enableStableConfigurationCachePreview() {
|
|||||||
|enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
|
|enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
id("maven-publish")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "org.jetbrains.kotlin.tests"
|
||||||
|
version = "0.1"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
val commonMain by getting {
|
||||||
|
dependencies {
|
||||||
|
api("org.jetbrains.kotlin.tests:preHmppLibrary:0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
kotlin.internal.mpp.hierarchicalStructureByDefault=true
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
id("maven-publish")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "org.jetbrains.kotlin.tests"
|
||||||
|
version = "0.1"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
listOf("jvmMain", "jsMain", "linuxX64Main").forEach {
|
||||||
|
sourceSets.getByName(it).dependencies {
|
||||||
|
implementation("org.jetbrains.kotlin.tests:preHmppLibrary:0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
sourceSets.getByName("commonMain").dependencies {
|
||||||
|
implementation(kotlin("stdlib"))
|
||||||
|
implementation(kotlin("kotlin-test"))
|
||||||
|
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") apply false
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
val commonMain by getting {
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":producer"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
kotlin.internal.mpp.hierarchicalStructureByDefault=true
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
kotlin.internal.mpp.hierarchicalStructureByDefault=false
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
linuxX64()
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
include("consumer", "producer")
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
id("maven-publish")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "org.jetbrains.kotlin.tests"
|
||||||
|
version = "0.1"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
linuxX64()
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
kotlin.internal.mpp.hierarchicalStructureByDefault=false
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
sourceSets.getByName("commonMain").dependencies {
|
||||||
|
implementation("org.jetbrains.kotlin.tests:hmppLibraryWithPreHmppInDependencies:0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
sourceSets.getByName("commonMain").dependencies {
|
||||||
|
implementation("org.jetbrains.kotlin.tests:preHmppLibrary:0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
maven("<localRepo>")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
|
||||||
|
sourceSets.getByName("commonMain").dependencies {
|
||||||
|
implementation("org.jetbrains.kotlin.tests:hmppLibraryWithPreHmppInDependencies:0.2")
|
||||||
|
implementation("org.jetbrains.kotlin.tests:preHmppLibrary:0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_JS_KARMA_BROWSERS
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_JS_KARMA_BROWSERS
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ALLOW_LEGACY_DEPENDENCIES
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION
|
||||||
@@ -517,6 +518,9 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
|||||||
val runKotlinCompilerViaBuildToolsApi: Boolean
|
val runKotlinCompilerViaBuildToolsApi: Boolean
|
||||||
get() = booleanProperty(KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API) ?: false
|
get() = booleanProperty(KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API) ?: false
|
||||||
|
|
||||||
|
val allowLegacyMppDependencies: Boolean
|
||||||
|
get() = booleanProperty(KOTLIN_MPP_ALLOW_LEGACY_DEPENDENCIES) ?: false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a comma-separated list of browsers to use when running karma tests for [target]
|
* Retrieves a comma-separated list of browsers to use when running karma tests for [target]
|
||||||
* @see KOTLIN_JS_KARMA_BROWSERS
|
* @see KOTLIN_JS_KARMA_BROWSERS
|
||||||
@@ -604,6 +608,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
|||||||
const val KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING = "kotlin.compiler.suppressExperimentalICOptimizationsWarning"
|
const val KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING = "kotlin.compiler.suppressExperimentalICOptimizationsWarning"
|
||||||
const val KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS = "kotlin.internal.mpp.createDefaultMultiplatformPublications"
|
const val KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS = "kotlin.internal.mpp.createDefaultMultiplatformPublications"
|
||||||
const val KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API = "kotlin.compiler.runViaBuildToolsApi"
|
const val KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API = "kotlin.compiler.runViaBuildToolsApi"
|
||||||
|
const val KOTLIN_MPP_ALLOW_LEGACY_DEPENDENCIES = "kotlin.mpp.allow.legacy.dependencies"
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+1
@@ -31,6 +31,7 @@ internal fun runDeprecationDiagnostics(project: Project) {
|
|||||||
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
||||||
checkAndReportDeprecatedNativeTargets(project)
|
checkAndReportDeprecatedNativeTargets(project)
|
||||||
reportTargetsWithNonUniqueConsumableConfigurations(project)
|
reportTargetsWithNonUniqueConsumableConfigurations(project)
|
||||||
|
checkAndReportPreHmppDependenciesUsage(project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.component.ComponentIdentifier
|
||||||
|
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
|
||||||
|
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||||
|
import org.gradle.api.attributes.Attribute
|
||||||
|
import org.gradle.api.attributes.Usage
|
||||||
|
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
internal fun checkAndReportPreHmppDependenciesUsage(
|
||||||
|
project: Project,
|
||||||
|
reportWarning: (Project, String) -> Unit = DEFAULT_DIAGNOSTIC_REPORTER,
|
||||||
|
) {
|
||||||
|
if (!project.isKotlinGranularMetadataEnabled || project.kotlinPropertiesProvider.allowLegacyMppDependencies) return
|
||||||
|
|
||||||
|
val metadataTarget = project.multiplatformExtensionOrNull?.targets?.matching { it is KotlinMetadataTarget }?.singleOrNull()
|
||||||
|
?: return
|
||||||
|
|
||||||
|
// Note that we do not inspect dependencies of compilations, because adding dependencies into compilation is esoteric enough on its own,
|
||||||
|
// and x2 esoteric for KotlinMetadataTarget
|
||||||
|
val sourceSetsInMetadataCompilations = metadataTarget.compilations.flatMapTo(mutableSetOf()) { it.allKotlinSourceSets }
|
||||||
|
val configurationsToInspect = sourceSetsInMetadataCompilations.map { it.internal.resolvableMetadataConfiguration }
|
||||||
|
|
||||||
|
// Resolution of configurations can happen concurrently, so need to use thread-safe primitives
|
||||||
|
val reportedDependencies: MutableSet<ComponentIdentifier> = Collections.newSetFromMap(ConcurrentHashMap())
|
||||||
|
val processedDependencies: MutableSet<ComponentIdentifier> = Collections.newSetFromMap(ConcurrentHashMap())
|
||||||
|
|
||||||
|
for (configuration in configurationsToInspect) {
|
||||||
|
configuration.incoming.afterResolve { configuration ->
|
||||||
|
val resolvedDependencies = configuration.resolutionResult.root.dependencies
|
||||||
|
.filterIsInstance<ResolvedDependencyResult>()
|
||||||
|
// We don't want to report deprecation on transitive dependencies. Gradle will add them into list of 'dependencies',
|
||||||
|
// but will mark them as 'isConstraint'
|
||||||
|
.filter { it.selected.id is ModuleComponentIdentifier && !it.isConstraint }
|
||||||
|
|
||||||
|
for (dependency in resolvedDependencies) {
|
||||||
|
val dependencyId = dependency.selected.id as ModuleComponentIdentifier
|
||||||
|
if (!processedDependencies.add(dependencyId)) continue
|
||||||
|
|
||||||
|
if (isPreHmppDependency(dependency) && reportedDependencies.add(dependencyId)) {
|
||||||
|
reportWarning(
|
||||||
|
project,
|
||||||
|
DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE.replace("{0}", dependencyId.displayName)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPreHmppDependency(dependency: ResolvedDependencyResult): Boolean {
|
||||||
|
val attributes = dependency.resolvedVariant.attributes
|
||||||
|
val kotlinPlatformAttribute = attributes.getAttribute(Attribute.of(KotlinPlatformType.attribute.name, String::class.java))
|
||||||
|
?: return false
|
||||||
|
val usageAttribute = attributes.getAttribute(Attribute.of(Usage.USAGE_ATTRIBUTE.name, String::class.java)) ?: return false
|
||||||
|
|
||||||
|
return kotlinPlatformAttribute == KotlinPlatformType.common.name && usageAttribute != KotlinUsages.KOTLIN_METADATA
|
||||||
|
}
|
||||||
|
|
||||||
|
private val DEFAULT_DIAGNOSTIC_REPORTER = { project: Project, message: String ->
|
||||||
|
SingleWarningPerBuild.show(project, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@InternalKotlinGradlePluginApi
|
||||||
|
val DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE =
|
||||||
|
"w: The dependency {0} was published in the legacy mode. Support for such dependencies will be removed in the future. " +
|
||||||
|
"See https://kotl.in/0b5kn8 for details."
|
||||||
Reference in New Issue
Block a user