Skip to content

Commit

Permalink
Pin AGP 'debug.keystore' in the repo.
Browse files Browse the repository at this point in the history
This change adds shared 'debug.keystore' into the repository and
sets all the tests to use it.

Fixes issue when keystore was created by AGP 7+, but then consumed in
the test using lower versions of AGP.

^KT-45745 In Progress
  • Loading branch information
Tapchicoma authored and Space committed Dec 7, 2021
1 parent e705a36 commit 43df58a
Show file tree
Hide file tree
Showing 26 changed files with 323 additions and 8 deletions.
4 changes: 4 additions & 0 deletions libraries/tools/gradle/android-test-fixes/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## Description

Contains a plugin for Gradle integration tests applying different fixes
for test that are using Android Gradle plugin.
52 changes: 52 additions & 0 deletions libraries/tools/gradle/android-test-fixes/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import plugins.KotlinBuildPublishingPlugin

plugins {
id("java-gradle-plugin")
id("gradle-plugin-common-configuration")
id("com.gradle.plugin-publish")
}

repositories {
google()
}

dependencies {
compileOnly(gradleKotlinDsl())
compileOnly("com.android.tools.build:gradle:3.4.0")
compileOnly("com.android.tools.build:gradle-api:3.4.0")
compileOnly("com.android.tools.build:builder:3.4.0")
compileOnly("com.android.tools.build:builder-model:3.4.0")
}

configure<GradlePluginDevelopmentExtension> {
isAutomatedPublishing = false
}

gradlePlugin {
(plugins) {
create("android-test-fixes") {
id = "org.jetbrains.kotlin.test.fixes.android"
implementationClass = "org.jetbrains.kotlin.gradle.test.fixes.android.AndroidTestFixesPlugin"
}
}
}

pluginBundle {
(plugins) {
named("android-test-fixes") {
id = "org.jetbrains.kotlin.test.fixes.android"
displayName = "AndroidTestFixes"
}
}
}

publishPluginMarkers()

