[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()
|
||||||
|
)
|
||||||
+22
-13
@@ -25,10 +25,9 @@ internal val USER_CONSENT_REQUEST = """
|
|||||||
! ATTENTION REQUIRED !
|
! 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
|
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.
|
for providing some optimizations and collecting additional debug information.
|
||||||
|
|
||||||
""".trimIndent()
|
""".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': "
|
internal const val PROMPT_REQUEST = "Do you agree with this? Please answer with 'yes' or 'no': "
|
||||||
|
|
||||||
@@ -53,16 +52,18 @@ internal class ConsentManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun askForConsent(consentDetailsLink: String? = null): Boolean {
|
private fun printConsentRequest(consentDetailsLink: String? = null) {
|
||||||
|
output.println()
|
||||||
output.println(USER_CONSENT_REQUEST)
|
output.println(USER_CONSENT_REQUEST)
|
||||||
if (consentDetailsLink != null) {
|
if (consentDetailsLink != null) {
|
||||||
output.println(USER_CONSENT_DETAILS_LINK_TEMPLATE.formatWithLink(consentDetailsLink))
|
output.println(USER_CONSENT_DETAILS_LINK_TEMPLATE.formatWithLink(consentDetailsLink))
|
||||||
}
|
}
|
||||||
repeat(MAX_REQUEST_ATTEMPTS) {
|
output.println()
|
||||||
output.println(PROMPT_REQUEST)
|
}
|
||||||
when (input.readLine()) {
|
|
||||||
"yes" -> {
|
fun applyConsentDecision(consentGiven: Boolean, consentDetailsLink: String? = null): Boolean {
|
||||||
output.println("You've given the consent")
|
if (consentGiven) {
|
||||||
|
output.println("You've given the consent for the automatic configuration of local.properties")
|
||||||
modifier.putLine(
|
modifier.putLine(
|
||||||
if (consentDetailsLink != null) {
|
if (consentDetailsLink != null) {
|
||||||
USER_CONSENT_MARKER_WITH_DETAILS_LINK.formatWithLink(consentDetailsLink)
|
USER_CONSENT_MARKER_WITH_DETAILS_LINK.formatWithLink(consentDetailsLink)
|
||||||
@@ -70,13 +71,21 @@ internal class ConsentManager(
|
|||||||
USER_CONSENT_MARKER
|
USER_CONSENT_MARKER
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return true
|
} else {
|
||||||
}
|
output.println("You've refused to give the consent for the automatic configuration of local.properties")
|
||||||
"no" -> {
|
|
||||||
output.println("You've refused to give the consent")
|
|
||||||
modifier.putLine(USER_REFUSAL_MARKER)
|
modifier.putLine(USER_REFUSAL_MARKER)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
return consentGiven
|
||||||
|
}
|
||||||
|
|
||||||
|
fun askForConsent(consentDetailsLink: String? = null): Boolean {
|
||||||
|
printConsentRequest(consentDetailsLink)
|
||||||
|
repeat(MAX_REQUEST_ATTEMPTS) {
|
||||||
|
output.println(PROMPT_REQUEST)
|
||||||
|
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
|
// we didn't receive an answer, let's ask next time
|
||||||
|
|||||||
+22
-3
@@ -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 SETUP_JSON_URL = "https://$DOMAIN_NAME/setup.json"
|
||||||
|
|
||||||
private const val PLUGIN_SWITCH_PROPERTY = "kotlin.build.internal.gradle.setup"
|
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> {
|
abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
||||||
private val log = Logging.getLogger(javaClass)
|
private val log = Logging.getLogger(javaClass)
|
||||||
@@ -34,7 +39,8 @@ abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val modifier = LocalPropertiesModifier(target.rootDir.resolve("local.properties"))
|
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()
|
val initialDecision = consentManager.getUserDecision()
|
||||||
if (initialDecision == false) {
|
if (initialDecision == false) {
|
||||||
log.debug("Skipping automatic local.properties configuration as you've opted out")
|
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 {
|
val setupFile = connection.getInputStream().buffered().use {
|
||||||
parseSetupFile(it)
|
parseSetupFile(it)
|
||||||
}
|
}
|
||||||
if (initialDecision == null && !consentManager.askForConsent(setupFile.consentDetailsLink)) {
|
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")
|
log.debug("Skipping automatic local.properties configuration as the consent wasn't given")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
modifier.applySetup(setupFile)
|
modifier.applySetup(setupFile)
|
||||||
log.info("Automatic local.properties setup has been applied.")
|
log.info("Automatic local.properties setup has been applied.")
|
||||||
|
} catch (e: CannotRequestConsentWithinIdeException) {
|
||||||
|
throw e
|
||||||
} catch (e: UnknownHostException) {
|
} catch (e: UnknownHostException) {
|
||||||
log.debug("Cannot connect to the internal properties storage", e)
|
log.debug("Cannot connect to the internal properties storage", e)
|
||||||
} catch (e: SocketTimeoutException) {
|
} catch (e: SocketTimeoutException) {
|
||||||
|
|||||||
Reference in New Issue
Block a user