diff --git a/BUILD b/BUILD index 1f1aea6e..2a40f669 100644 --- a/BUILD +++ b/BUILD @@ -1,4 +1,6 @@ load("//tools/base/bazel:kotlin.bzl", "kotlin_library") +load("//tools/base/bazel:maven.bzl", "maven_repository") +load("//tools/base/build-system/integration-test:common-dependencies.bzl", "KGP_1_8_10", "KGP_1_9_20") load(":recipes.bzl", "recipe_test") kotlin_library( @@ -28,6 +30,19 @@ kotlin_library( ], ) +# for testing against older KGP +maven_repository( + name = "kotlin_1_9_20", + artifacts = KGP_1_9_20, + visibility = [":__subpackages__"], +) + +maven_repository( + name = "kotlin_1_8_10", + artifacts = KGP_1_8_10, + visibility = [":__subpackages__"], +) + recipe_test( name = "addBuildTypeUsingDslFinalize", ) diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/Converter.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/Converter.kt index b5863ea5..cabb1588 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/Converter.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/Converter.kt @@ -17,7 +17,9 @@ package com.google.android.gradle_recipe.converter.converters import com.google.android.gradle_recipe.converter.recipe.Recipe +import com.google.android.gradle_recipe.converter.recipe.toMajorMinor import java.nio.file.Path +import kotlin.io.path.isDirectory /** The position of the gradle-resources folder * to take the Gradle wrapper @@ -28,21 +30,21 @@ const val GRADLE_RESOURCES_FOLDER = "gradle-resources" * The objects are created and called from the RecipeConverter class, * using a Template Method pattern. */ -interface Converter { +abstract class Converter( + protected val branchRoot: Path +) { + + var recipe: Recipe? = null + /** Can converter convert this recipe */ - fun isConversionCompliant(recipe: Recipe): Boolean - - /** Sets the recipe to convert, before the conversion - */ - fun setRecipe(recipe: Recipe) { - } + abstract fun isConversionCompliant(recipe: Recipe): Boolean /** * Converts build.gradle */ - fun convertBuildGradle(source: Path, target: Path) + abstract fun convertBuildGradle(source: Path, target: Path) /** * Converts build.gradle.kts ==> same as build.gradle @@ -54,7 +56,7 @@ interface Converter { /** * Converts settings.gradle */ - fun convertSettingsGradle(source: Path, target: Path) + abstract fun convertSettingsGradle(source: Path, target: Path) /** * Converts settings.gradle.kts ==> same as settings.gradle @@ -66,11 +68,36 @@ interface Converter { /** * Converts the version catalog file */ - fun convertVersionCatalog(source: Path, target: Path) + abstract fun convertVersionCatalog(source: Path, target: Path) /** * Copies the gradle folder from the GRADLE_RESOURCES_FOLDER * to dest. */ - fun copyGradleFolder(dest: Path) + fun copyGradleFolder(dest: Path) { + val source = branchRoot.resolve(GRADLE_RESOURCES_FOLDER) + if (!source.isDirectory()) { + throw RuntimeException("Unable to find gradle resources at $source") + } + + dest.mkdirs() + + source.toFile().copyRecursively(target = dest.toFile()) + + processGradleWrapperProperties( + dest.resolve("gradle").resolve("wrapper").resolve("gradle-wrapper.properties") + ) + + } + + open fun processGradleWrapperProperties(file: Path) { } + + protected fun getMinAgp(): String = recipe?.minAgpVersion + ?: error("min Agp version is badly specified in the metadata") + + protected fun getVersionInfoFromAgp(agpVersion: String): VersionInfo { + val agp = agpVersion.toMajorMinor() + return getVersionsFromAgp(branchRoot, agp) + ?: throw RuntimeException("Unable to fetch VersionInfo for AGP $agp") + } } \ No newline at end of file diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ConverterUtils.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ConverterUtils.kt index f743261f..880ee416 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ConverterUtils.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ConverterUtils.kt @@ -52,8 +52,8 @@ fun Path.mkdirs(): Boolean { * id 'com.android.application' version $AGP_VERSION apply false * and replaces the $AGP_VERSION */ -fun wrapGradlePlaceholdersWithInlineValue(originalLines: List, from: String, to: String): List { - return wrapPlaceholdersWithInlineValue(originalLines, from, to, "// ") +fun List.wrapGradlePlaceholdersWithInlineValue(from: String, to: String): List { + return wrapPlaceholdersWithInlineValue(from, to, "// ") } /** @@ -63,56 +63,55 @@ fun wrapGradlePlaceholdersWithInlineValue(originalLines: List, from: Str * * with lists of relevant repositories */ -fun wrapGradlePlaceholdersWithList(originalLines: List, from: String, to: List): List { - return wrapPlaceholdersWithList(originalLines, from, to, "// ") +fun List.wrapGradlePlaceholdersWithList(from: String, to: List): List { + return wrapPlaceholdersWithList(from, to, "// ") } /** * for build.gradle[.kts] , settings.gradle[.kts] ==> removes all working copy blocks * and generated lines */ -fun unwrapGradlePlaceholders(originalLines: List): List { - return unwrapPlaceholders(originalLines, "// ") +fun List.unwrapGradlePlaceholders(): List { + return unwrapPlaceholders("// ") } /** * for gradle.wrapper.properties ==> wraps $GRADLE_LOCATION */ -fun wrapGradleWrapperPlaceholders(originalLines: List, from: String, to: String): List { - return wrapPlaceholdersWithInlineValue(originalLines, from, to, "# ") +fun List.wrapGradleWrapperPlaceholders(from: String, to: String): List { + return wrapPlaceholdersWithInlineValue(from, to, "# ") } /** * for libs.versions.toml ==> unwraps all converter placeholders */ -fun unwrapVersionCatalogPlaceholders(originalLines: List): List { - return unwrapPlaceholders(originalLines, "# ") +fun List.unwrapVersionCatalogPlaceholders(): List { + return unwrapPlaceholders( "# ") } /** * for libs.versions.toml ==> wraps all converter placeholders */ -fun wrapVersionCatalogPlaceholders(originalLines: List, from: String, to: String): List { - return wrapPlaceholdersWithInlineValue(originalLines, from, to, "# ") +fun List.wrapVersionCatalogPlaceholders(from: String, to: String): List { + return wrapPlaceholdersWithInlineValue(from, to, "# ") } /** * for libs.versions.toml ==> replace all converter placeholders */ -fun replaceVersionCatalogPlaceholders(originalLines: List, from: String, to: String): List { - return replaceGradlePlaceholdersWithInlineValue(originalLines, from, to) +fun List.replaceVersionCatalogPlaceholders(from: String, to: String): List { + return replaceGradlePlaceholdersWithInlineValue(from, to) } /** * replaces placeholders inside line */ -fun replaceGradlePlaceholdersWithInlineValue( - originalLines: List, +fun List.replaceGradlePlaceholdersWithInlineValue( from: String, to: String, ): List { val result = buildList { - for (line in originalLines) { + for (line: String in this@replaceGradlePlaceholdersWithInlineValue) { if (line.contains(from)) { if (to.isNotEmpty()) { val newLine: String = line.replace(from, to) @@ -130,17 +129,16 @@ fun replaceGradlePlaceholdersWithInlineValue( /** * replaces placeholders with a code line */ -fun replacePlaceHolderWithLine(originalLines: List, placeHolder: String, value: String): List { - return replacePlaceHolderWithList(originalLines, placeHolder, if (value.isEmpty()) listOf() else listOf(value)) +fun List.replacePlaceHolderWithLine(placeHolder: String, value: String): List { + return replacePlaceHolderWithList(placeHolder, if (value.isEmpty()) listOf() else listOf(value)) } -fun replacePlaceHolderWithList( - originalLines: List, +fun List.replacePlaceHolderWithList( placeHolder: String, values: List, ): List { val result = buildList { - for (line in originalLines) { + for (line in this@replacePlaceHolderWithList) { if (line.contains(placeHolder)) { for (toLine in values) { add(toLine) @@ -157,14 +155,13 @@ fun replacePlaceHolderWithList( /** wraps placeholders, and replaces the placeholder inline * */ -private fun wrapPlaceholdersWithInlineValue( - originalLines: List, +private fun List.wrapPlaceholdersWithInlineValue( from: String, to: String, commentOut: String, ): List { val result = buildList { - for (line in originalLines) { + for (line in this@wrapPlaceholdersWithInlineValue) { if (line.contains(from)) { add("$commentOut$START_WORKING_COPY_BLOCK") add("$commentOut$line") @@ -187,14 +184,13 @@ private fun wrapPlaceholdersWithInlineValue( /** wraps placeholders, and replaces the placeholder with * a list */ -private fun wrapPlaceholdersWithList( - originalLines: List, +private fun List.wrapPlaceholdersWithList( from: String, to: List, commentOut: String, ): List { val result = buildList { - for (line in originalLines) { + for (line in this@wrapPlaceholdersWithList) { if (line.contains(from)) { add("$commentOut$START_WORKING_COPY_BLOCK") add("$commentOut$line") @@ -214,15 +210,15 @@ private fun wrapPlaceholdersWithList( /** * unwraps both gradle and properties with commentOut */ -private fun unwrapPlaceholders(originalLines: List, commentOut: String): List { +private fun List.unwrapPlaceholders(commentOut: String): List { var insideWorkBlock = false val result = buildList { - for (line in originalLines) { + for (line in this@unwrapPlaceholders) { if (line == "$commentOut$START_WORKING_COPY_BLOCK") { insideWorkBlock = true } else if (insideWorkBlock) { if (line != "$commentOut$END_WORKING_COPY_BLOCK") { - if (line.startsWith("$commentOut")) { + if (line.startsWith(commentOut)) { add(line.substring(commentOut.length)) } diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/RecipeConverter.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/RecipeConverter.kt index 352dc7e5..ee7b43df 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/RecipeConverter.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/RecipeConverter.kt @@ -30,13 +30,19 @@ import kotlin.io.path.readLines private const val VERSION_MAPPING = "version_mappings.txt" -private lateinit var agpToGradleMap: Map +data class VersionInfo( + val agp: String, + val gradle: String, + val kotlin: String +) + +private lateinit var agpToVersionsMap: Map private lateinit var maxAgp: String -fun getGradleFromAgp(branchRoot: Path, agp: String): String? { +fun getVersionsFromAgp(branchRoot: Path, agp: String): VersionInfo? { initAgpToGradleMap(branchRoot) - return agpToGradleMap[agp].also { + return agpToVersionsMap[agp].also { if (it == null) { - println(agpToGradleMap.entries) + println(agpToVersionsMap.entries) } } } @@ -48,7 +54,7 @@ fun getMaxAgp(branchRoot: Path): String { @Synchronized private fun initAgpToGradleMap(branchRoot: Path) { - if (!::agpToGradleMap.isInitialized) { + if (!::agpToVersionsMap.isInitialized) { val file = branchRoot.resolve(VERSION_MAPPING) if (!file.isRegularFile()) { throw RuntimeException("Missing AGP version mapping file at $file") @@ -59,23 +65,20 @@ private fun initAgpToGradleMap(branchRoot: Path) { .asSequence() .filter { !it.startsWith("#") } - agpToGradleMap = lines + agpToVersionsMap = lines .map { - val pair = it.split(";") - pair[0].toMajorMinor() to pair[1] + val values = it.split(";") + values[0].toMajorMinor() to VersionInfo( + agp = values[0], + gradle = values[1], + kotlin = values[2] + ) }.toMap() maxAgp = lines.map { it.split(";")[0] }.max() } } - -/** - * Current supported Kotlin plugin, later we add a - * CLI argument to support more versions - */ -const val kotlinPluginVersion = "2.0.0-Beta1" - /** * The compile SDK version for recipes */ @@ -96,7 +99,7 @@ class RecipeConverter( repoLocation: String?, gradleVersion: String?, gradlePath: String?, - mode: Mode, + private val mode: Mode, private val overwrite: Boolean, branchRoot: Path, private val generateWrapper: Boolean = true, @@ -134,7 +137,7 @@ class RecipeConverter( } Mode.SOURCE -> { - SourceConverter() + SourceConverter(branchRoot) } Mode.RELEASE -> { @@ -172,7 +175,7 @@ class RecipeConverter( ) val success = if (converter.isConversionCompliant(recipe)) { - converter.setRecipe(recipe) + converter.recipe = recipe Files.walkFileTree(source, object : SimpleFileVisitor() { @Throws(IOException::class) @@ -226,7 +229,7 @@ class RecipeConverter( } }) - if (generateWrapper) { + if (generateWrapper && mode != Mode.SOURCE) { converter.copyGradleFolder(destination) } diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ReleaseConverter.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ReleaseConverter.kt index 3e7b14ae..2f1e6f78 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ReleaseConverter.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/ReleaseConverter.kt @@ -17,11 +17,8 @@ package com.google.android.gradle_recipe.converter.converters import com.google.android.gradle_recipe.converter.recipe.Recipe -import java.io.File -import java.io.IOException import java.nio.file.Files import java.nio.file.Path -import kotlin.io.path.isDirectory import kotlin.io.path.writeLines /** This mode is for a recipe that has no placeholders. @@ -32,8 +29,8 @@ class ReleaseConverter( gradleVersion: String?, repoLocation: String?, gradlePath: String?, - private val branchRoot: Path, -) : Converter { + branchRoot: Path, +) : Converter(branchRoot) { private var pathToGradle: String = "" private var pathToAgpRepo: String = "" @@ -61,101 +58,57 @@ class ReleaseConverter( } override fun convertBuildGradle(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - val agpVersionReplaced = replaceGradlePlaceholdersWithInlineValue( - originalLines, - "\$AGP_VERSION", - "\"$agpVersion\"" - ) - - val kotlinAndAgpVersionReplaced = - replaceGradlePlaceholdersWithInlineValue( - agpVersionReplaced, + val convertedText = Files.readAllLines(source) + .replaceGradlePlaceholdersWithInlineValue( + "\$AGP_VERSION", + "\"$agpVersion\"" + ).replaceGradlePlaceholdersWithInlineValue( "\$KOTLIN_VERSION", - "\"$kotlinPluginVersion\"" - ) - - val kotlinAndAgpCompileSdkVersionReplaced = - replaceGradlePlaceholdersWithInlineValue( - kotlinAndAgpVersionReplaced, + "\"${getVersionInfoFromAgp(agpVersion).kotlin}\"" + ).replaceGradlePlaceholdersWithInlineValue( "\$COMPILE_SDK", - "$compileSdkVersion" - ) - - val kotlinAndAgpCompileSdkMinimumSdkVersionReplaced = - replaceGradlePlaceholdersWithInlineValue( - kotlinAndAgpCompileSdkVersionReplaced, + compileSdkVersion + ).replaceGradlePlaceholdersWithInlineValue( "\$MINIMUM_SDK", - "$minimumSdkVersion" + minimumSdkVersion ) - target.writeLines(kotlinAndAgpCompileSdkMinimumSdkVersionReplaced, Charsets.UTF_8) + target.writeLines(convertedText, Charsets.UTF_8) } override fun convertSettingsGradle(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - - val agpRepoConverted = - replacePlaceHolderWithLine( - originalLines, + val convertedText = Files.readAllLines(source) + .replacePlaceHolderWithLine( "\$AGP_REPOSITORY", "$pathToAgpRepo" - ) - - val agpAndPluginRepoConverted = replacePlaceHolderWithList( - agpRepoConverted, "\$PLUGIN_REPOSITORIES", + ).replacePlaceHolderWithList( + "\$PLUGIN_REPOSITORIES", pluginRepo - ) - - val agpAndPluginAndDependencyRepoConverted = replacePlaceHolderWithList( - agpAndPluginRepoConverted, "\$DEPENDENCY_REPOSITORIES", + ).replacePlaceHolderWithList( + "\$DEPENDENCY_REPOSITORIES", dependencyRepo ) - target.writeLines(agpAndPluginAndDependencyRepoConverted, Charsets.UTF_8) + target.writeLines(convertedText, Charsets.UTF_8) } override fun convertVersionCatalog(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - - val agpVersionReplaced = replaceVersionCatalogPlaceholders( - originalLines, - "\$AGP_VERSION", - "\"$agpVersion\"" - ) - - val kotlinAndAgpVersionReplaced = - replaceGradlePlaceholdersWithInlineValue( - agpVersionReplaced, + val convertedText = Files.readAllLines(source) + .replaceVersionCatalogPlaceholders( + "\$AGP_VERSION", + "\"$agpVersion\"" + ).replaceGradlePlaceholdersWithInlineValue( "\$KOTLIN_VERSION", - "\"$kotlinPluginVersion\"" + "\"${getVersionInfoFromAgp(agpVersion).kotlin}\"" ) - target.writeLines(kotlinAndAgpVersionReplaced, Charsets.UTF_8) - } - - override fun copyGradleFolder(dest: Path) { - val source = branchRoot.resolve(GRADLE_RESOURCES_FOLDER) - if (!source.isDirectory()) { - throw RuntimeException("Unable to find gradle resources at $source") - } - - dest.mkdirs() - - source.toFile().copyRecursively(target = dest.toFile()) - val gradleWrapperPropertiesPath = - dest.resolve("gradle").resolve("wrapper").resolve("gradle-wrapper.properties") - if (Files.exists(gradleWrapperPropertiesPath)) { - convertGradleWrapper(gradleWrapperPropertiesPath, gradleWrapperPropertiesPath) - } + target.writeLines(convertedText, Charsets.UTF_8) } - private fun convertGradleWrapper(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - val resultLines = replaceGradlePlaceholdersWithInlineValue( - originalLines, "\$GRADLE_LOCATION", "$pathToGradle" - ) + override fun processGradleWrapperProperties(file: Path) { + val resultLines = + Files.readAllLines(file).replaceGradlePlaceholdersWithInlineValue("\$GRADLE_LOCATION", pathToGradle) - target.writeLines(resultLines, Charsets.UTF_8) + file.writeLines(resultLines, Charsets.UTF_8) } } \ No newline at end of file diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/SourceConverter.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/SourceConverter.kt index 7ccd8b8e..bd3d2e55 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/SourceConverter.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/SourceConverter.kt @@ -24,33 +24,20 @@ import kotlin.io.path.writeLines /** This mode has the placeholders ($AGP_VERSION etc') and * this is how we store the recipes in the dev branch */ -class SourceConverter : Converter { +class SourceConverter(branchRoot: Path) : Converter(branchRoot) { override fun isConversionCompliant(recipe: Recipe): Boolean { return true } override fun convertBuildGradle(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - val resultLines: List = unwrapGradlePlaceholders(originalLines) - - target.writeLines(resultLines, Charsets.UTF_8) + target.writeLines(Files.readAllLines(source).unwrapGradlePlaceholders(), Charsets.UTF_8) } override fun convertSettingsGradle(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - val resultLines: List = unwrapGradlePlaceholders(originalLines) - - target.writeLines(resultLines, Charsets.UTF_8) + target.writeLines(Files.readAllLines(source).unwrapGradlePlaceholders(), Charsets.UTF_8) } override fun convertVersionCatalog(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - val resultLines: List = unwrapVersionCatalogPlaceholders(originalLines) - - target.writeLines(resultLines, Charsets.UTF_8) - } - - override fun copyGradleFolder(dest: Path) { - + target.writeLines(Files.readAllLines(source).unwrapVersionCatalogPlaceholders(), Charsets.UTF_8) } } \ No newline at end of file diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/WorkingCopyConverter.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/WorkingCopyConverter.kt index 5dca79ff..05ea9d58 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/WorkingCopyConverter.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/converters/WorkingCopyConverter.kt @@ -17,145 +17,87 @@ package com.google.android.gradle_recipe.converter.converters import com.google.android.gradle_recipe.converter.recipe.Recipe -import com.google.android.gradle_recipe.converter.recipe.toMajorMinor import java.nio.file.Files import java.nio.file.Path -import kotlin.io.path.isDirectory import kotlin.io.path.writeLines /** * This is the working copy where the recipe has static values for $AGP_VERSION, etc... * but markers to revert them back to placeholders. */ -class WorkingCopyConverter( - private val branchRoot: Path, -) : Converter { - private var recipe: Recipe? = null +class WorkingCopyConverter(branchRoot: Path) : Converter(branchRoot) { + override fun isConversionCompliant(recipe: Recipe): Boolean { return true } - override fun setRecipe(recipe: Recipe) { - this.recipe = recipe - } - override fun convertBuildGradle(source: Path, target: Path) { val agpVersion = recipe?.minAgpVersion ?: error("min Agp version is badly specified in the metadata") - val originalLines = Files.readAllLines(source) - - val agpVersionWrapped = wrapGradlePlaceholdersWithInlineValue( - originalLines, "\$AGP_VERSION", "\"$agpVersion\"" - ) - val kotlinAndAgpVersionWrapped = - wrapGradlePlaceholdersWithInlineValue( - agpVersionWrapped, + val convertedText = Files.readAllLines(source) + .wrapGradlePlaceholdersWithInlineValue( + "\$AGP_VERSION", + "\"$agpVersion\"" + ).wrapGradlePlaceholdersWithInlineValue( "\$KOTLIN_VERSION", - "\"$kotlinPluginVersion\"" - ) - - val kotlinAndAgpCompileSdkVersionWrapped = - wrapGradlePlaceholdersWithInlineValue( - kotlinAndAgpVersionWrapped, + "\"${getVersionInfoFromAgp(agpVersion).kotlin}\"" + ).wrapGradlePlaceholdersWithInlineValue( "\$COMPILE_SDK", - "$compileSdkVersion" - ) - - val kotlinAndAgpCompileSdkMinimumSdkVersionWrapped = - wrapGradlePlaceholdersWithInlineValue( - kotlinAndAgpCompileSdkVersionWrapped, + compileSdkVersion + ).wrapGradlePlaceholdersWithInlineValue( "\$MINIMUM_SDK", - "$minimumSdkVersion" + minimumSdkVersion ) - target.writeLines( - kotlinAndAgpCompileSdkMinimumSdkVersionWrapped, - Charsets.UTF_8 - ) + target.writeLines(convertedText, Charsets.UTF_8) } override fun convertSettingsGradle(source: Path, target: Path) { - val originalLines = Files.readAllLines(source) - - val agpConverted = wrapGradlePlaceholdersWithInlineValue( - originalLines, - "\$AGP_REPOSITORY", - "" - ) - val agpAndPluginRepoConverted = wrapGradlePlaceholdersWithList( - agpConverted, "\$PLUGIN_REPOSITORIES", - listOf( - " gradlePluginPortal()", - " google()", - " mavenCentral()" - ) - ) - - val agpAndPluginRepoAndDepsRepoConverted = - wrapGradlePlaceholdersWithList( - agpAndPluginRepoConverted, "\$DEPENDENCY_REPOSITORIES", + val convertedText = Files.readAllLines(source) + .wrapGradlePlaceholdersWithInlineValue( + "\$AGP_REPOSITORY", + "" + ).wrapGradlePlaceholdersWithList( + "\$PLUGIN_REPOSITORIES", + listOf( + " gradlePluginPortal()", + " google()", + " mavenCentral()" + ) + ).wrapGradlePlaceholdersWithList( + "\$DEPENDENCY_REPOSITORIES", listOf(" google()", " mavenCentral()") ) - target.writeLines(agpAndPluginRepoAndDepsRepoConverted, Charsets.UTF_8) + target.writeLines(convertedText, Charsets.UTF_8) } override fun convertVersionCatalog(source: Path, target: Path) { - val agpVersion = recipe?.minAgpVersion - ?: error("min Agp version is badly specified in the metadata") - val originalLines = Files.readAllLines(source) - - val agpVersionWrapped = wrapVersionCatalogPlaceholders( - originalLines, - "\$AGP_VERSION", - "\"$agpVersion\"" - ) + val agpVersion = getMinAgp() - val kotlinAndAgpVersionWrapped = - wrapVersionCatalogPlaceholders( - agpVersionWrapped, + val convertedText = Files.readAllLines(source) + .wrapVersionCatalogPlaceholders( + "\$AGP_VERSION", + "\"$agpVersion\"" + ).wrapVersionCatalogPlaceholders( "\$KOTLIN_VERSION", - "\"$kotlinPluginVersion\"" + "\"${getVersionInfoFromAgp(agpVersion).kotlin}\"" ) - target.writeLines(kotlinAndAgpVersionWrapped, Charsets.UTF_8) + target.writeLines(convertedText, Charsets.UTF_8) } - override fun copyGradleFolder(dest: Path) { - val source = branchRoot.resolve(GRADLE_RESOURCES_FOLDER) - if (!source.isDirectory()) { - throw RuntimeException("Unable to find gradle resources at $source") - } - - dest.mkdirs() - - source.toFile().copyRecursively(target = dest.toFile()) - - convertGradleWrapper( - dest.resolve("gradle").resolve("wrapper") - .resolve("gradle-wrapper.properties"), - dest.resolve("gradle").resolve("wrapper") - .resolve("gradle-wrapper.properties") - ) - } - - private fun convertGradleWrapper(source: Path, target: Path) { + override fun processGradleWrapperProperties(file: Path) { // building the line // distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip - val agpVersion = recipe?.minAgpVersion - ?: error("min Agp version is badly specified in the metadata") - - val agpVersionMajorMinor = agpVersion.toMajorMinor() - val gradleVersion = getGradleFromAgp(branchRoot, agpVersionMajorMinor) - ?: error("Can't deduce the gradle version from the recipe metadata") - - val originalLines = Files.readAllLines(source) - val resultLines = wrapGradleWrapperPlaceholders( - originalLines, - "\$GRADLE_LOCATION", - "https\\://services.gradle.org/distributions/gradle-$gradleVersion-bin.zip" + file.writeLines( + Files.readAllLines(file) + .wrapGradleWrapperPlaceholders( + "\$GRADLE_LOCATION", + "https\\://services.gradle.org/distributions/gradle-${getVersionInfoFromAgp(getMinAgp()).gradle}-bin.zip" + ), + Charsets.UTF_8 ) - target.writeLines(resultLines, Charsets.UTF_8) } } \ No newline at end of file diff --git a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/validators/MinMaxCurrentAgpValidator.kt b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/validators/MinMaxCurrentAgpValidator.kt index 551d214c..efb962a2 100644 --- a/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/validators/MinMaxCurrentAgpValidator.kt +++ b/convert-tool/app/src/main/kotlin/com/google/android/gradle_recipe/converter/validators/MinMaxCurrentAgpValidator.kt @@ -18,8 +18,8 @@ package com.google.android.gradle_recipe.converter.validators import com.google.android.gradle_recipe.converter.converters.RecipeConverter import com.google.android.gradle_recipe.converter.converters.RecipeConverter.Mode -import com.google.android.gradle_recipe.converter.converters.getGradleFromAgp import com.google.android.gradle_recipe.converter.converters.getMaxAgp +import com.google.android.gradle_recipe.converter.converters.getVersionsFromAgp import com.google.android.gradle_recipe.converter.recipe.RecipeMetadataParser import com.google.android.gradle_recipe.converter.recipe.toMajorMinor import java.nio.file.Path @@ -48,7 +48,7 @@ class MinMaxCurrentAgpValidator( from: Path, agpVersion: String, ) { - val gradleVersion = getGradleFromAgp(branchRoot, agpVersion.toMajorMinor()) + val gradleVersion = getVersionsFromAgp(branchRoot, agpVersion.toMajorMinor())?.gradle ?: throw RuntimeException("Unable to find Gradle version for AGP version $agpVersion - Make sure it's present in version_mappings.txt") val recipeConverter = RecipeConverter( diff --git a/recipes.bzl b/recipes.bzl index 3b3750b2..6e27b53b 100644 --- a/recipes.bzl +++ b/recipes.bzl @@ -15,38 +15,62 @@ def recipe_test( """ # Test scenarios keyed by AGP version. Keep in chronological order, with "ToT" (tip of tree) last. + test_scenarios = { "8.1.0": { "name": name + "_8_1_0", - "gradle_path": "$(location //tools/base/build-system:gradle-distrib-8.1)", - "manifest_repos": ["//tools/base/build-system/previous-versions:8.1.0"], + "gradle_path": "$(location //tools/base/build-system:gradle-distrib-8.0)", + "manifest_repos": [ + "//tools/base/build-system/previous-versions:8.1.0", + ":kotlin_1_8_10", + ], "zip_repos": [], "data": [ "//prebuilts/studio/sdk:build-tools/33.0.1", "//tools/base/build-system:android_platform_for_tests", - "//tools/base/build-system:gradle-distrib-8.1", + "//tools/base/build-system:gradle-distrib-8.0", + "version_mappings.txt", + ], + }, + "8.2.0": { + "name": name + "_8_2_0", + "gradle_path": "$(location //tools/base/build-system:gradle-distrib-8.2)", + "manifest_repos": [ + "//tools/base/build-system/previous-versions:8.2.0", + ":kotlin_1_8_10", + ], + "zip_repos": [], + "data": [ + "//prebuilts/studio/sdk:build-tools/34.0.0", + "//tools/base/build-system:android_platform_for_tests", + "//tools/base/build-system:gradle-distrib-8.2", "version_mappings.txt", ], }, "ToT": { "name": name, "gradle_path": "$(location //tools/base/build-system:gradle-distrib)", - "manifest_repos": [], + "manifest_repos": [ + "//tools/base/build-system/integration-test:kotlin_gradle_plugin_prebuilts", + ":kotlin_1_9_20", + ], "zip_repos": ["//tools/base/build-system:android_gradle_plugin"], "data": [ "//prebuilts/studio/sdk:build-tools/33.0.1", "//prebuilts/studio/sdk:build-tools/latest", "//tools/base/build-system:android_platform_for_tests", "//tools/base/build-system:gradle-distrib", + "//tools/base/build-system:gradle-distrib-8.0", "//tools/base/build-system:gradle-distrib-8.1", + "//tools/base/build-system:gradle-distrib-8.2", "version_mappings.txt", + ":kotlin_1_8_10", ], }, } for agp_version in test_scenarios: manifest_repos = [ - "//tools/base/build-system/integration-test:kotlin_gradle_plugin_prebuilts", "//tools/base/build-system:android_gradle_plugin_runtime_dependencies", ] + test_scenarios[agp_version]["manifest_repos"] zip_repos = test_scenarios[agp_version]["zip_repos"] diff --git a/version_mappings.txt b/version_mappings.txt index 6cba1aec..e1b02bf1 100644 --- a/version_mappings.txt +++ b/version_mappings.txt @@ -1,6 +1,7 @@ -# mapping of AGP versions to Gradle Versions, separated by ';' -# Note: For AGP 8.1, minimum required Gradle version is 8.0, but because of -# https://github.com/gradle/gradle/issues/21436, we need to use Gradle 8.1 to be able to run against -# KGP 2.0+. -8.1.0;8.1 -8.2.0;8.2 +# mapping of AGP versions to Gradle and Kotlin Versions, separated by ';' +8.1.0;8.0;1.8.10 +8.2.0;8.2;1.8.10 +# wait until we have beta1 in the previous version +#8.3.0-beta01;8.4;1.9.20 +8.4.0-alpha01;8.4;1.9.20 +#8.4.0-alpha01;8.4;2.0.0-Beta1