Skip to content

Commit

Permalink
Make Kotlin version per AGP
Browse files Browse the repository at this point in the history
This includes reading the kotlin version from version_mappings.txt
and some refactoring here and there to make reading it and using it
simpler.

Also added a 3rd AGP to test (8.2), and some work to make older
AGP and older Kotlin versions available as targets

Still need to figure out the target issue in the bazel macro.

Bug: N/A
Test: tested via the recipes themselves
Change-Id: Ibf9029291d54ebd66e1988dce9c95fdf6fab049f
  • Loading branch information
ducrohet committed Dec 21, 2023
1 parent 2d805ba commit 4e2a09f
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 270 deletions.
15 changes: 15 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>, from: String, to: String): List<String> {
return wrapPlaceholdersWithInlineValue(originalLines, from, to, "// ")
fun List<String>.wrapGradlePlaceholdersWithInlineValue(from: String, to: String): List<String> {
return wrapPlaceholdersWithInlineValue(from, to, "// ")
}

/**
Expand All @@ -63,56 +63,55 @@ fun wrapGradlePlaceholdersWithInlineValue(originalLines: List<String>, from: Str
*
* with lists of relevant repositories
*/
fun wrapGradlePlaceholdersWithList(originalLines: List<String>, from: String, to: List<String>): List<String> {
return wrapPlaceholdersWithList(originalLines, from, to, "// ")
fun List<String>.wrapGradlePlaceholdersWithList(from: String, to: List<String>): List<String> {
return wrapPlaceholdersWithList(from, to, "// ")
}

/**
* for build.gradle[.kts] , settings.gradle[.kts] ==> removes all working copy blocks
* and generated lines
*/
fun unwrapGradlePlaceholders(originalLines: List<String>): List<String> {
return unwrapPlaceholders(originalLines, "// ")
fun List<String>.unwrapGradlePlaceholders(): List<String> {
return unwrapPlaceholders("// ")
}

/**
* for gradle.wrapper.properties ==> wraps $GRADLE_LOCATION
*/
fun wrapGradleWrapperPlaceholders(originalLines: List<String>, from: String, to: String): List<String> {
return wrapPlaceholdersWithInlineValue(originalLines, from, to, "# ")
fun List<String>.wrapGradleWrapperPlaceholders(from: String, to: String): List<String> {
return wrapPlaceholdersWithInlineValue(from, to, "# ")
}

/**
* for libs.versions.toml ==> unwraps all converter placeholders
*/
fun unwrapVersionCatalogPlaceholders(originalLines: List<String>): List<String> {
return unwrapPlaceholders(originalLines, "# ")
fun List<String>.unwrapVersionCatalogPlaceholders(): List<String> {
return unwrapPlaceholders( "# ")
}

/**
* for libs.versions.toml ==> wraps all converter placeholders
*/
fun wrapVersionCatalogPlaceholders(originalLines: List<String>, from: String, to: String): List<String> {
return wrapPlaceholdersWithInlineValue(originalLines, from, to, "# ")
fun List<String>.wrapVersionCatalogPlaceholders(from: String, to: String): List<String> {
return wrapPlaceholdersWithInlineValue(from, to, "# ")
}

/**
* for libs.versions.toml ==> replace all converter placeholders
*/
fun replaceVersionCatalogPlaceholders(originalLines: List<String>, from: String, to: String): List<String> {
return replaceGradlePlaceholdersWithInlineValue(originalLines, from, to)
fun List<String>.replaceVersionCatalogPlaceholders(from: String, to: String): List<String> {
return replaceGradlePlaceholdersWithInlineValue(from, to)
}

/**
* replaces placeholders inside line
*/
fun replaceGradlePlaceholdersWithInlineValue(
originalLines: List<String>,
fun List<String>.replaceGradlePlaceholdersWithInlineValue(
from: String,
to: String,
): List<String> {
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)
Expand All @@ -130,17 +129,16 @@ fun replaceGradlePlaceholdersWithInlineValue(
/**
* replaces placeholders with a code line
*/
fun replacePlaceHolderWithLine(originalLines: List<String>, placeHolder: String, value: String): List<String> {
return replacePlaceHolderWithList(originalLines, placeHolder, if (value.isEmpty()) listOf() else listOf(value))
fun List<String>.replacePlaceHolderWithLine(placeHolder: String, value: String): List<String> {
return replacePlaceHolderWithList(placeHolder, if (value.isEmpty()) listOf() else listOf(value))
}

fun replacePlaceHolderWithList(
originalLines: List<String>,
fun List<String>.replacePlaceHolderWithList(
placeHolder: String,
values: List<String>,
): List<String> {
val result = buildList {
for (line in originalLines) {
for (line in this@replacePlaceHolderWithList) {
if (line.contains(placeHolder)) {
for (toLine in values) {
add(toLine)
Expand All @@ -157,14 +155,13 @@ fun replacePlaceHolderWithList(
/** wraps placeholders, and replaces the placeholder inline
*
*/
private fun wrapPlaceholdersWithInlineValue(
originalLines: List<String>,
private fun List<String>.wrapPlaceholdersWithInlineValue(
from: String,
to: String,
commentOut: String,
): List<String> {
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")
Expand All @@ -187,14 +184,13 @@ private fun wrapPlaceholdersWithInlineValue(
/** wraps placeholders, and replaces the placeholder with
* a list
*/
private fun wrapPlaceholdersWithList(
originalLines: List<String>,
private fun List<String>.wrapPlaceholdersWithList(
from: String,
to: List<String>,
commentOut: String,
): List<String> {
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")
Expand All @@ -214,15 +210,15 @@ private fun wrapPlaceholdersWithList(
/**
* unwraps both gradle and properties with commentOut
*/
private fun unwrapPlaceholders(originalLines: List<String>, commentOut: String): List<String> {
private fun List<String>.unwrapPlaceholders(commentOut: String): List<String> {
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))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ import kotlin.io.path.readLines

private const val VERSION_MAPPING = "version_mappings.txt"

private lateinit var agpToGradleMap: Map<String, String>
data class VersionInfo(
val agp: String,
val gradle: String,
val kotlin: String
)

private lateinit var agpToVersionsMap: Map<String, VersionInfo>
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)
}
}
}
Expand All @@ -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")
Expand All @@ -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
*/
Expand All @@ -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,
Expand Down Expand Up @@ -134,7 +137,7 @@ class RecipeConverter(
}

Mode.SOURCE -> {
SourceConverter()
SourceConverter(branchRoot)
}

Mode.RELEASE -> {
Expand Down Expand Up @@ -172,7 +175,7 @@ class RecipeConverter(
)

val success = if (converter.isConversionCompliant(recipe)) {
converter.setRecipe(recipe)
converter.recipe = recipe

Files.walkFileTree(source, object : SimpleFileVisitor<Path>() {
@Throws(IOException::class)
Expand Down Expand Up @@ -226,7 +229,7 @@ class RecipeConverter(
}
})

if (generateWrapper) {
if (generateWrapper && mode != Mode.SOURCE) {
converter.copyGradleFolder(destination)
}

Expand Down
Loading

0 comments on commit 4e2a09f

Please sign in to comment.