[IGS] Add a non-interactive way to make a consent decision for IDEA builds
When running builds from IDEA, especially tests, the interactive consent request is barely noticeable. Also, some of the tools windows are non-interactive terminals. Thus, we detect the IDEA builds and fail fast to make it noticeable. ^KTI-1443 Fixed
This commit is contained in:
committed by
Space Team
parent
ab5699f106
commit
2bd77d5cdc
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.build
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
|
||||
class CannotRequestConsentWithinIdeException(consentDetailsLink: String?) : GradleException(
|
||||
"""
|
||||
|$USER_CONSENT_REQUEST
|
||||
|The consent cannot be requested in interactive mode when running from IDE.
|
||||
|Please either invoke Gradle from the command line or add -P$CONSENT_DECISION_GRADLE_PROPERTY=(true,false) to the run parameters in order to make a decision
|
||||
|${if (consentDetailsLink != null) USER_CONSENT_DETAILS_LINK_TEMPLATE.formatWithLink(consentDetailsLink) else ""}
|
||||
""".trimMargin()
|
||||
)
|
||||
+29
-20
@@ -25,10 +25,9 @@ internal val USER_CONSENT_REQUEST = """
|
||||
! ATTENTION REQUIRED !
|
||||
Most probably you're a developer from the Kotlin team. We are asking for your consent for automatic configuration of local.properties file
|
||||
for providing some optimizations and collecting additional debug information.
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
internal val USER_CONSENT_DETAILS_LINK_TEMPLATE = "You can read more details here: $linkPlaceholder"
|
||||
internal const val USER_CONSENT_DETAILS_LINK_TEMPLATE = "You can read more details here: $linkPlaceholder"
|
||||
|
||||
internal const val PROMPT_REQUEST = "Do you agree with this? Please answer with 'yes' or 'no': "
|
||||
|
||||
@@ -53,30 +52,40 @@ internal class ConsentManager(
|
||||
}
|
||||
}
|
||||
|
||||
fun askForConsent(consentDetailsLink: String? = null): Boolean {
|
||||
private fun printConsentRequest(consentDetailsLink: String? = null) {
|
||||
output.println()
|
||||
output.println(USER_CONSENT_REQUEST)
|
||||
if (consentDetailsLink != null) {
|
||||
output.println(USER_CONSENT_DETAILS_LINK_TEMPLATE.formatWithLink(consentDetailsLink))
|
||||
}
|
||||
output.println()
|
||||
}
|
||||
|
||||
fun applyConsentDecision(consentGiven: Boolean, consentDetailsLink: String? = null): Boolean {
|
||||
if (consentGiven) {
|
||||
output.println("You've given the consent for the automatic configuration of local.properties")
|
||||
modifier.putLine(
|
||||
if (consentDetailsLink != null) {
|
||||
USER_CONSENT_MARKER_WITH_DETAILS_LINK.formatWithLink(consentDetailsLink)
|
||||
} else {
|
||||
USER_CONSENT_MARKER
|
||||
}
|
||||
)
|
||||
} else {
|
||||
output.println("You've refused to give the consent for the automatic configuration of local.properties")
|
||||
modifier.putLine(USER_REFUSAL_MARKER)
|
||||
}
|
||||
return consentGiven
|
||||
}
|
||||
|
||||
fun askForConsent(consentDetailsLink: String? = null): Boolean {
|
||||
printConsentRequest(consentDetailsLink)
|
||||
repeat(MAX_REQUEST_ATTEMPTS) {
|
||||
output.println(PROMPT_REQUEST)
|
||||
when (input.readLine()) {
|
||||
"yes" -> {
|
||||
output.println("You've given the consent")
|
||||
modifier.putLine(
|
||||
if (consentDetailsLink != null) {
|
||||
USER_CONSENT_MARKER_WITH_DETAILS_LINK.formatWithLink(consentDetailsLink)
|
||||
} else {
|
||||
USER_CONSENT_MARKER
|
||||
}
|
||||
)
|
||||
return true
|
||||
}
|
||||
"no" -> {
|
||||
output.println("You've refused to give the consent")
|
||||
modifier.putLine(USER_REFUSAL_MARKER)
|
||||
return false
|
||||
}
|
||||
return when (input.readLine()) {
|
||||
"yes" -> applyConsentDecision(true, consentDetailsLink)
|
||||
"no" -> applyConsentDecision(false, consentDetailsLink)
|
||||
else -> return@repeat
|
||||
}
|
||||
}
|
||||
// we didn't receive an answer, let's ask next time
|
||||
|
||||
+24
-5
@@ -18,7 +18,12 @@ private const val DOMAIN_NAME = "kotlin-build-properties.labs.jb.gg"
|
||||
private const val SETUP_JSON_URL = "https://$DOMAIN_NAME/setup.json"
|
||||
|
||||
private const val PLUGIN_SWITCH_PROPERTY = "kotlin.build.internal.gradle.setup"
|
||||
private const val CONSENT_GRADLE_PROPERTY = "kotlin.build.internal.gradle.setup.consent"
|
||||
private const val GLOBAL_CONSENT_GRADLE_PROPERTY = "kotlin.build.internal.gradle.setup.consent"
|
||||
|
||||
private val isInIdea
|
||||
get() = System.getProperty("idea.active").toBoolean()
|
||||
|
||||
internal const val CONSENT_DECISION_GRADLE_PROPERTY = "kotlin.build.internal.gradle.setup.consent.give"
|
||||
|
||||
abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
||||
private val log = Logging.getLogger(javaClass)
|
||||
@@ -34,7 +39,8 @@ abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
||||
}
|
||||
try {
|
||||
val modifier = LocalPropertiesModifier(target.rootDir.resolve("local.properties"))
|
||||
val consentManager = ConsentManager(modifier, target.providers.gradleProperty(CONSENT_GRADLE_PROPERTY).orNull?.toBoolean())
|
||||
val consentManager =
|
||||
ConsentManager(modifier, target.providers.gradleProperty(GLOBAL_CONSENT_GRADLE_PROPERTY).orNull?.toBoolean())
|
||||
val initialDecision = consentManager.getUserDecision()
|
||||
if (initialDecision == false) {
|
||||
log.debug("Skipping automatic local.properties configuration as you've opted out")
|
||||
@@ -44,12 +50,25 @@ abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
||||
val setupFile = connection.getInputStream().buffered().use {
|
||||
parseSetupFile(it)
|
||||
}
|
||||
if (initialDecision == null && !consentManager.askForConsent(setupFile.consentDetailsLink)) {
|
||||
log.debug("Skipping automatic local.properties configuration as the consent wasn't given")
|
||||
return
|
||||
if (initialDecision == null) {
|
||||
val nonInteractiveDecision = target.providers.gradleProperty(CONSENT_DECISION_GRADLE_PROPERTY).map { it.toBoolean() }
|
||||
if (isInIdea && !nonInteractiveDecision.isPresent) {
|
||||
throw CannotRequestConsentWithinIdeException(setupFile.consentDetailsLink)
|
||||
}
|
||||
val consentReceived = if (nonInteractiveDecision.isPresent) {
|
||||
consentManager.applyConsentDecision(nonInteractiveDecision.get(), setupFile.consentDetailsLink)
|
||||
} else {
|
||||
consentManager.askForConsent(setupFile.consentDetailsLink)
|
||||
}
|
||||
if (!consentReceived) {
|
||||
log.debug("Skipping automatic local.properties configuration as the consent wasn't given")
|
||||
return
|
||||
}
|
||||
}
|
||||
modifier.applySetup(setupFile)
|
||||
log.info("Automatic local.properties setup has been applied.")
|
||||
} catch (e: CannotRequestConsentWithinIdeException) {
|
||||
throw e
|
||||
} catch (e: UnknownHostException) {
|
||||
log.debug("Cannot connect to the internal properties storage", e)
|
||||
} catch (e: SocketTimeoutException) {
|
||||
|
||||
Reference in New Issue
Block a user