[Gradle] Don't print stacktraces in IDEA sync

IDEA sync is always launched with equivalent of `--stacktrace`, so
checking startParameter.showStacktrace is unreliable.

This commit instead mutes printing of stacktraces in sync unless the
internal property is specified. If users want stacktraces, they're
expected to launch Gradle task with `--stacktrace`.

In the extremely rare cases where the stacktrace is needed
*specifically* during IDE sync,
`kotlin.internal.diagnostics.showStacktrace=true` can be used

^KT-61172
This commit is contained in:
Dmitry Savvinov
2023-08-11 16:11:15 +02:00
committed by Space Team
parent f727934f6b
commit c359f684cd
3 changed files with 31 additions and 9 deletions
@@ -7,19 +7,28 @@ package org.jetbrains.kotlin.gradle.plugin.diagnostics
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.logging.configuration.ShowStacktrace import org.gradle.api.logging.configuration.ShowStacktrace
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
internal class ToolingDiagnosticRenderingOptions( internal class ToolingDiagnosticRenderingOptions(
val useParsableFormat: Boolean, val useParsableFormat: Boolean,
val suppressedWarningIds: List<String>, val suppressedWarningIds: List<String>,
val suppressedErrorIds: List<String>, val suppressedErrorIds: List<String>,
val showStacktrace: Boolean val showStacktrace: Boolean,
) { ) {
companion object { companion object {
fun forProject(project: Project): ToolingDiagnosticRenderingOptions { fun forProject(project: Project): ToolingDiagnosticRenderingOptions {
return with(project.kotlinPropertiesProvider) { return with(project.kotlinPropertiesProvider) {
val showStacktrace = internalDiagnosticsShowStacktrace val showStacktrace = when {
?: (project.gradle.startParameter.showStacktrace > ShowStacktrace.INTERNAL_EXCEPTIONS) // if the internal property is specified, it takes the highest priority
internalDiagnosticsShowStacktrace != null -> internalDiagnosticsShowStacktrace!!
// IDEA launches sync with `--stacktrace` option, but we don't want to
// spam stacktraces in build toolwindow
project.isInIdeaSync -> false
else -> project.gradle.startParameter.showStacktrace > ShowStacktrace.INTERNAL_EXCEPTIONS
}
ToolingDiagnosticRenderingOptions( ToolingDiagnosticRenderingOptions(
internalDiagnosticsUseParsableFormat, internalDiagnosticsUseParsableFormat,
@@ -183,7 +183,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest {
@Test @Test
fun `test WhenAndroidIsApplied - android is applied after the health check call`() { fun `test WhenAndroidIsApplied - android is applied after the health check call`() {
val project = ProjectBuilder.builder().build() val project = ProjectBuilder.builder().build()
project.gradle.registerConfigurationTimePropertiesAccessorForTests() project.gradle.registerMinimalVariantImplementationFactoriesForTests()
project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheckWhenAndroidIsApplied( project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheckWhenAndroidIsApplied(
FixedAndroidGradlePluginVersionProvider(null) FixedAndroidGradlePluginVersionProvider(null)
@@ -200,7 +200,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest {
@Test @Test
fun `test - WhenAndroidIsApplied - android is applied before the health check call`() { fun `test - WhenAndroidIsApplied - android is applied before the health check call`() {
val project = ProjectBuilder.builder().build() val project = ProjectBuilder.builder().build()
project.gradle.registerConfigurationTimePropertiesAccessorForTests() project.gradle.registerMinimalVariantImplementationFactoriesForTests()
addBuildEventsListenerRegistryMock(project) addBuildEventsListenerRegistryMock(project)
project.plugins.apply(LibraryPlugin::class.java) project.plugins.apply(LibraryPlugin::class.java)
@@ -214,7 +214,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest {
@Test @Test
fun `test - WhenAndroidIsApplied - called multiple times - still emits only a single message`() { fun `test - WhenAndroidIsApplied - called multiple times - still emits only a single message`() {
val project = ProjectBuilder.builder().build() val project = ProjectBuilder.builder().build()
project.gradle.registerConfigurationTimePropertiesAccessorForTests() project.gradle.registerMinimalVariantImplementationFactoriesForTests()
addBuildEventsListenerRegistryMock(project) addBuildEventsListenerRegistryMock(project)
project.plugins.apply(LibraryPlugin::class.java) project.plugins.apply(LibraryPlugin::class.java)
@@ -7,16 +7,29 @@ package org.jetbrains.kotlin.gradle.util
import org.gradle.api.invocation.Gradle import org.gradle.api.invocation.Gradle
import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactoriesConfigurator import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactoriesConfigurator
import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessor import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.DefaultConfigurationTimePropertiesAccessorVariantFactory import org.jetbrains.kotlin.gradle.plugin.internal.DefaultConfigurationTimePropertiesAccessorVariantFactory
import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetector
/** /**
* [ConfigurationTimePropertiesAccessor] default factory is automatically registered in [org.jetbrains.kotlin.gradle.plugin.DefaultKotlinBasePlugin.apply] * Configures some default factories that are usually automatically registered in
* This helper function is for simple tests that are testing granular logic without applying Kotlin plugin * [org.jetbrains.kotlin.gradle.plugin.DefaultKotlinBasePlugin.apply]
*
* This function can be used in some minimal tests that do not apply the full KGP plugin but still touch
* some parts of its code
*/ */
fun Gradle.registerConfigurationTimePropertiesAccessorForTests() { fun Gradle.registerMinimalVariantImplementationFactoriesForTests() {
VariantImplementationFactoriesConfigurator.get(gradle).putIfAbsent( VariantImplementationFactoriesConfigurator.get(gradle).putIfAbsent(
ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class, ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class,
DefaultConfigurationTimePropertiesAccessorVariantFactory() DefaultConfigurationTimePropertiesAccessorVariantFactory()
) )
// Diagnostics need to know if we're in IDEA sync in order to decide whether the stacktrace
// should be reported
VariantImplementationFactoriesConfigurator.get(gradle).putIfAbsent(
IdeaSyncDetector.IdeaSyncDetectorVariantFactory::class,
DefaultIdeaSyncDetectorVariantFactory()
)
} }