[Gradle] Migrate warning about using pre-HMPP dependencies to new infra
This commit is contained in:
+4
-6
@@ -1,7 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.mpp
|
package org.jetbrains.kotlin.gradle.mpp
|
||||||
|
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.util.replaceText
|
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||||
import org.junit.jupiter.api.io.TempDir
|
import org.junit.jupiter.api.io.TempDir
|
||||||
@@ -90,13 +90,11 @@ class PreHmppDependenciesDeprecationIT : KGPBaseTest() {
|
|||||||
preBuildAction()
|
preBuildAction()
|
||||||
build(taskToCall) {
|
build(taskToCall) {
|
||||||
if (expectReportForDependency != null) {
|
if (expectReportForDependency != null) {
|
||||||
assertOutputContainsExactlyTimes(
|
output.assertHasDiagnostic(
|
||||||
DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE.replace("{0}", ".*$expectReportForDependency.*").toRegex()
|
KotlinToolingDiagnostics.PreHmppDependenciesUsedInBuild
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
assertOutputDoesNotContain(
|
output.assertNoDiagnostic(KotlinToolingDiagnostics.PreHmppDependenciesUsedInBuild)
|
||||||
DEPRECATED_PRE_HMPP_LIBRARIES_DETECTED_MESSAGE.replace("{0}", ".*").toRegex()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -104,7 +104,8 @@ internal interface KotlinGradleProjectChecker {
|
|||||||
NoKotlinTargetsDeclaredChecker,
|
NoKotlinTargetsDeclaredChecker,
|
||||||
DisabledCinteropCommonizationInHmppProjectChecker,
|
DisabledCinteropCommonizationInHmppProjectChecker,
|
||||||
DisabledNativeTargetsChecker,
|
DisabledNativeTargetsChecker,
|
||||||
JsEnvironmentChecker
|
JsEnvironmentChecker,
|
||||||
|
PreHmppDependenciesUsageChecker
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -312,4 +312,13 @@ object KotlinToolingDiagnostics {
|
|||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object PreHmppDependenciesUsedInBuild : ToolingDiagnosticFactory(WARNING) {
|
||||||
|
operator fun invoke(dependencyName: String) = build(
|
||||||
|
"""
|
||||||
|
The dependency '$dependencyName' was published in the legacy mode. Support for such dependencies will be removed in the future.
|
||||||
|
See https://kotl.in/0b5kn8 for details.
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.diagnostics.checkers
|
||||||
|
|
||||||
|
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.dsl.multiplatformExtensionOrNull
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.await
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
|
||||||
|
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 java.util.*
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
internal object PreHmppDependenciesUsageChecker : KotlinGradleProjectChecker {
|
||||||
|
override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) {
|
||||||
|
KotlinPluginLifecycle.Stage.ReadyForExecution.await()
|
||||||
|
|
||||||
|
if (!project.isKotlinGranularMetadataEnabled || project.kotlinPropertiesProvider.allowLegacyMppDependencies) return
|
||||||
|
|
||||||
|
val metadataTarget = project.multiplatformExtensionOrNull?.awaitTargets()
|
||||||
|
?.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 { resolvableDependencies ->
|
||||||
|
val resolvedDependencies = resolvableDependencies.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)) {
|
||||||
|
collector.reportOncePerGradleBuild(
|
||||||
|
project,
|
||||||
|
KotlinToolingDiagnostics.PreHmppDependenciesUsedInBuild(dependencyId.displayName),
|
||||||
|
key = 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
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-4
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
|||||||
internal fun runDeprecationDiagnostics(project: Project) {
|
internal fun runDeprecationDiagnostics(project: Project) {
|
||||||
checkAndReportDeprecatedMppProperties(project)
|
checkAndReportDeprecatedMppProperties(project)
|
||||||
handleHierarchicalStructureFlagsMigration(project)
|
handleHierarchicalStructureFlagsMigration(project)
|
||||||
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
}
|
||||||
checkAndReportPreHmppDependenciesUsage(project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declared properties have to be captured during plugin application phase before the HMPP migration util sets them.
|
* Declared properties have to be captured during plugin application phase before the HMPP migration util sets them.
|
||||||
|
|||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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