[Build, IGS] Add a consent details document link
Related to KTI-1223
This commit is contained in:
committed by
Space Team
parent
063e7258ee
commit
04fcffa664
+19
-2
@@ -11,8 +11,12 @@ import java.io.PrintStream
|
||||
private val isInIdeaSync
|
||||
get() = System.getProperty("idea.sync.active").toBoolean()
|
||||
|
||||
private const val linkPlaceholder = "%LINK%"
|
||||
|
||||
internal const val USER_CONSENT_MARKER = "# This line indicates that you have chosen to enable automatic configuration of properties."
|
||||
|
||||
internal const val USER_CONSENT_MARKER_WITH_DETAILS_LINK = "$USER_CONSENT_MARKER Details: $linkPlaceholder"
|
||||
|
||||
internal const val USER_REFUSAL_MARKER =
|
||||
"# This line indicates that you have chosen to disable automatic configuration of properties. If you want to enable it, remove this line."
|
||||
|
||||
@@ -24,8 +28,12 @@ internal val USER_CONSENT_REQUEST = """
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
internal 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 fun String.formatWithLink(link: String) = replace(linkPlaceholder, link)
|
||||
|
||||
internal class ConsentManager(
|
||||
private val modifier: LocalPropertiesModifier,
|
||||
private val input: BufferedReader = System.`in`.bufferedReader(),
|
||||
@@ -38,14 +46,23 @@ internal class ConsentManager(
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun askForConsent(): Boolean {
|
||||
fun askForConsent(consentDetailsLink: String? = null): Boolean {
|
||||
output.println(USER_CONSENT_REQUEST)
|
||||
if (consentDetailsLink != null) {
|
||||
output.println(USER_CONSENT_DETAILS_LINK_TEMPLATE.formatWithLink(consentDetailsLink))
|
||||
}
|
||||
while (true) {
|
||||
output.println(PROMPT_REQUEST)
|
||||
when (input.readLine()) {
|
||||
"yes" -> {
|
||||
output.println("You've given the consent")
|
||||
modifier.putLine(USER_CONSENT_MARKER)
|
||||
modifier.putLine(
|
||||
if (consentDetailsLink != null) {
|
||||
USER_CONSENT_MARKER_WITH_DETAILS_LINK.formatWithLink(consentDetailsLink)
|
||||
} else {
|
||||
USER_CONSENT_MARKER
|
||||
}
|
||||
)
|
||||
return true
|
||||
}
|
||||
"no" -> {
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
||||
private val log = Logging.getLogger(javaClass)
|
||||
|
||||
override fun apply(target: Settings) {
|
||||
// `kotlin-build-gradle-plugin` is not used here intentionally, as it caches properties, we don't want to cache them before modificaation
|
||||
// `kotlin-build-gradle-plugin` is not used here intentionally, as it caches properties, we don't want to cache them before modification
|
||||
val shouldApplyPlugin = target.providers.gradleProperty(PLUGIN_SWITCH_PROPERTY).orElse("false").map(String::toBoolean)
|
||||
if (!shouldApplyPlugin.get()) return // the plugin is disabled, do nothing at all
|
||||
val isTeamCityBuild = (target as? ExtensionAware)?.extra?.has("teamcity") == true || System.getenv("TEAMCITY_VERSION") != null
|
||||
@@ -43,7 +43,7 @@ abstract class InternalGradleSetupSettingsPlugin : Plugin<Settings> {
|
||||
val setupFile = connection.getInputStream().buffered().use {
|
||||
parseSetupFile(it)
|
||||
}
|
||||
if (initialDecision == null && !consentManager.askForConsent()) {
|
||||
if (initialDecision == null && !consentManager.askForConsent(setupFile.consentDetailsLink)) {
|
||||
log.debug("Skipping automatic local.properties configuration as the consent wasn't given")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.build
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonNamingStrategy
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStream
|
||||
import java.io.InputStreamReader
|
||||
@@ -16,9 +18,14 @@ import kotlin.streams.asSequence
|
||||
@Serializable
|
||||
internal data class SetupFile(
|
||||
val properties: Map<String, String>,
|
||||
val consentDetailsLink: String? = null,
|
||||
)
|
||||
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
namingStrategy = JsonNamingStrategy.SnakeCase
|
||||
}
|
||||
|
||||
// can't use decodeFromStream: https://github.com/Kotlin/kotlinx.serialization/issues/2218
|
||||
internal fun parseSetupFile(inputStream: InputStream): SetupFile =
|
||||
|
||||
+20
-2
@@ -52,24 +52,42 @@ class ConsentManagerTest {
|
||||
@Test
|
||||
fun testConsentRequestAgree() = testUserDecision("yes", true, USER_CONSENT_MARKER)
|
||||
|
||||
@Test
|
||||
fun testConsentRequestAgreeWithDetailsLink() = testUserDecision(
|
||||
"yes",
|
||||
true,
|
||||
USER_CONSENT_MARKER_WITH_DETAILS_LINK.formatWithLink("https://example.org"),
|
||||
consentDetailsLink = "https://example.org"
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testConsentRequestRefusal() = testUserDecision("no", false, USER_REFUSAL_MARKER)
|
||||
|
||||
@Test
|
||||
fun testConsentRequestAnswerAfterBadInput() = testUserDecision("\nasdasd\nno", false, USER_REFUSAL_MARKER, 3)
|
||||
|
||||
private fun testUserDecision(prompt: String, expectedDecision: Boolean, expectedLine: String, promptCount: Int = 1) {
|
||||
private fun testUserDecision(
|
||||
prompt: String,
|
||||
expectedDecision: Boolean,
|
||||
expectedLine: String,
|
||||
promptCount: Int = 1,
|
||||
consentDetailsLink: String? = null,
|
||||
) {
|
||||
StringInputStream(prompt).bufferedReader().use { input ->
|
||||
val outputStream = ByteArrayOutputStream(255)
|
||||
PrintStream(outputStream).use { printStream ->
|
||||
val consentManager = ConsentManager(modifier, input, printStream)
|
||||
val userDecision = consentManager.askForConsent()
|
||||
val userDecision = consentManager.askForConsent(consentDetailsLink)
|
||||
assertEquals(expectedDecision, userDecision)
|
||||
val content = Files.readAllLines(localPropertiesFile)
|
||||
assertTrue(content.contains(expectedLine))
|
||||
val output = String(outputStream.toByteArray())
|
||||
assertContainsExactTimes(output, USER_CONSENT_REQUEST, 1)
|
||||
assertContainsExactTimes(output, PROMPT_REQUEST, promptCount)
|
||||
|
||||
if (consentDetailsLink != null) {
|
||||
assertContainsExactTimes(output, USER_CONSENT_DETAILS_LINK_TEMPLATE.formatWithLink(consentDetailsLink), 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -29,6 +29,7 @@ class SetupFileParseTest {
|
||||
parseSetupFile(it)
|
||||
}
|
||||
assertSampleSetupFileIsParsedCorrectly(setupFile)
|
||||
assertNull(setupFile.consentDetailsLink)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -37,5 +38,15 @@ class SetupFileParseTest {
|
||||
parseSetupFile(it)
|
||||
}
|
||||
assertSampleSetupFileIsParsedCorrectly(setupFile)
|
||||
assertNull(setupFile.consentDetailsLink)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testParsingWithConsentDetailsLink() {
|
||||
val setupFile = openPropertiesJsonStream("properties-with-consent-details").use {
|
||||
parseSetupFile(it)
|
||||
}
|
||||
assertSampleSetupFileIsParsedCorrectly(setupFile)
|
||||
assertEquals(setupFile.consentDetailsLink, "https://example.org")
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"properties": {
|
||||
"newProperty1": "someValue",
|
||||
"newProperty2": "someOtherValue",
|
||||
"alreadySetProperty": "newValue"
|
||||
},
|
||||
"consent_details_link": "https://example.org"
|
||||
}
|
||||
Reference in New Issue
Block a user