// Disable releasing for this plugin
// It is not intended to be released publicly
tasks.withType<PublishToMavenRepository>()
.configureEach {
if (name.endsWith("PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository")) {
enabled = false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2021 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.test.fixes.android

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.test.fixes.android.fixes.applyDebugKeystoreFix

class AndroidTestFixesPlugin : Plugin<Project> {
override fun apply(target: Project) {
val testFixesProperties = TestFixesProperties(target)
target.applyDebugKeystoreFix(testFixesProperties)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2021 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.test.fixes.android

import org.gradle.api.Project

internal class TestFixesProperties(
private val project: Project
) {
val androidDebugKeystoreLocation: String
get() = project.findProperty(ANDROID_DEBUG_KEYSTORE_LOCATION) as String? ?: throw IllegalArgumentException(
"$ANDROID_DEBUG_KEYSTORE_LOCATION property was not found in 'gradle.properties'."
)

companion object {
private const val PROP_PREFIX = "test.fixes."
private const val ANDROID_DEBUG_KEYSTORE_LOCATION = "${PROP_PREFIX}android.debugKeystore"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2021 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.test.fixes.android.fixes

import com.android.build.gradle.AppExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.jetbrains.kotlin.gradle.test.fixes.android.TestFixesProperties

/**
* AGP 7+ creates a keystore that is not compatible with lover versions of AGP,
* but could consume keystores created by them.
*
* With this fix 'debug.keystore' could be checked in into the repo and shared
* between test executions.
*/
internal fun Project.applyDebugKeystoreFix(
testFixesProperties: TestFixesProperties
) {
plugins.withId("com.android.application") {
extensions.configure<AppExtension> {
logger.info("Reconfiguring Android debug keystore")
buildTypes.named("debug") {
it.signingConfig?.storeFile = file(testFixesProperties.androidDebugKeystoreLocation)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ tasks.withType<Test> {

dependsOn(":kotlin-gradle-plugin:validatePlugins")
dependsOnKotlinGradlePluginInstall()
dependsOn(":gradle:android-test-fixes:install")

systemProperty("kotlinVersion", rootProject.extra["kotlinVersion"] as String)
systemProperty("runnerGradleVersion", gradle.gradleVersion)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.jdom.output.XMLOutputter
import org.jetbrains.kotlin.gradle.model.ModelContainer
import org.jetbrains.kotlin.gradle.model.ModelFetcherBuildAction
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
import org.jetbrains.kotlin.gradle.testbase.applyAndroidTestFixes
import org.jetbrains.kotlin.gradle.testbase.enableCacheRedirector
import org.jetbrains.kotlin.gradle.testbase.addPluginManagementToSettings
import org.jetbrains.kotlin.gradle.util.*
Expand Down Expand Up @@ -296,6 +297,7 @@ abstract class BaseGradleIT {
projectDir.toPath().apply {
addPluginManagementToSettings()
if (enableCacheRedirector) enableCacheRedirector()
applyAndroidTestFixes()
}
}
}
Expand Down Expand Up @@ -452,7 +454,7 @@ abstract class BaseGradleIT {
}

val options = defaultBuildOptions()
val arguments = mutableListOf("-Pkotlin_version=${options.kotlinVersion}")
val arguments = mutableListOf("-Pkotlin_version=${options.kotlinVersion}", "-Ptest_fixes_version=$KOTLIN_VERSION")
options.androidGradlePluginVersion?.let { arguments.add("-Pandroid_tools_version=$it") }
val env = createEnvironmentVariablesMap(options)
val wrapperVersion = chooseWrapperVersionOrFinishTest()
Expand Down Expand Up @@ -929,6 +931,7 @@ Finished executing task ':$taskName'|
}

add("-Pkotlin_version=" + options.kotlinVersion)
add("-Ptest_fixes_version=$KOTLIN_VERSION")
options.incremental?.let {
add("-Pkotlin.incremental=$it")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
""".trimIndent()
)

build("assembleDebug", "-Pagp_version=${TestVersions.AGP.AGP_42}")
build("assembleDebug", "-Pandroid_tools_version=${TestVersions.AGP.AGP_42}")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,7 @@ class NewMultiplatformIT : BaseGradleIT() {
.replace(": ", " = ")
.replace("def ", " val ")
.replace("new File(cacheRedirectorFile)", "File(cacheRedirectorFile)")
.replace("id \"org.jetbrains.kotlin.test.fixes.android\"", "id(\"org.jetbrains.kotlin.test.fixes.android\")")
}
renameTo(projectDir.resolve("app/build.gradle.kts"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ abstract class KGPBaseTest {
}
}

arguments.add("-Ptest_fixes_version=${TestVersions.Kotlin.CURRENT}")

return arguments.toList()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
@file:OptIn(kotlin.io.path.ExperimentalPathApi::class)
/*
* Copyright 2010-2021 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.testbase

import org.jetbrains.kotlin.gradle.util.modify
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.exists

internal fun Path.applyAndroidTestFixes() {
// Path relative to the current gradle module project dir
val keystoreFile = Paths.get("src/test/resources/common/debug.keystore")
assert(keystoreFile.exists()) {
"Common 'debug.keystore' file does not exists in ${keystoreFile.toAbsolutePath()} location!"
}
resolve("gradle.properties").append(
"""
|test.fixes.android.debugKeystore=${keystoreFile.toAbsolutePath().toString().normalizePath()}
|
""".trimMargin()
)

val pathFile = toFile()

pathFile.walkTopDown()
.filter { it.name == "build.gradle" || it.name == "build.gradle.kts" }
.forEach { file ->
when (file.name) {
"build.gradle" -> file.updateBuildGradle()
"build.gradle.kts" -> file.updateBuildGradleKts()
}
}
}

private fun File.updateBuildGradle() {
modify {
if (it.contains("plugins {")) {
"""
|${it.substringBefore("plugins {")}
|plugins {
| id "org.jetbrains.kotlin.test.fixes.android"
|${it.substringAfter("plugins {")}
""".trimMargin()
} else if (it.contains("apply plugin:")) {
it.modifyBuildScript().run {
"""
|${substringBefore("apply plugin:")}
|apply plugin: 'org.jetbrains.kotlin.test.fixes.android'
|apply plugin:${substringAfter("apply plugin:")}
""".trimMargin()
}
} else {
it.modifyBuildScript()
}
}
}

private fun String.modifyBuildScript(isKts: Boolean = false): String =
if (contains("buildscript {") &&
contains("classpath")
) {
val kotlinVersionStr = if (isKts) "${'$'}{property(\"test_fixes_version\")}" else "${'$'}test_fixes_version"
"""
|${substringBefore("classpath")}
|classpath("org.jetbrains.kotlin:android-test-fixes:$kotlinVersionStr")
|classpath${substringAfter("classpath")}
""".trimMargin()
} else {
this
}


private fun File.updateBuildGradleKts() {
modify {
if (it.contains("plugins {")) {
"""
|${it.substringBefore("plugins {")}
|plugins {
| id("org.jetbrains.kotlin.test.fixes.android")
|${it.substringAfter("plugins {")}
""".trimMargin()
} else if (it.contains("apply(plugin")) {
it.modifyBuildScript(true).run {
"""
|${substringBefore("apply(plugin")}
|apply(plugin = "org.jetbrains.kotlin.test.fixes.android")
|apply(plugin${substringAfter("apply(plugin")}
""".trimMargin()
}
} else {
it.modifyBuildScript(true)
}
}
}

private fun String.normalizePath() = replace("\\", "/")
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal val DEFAULT_GROOVY_SETTINGS_FILE =
id "org.jetbrains.kotlin.multiplatform" version "${'$'}kotlin_version"
id "org.jetbrains.kotlin.multiplatform.pm20" version "${'$'}kotlin_version"
id "org.jetbrains.kotlin.plugin.allopen" version "${'$'}kotlin_version"
id "org.jetbrains.kotlin.test.fixes.android" version "${'$'}kotlin_version"
id "org.jetbrains.kotlin.test.fixes.android" version "${'$'}test_fixes_version"
}
resolutionStrategy {
Expand Down Expand Up @@ -67,6 +67,7 @@ internal val DEFAULT_KOTLIN_SETTINGS_FILE =
val kotlin_version: String by settings
val android_tools_version: String by settings
val test_fixes_version: String by settings
plugins {
id("org.jetbrains.kotlin.jvm") version kotlin_version
id("org.jetbrains.kotlin.kapt") version kotlin_version
Expand All @@ -75,7 +76,7 @@ internal val DEFAULT_KOTLIN_SETTINGS_FILE =
id("org.jetbrains.kotlin.multiplatform") version kotlin_version
id("org.jetbrains.kotlin.multiplatform.pm20") version kotlin_version
id("org.jetbrains.kotlin.plugin.allopen") version kotlin_version
id("org.jetbrains.kotlin.test.fixes.android") version kotlin_version
id("org.jetbrains.kotlin.test.fixes.android") version test_fixes_version
}
resolutionStrategy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ internal fun Path.addPluginManagementToSettings() {
}
else -> settingsGradle.toFile().writeText(DEFAULT_GROOVY_SETTINGS_FILE)
}

if (Files.exists(resolve("buildSrc"))) {
resolve("buildSrc").addPluginManagementToSettings()
}
}

private fun TestProject.setupNonDefaultJdk(pathToJdk: File) {
Expand All @@ -290,6 +294,7 @@ internal fun Path.enableAndroidSdk() {
""".trimIndent()
)
acceptAndroidSdkLicenses(androidSdk)
applyAndroidTestFixes()
}

@OptIn(ExperimentalPathApi::class)
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}

plugins {
id "org.jetbrains.kotlin.jvm" version "$kotlin_version"
id "org.jetbrains.kotlin.test.fixes.android" version "$test_fixes_version"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
google()
gradlePluginPortal()
}

plugins {
id "org.jetbrains.kotlin.js" version "$kotlin_version"
id "org.jetbrains.kotlin.test.fixes.android" version "$test_fixes_version"
}
}

rootProject.name = "lib2"
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
pluginManagement {
repositories {
mavenCentral()
mavenLocal()
mavenCentral()
}

val test_fixes_version: String by settings
plugins {
id("org.jetbrains.kotlin.test.fixes.android") version test_fixes_version
}
}
Loading

0 comments on commit 43df58a

Please sign in to comment.