Aperture: Use generateBp plugin from maven repo
We share this code within our apps, extract it into a common package and
decommonize whatever might be app-specific.
Change-Id: I403a0d8ce4c78b9a6ed2001e20611926c608ae06
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c5afd92..83b504c 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -3,15 +3,29 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import groovy.util.Node
-import groovy.util.NodeList
-import groovy.xml.XmlParser
+import org.lineageos.generatebp.GenerateBpPlugin
+import org.lineageos.generatebp.GenerateBpPluginExtension
+import org.lineageos.generatebp.models.Module
plugins {
id("com.android.application")
id("kotlin-android")
}
+apply {
+ plugin<GenerateBpPlugin>()
+}
+
+buildscript {
+ repositories {
+ maven("https://raw.githubusercontent.com/lineage-next/gradle-generatebp/v1.1/.m2")
+ }
+
+ dependencies {
+ classpath("org.lineageos:gradle-generatebp:+")
+ }
+}
+
android {
compileSdk = 33
@@ -97,275 +111,21 @@
implementation("io.coil-kt:coil-video:2.2.2")
}
-tasks.register("generateBp") {
- val project = project(":app")
- val configuration = project.configurations["debugRuntimeClasspath"]
-
- val libsBase = File("${project.projectDir.absolutePath}/libs")
- libsBase.deleteRecursively()
-
- val moduleString = { it: ModuleVersionIdentifier -> "${it.group}:${it.name}:${it.version}" }
- val modulePath =
- { it: ModuleVersionIdentifier -> "${it.group.replace(".", "/")}/${it.name}/${it.version}" }
-
- val spaces = { it: Int ->
- var ret = ""
- for (i in it downTo 1) {
- ret += ' '
- }
- ret
- }
-
- val moduleName = { it: Any ->
- when (it) {
- is ModuleVersionIdentifier -> {
- "${rootProject.name}_${it.group}_${it.name}"
- }
- is String -> {
- if (it.contains(":")) {
- val (group, artifactId) = it.split(":")
- "${rootProject.name}_${group}_${artifactId}"
- } else {
- "${rootProject.name}_${it}"
- }
- }
- else -> {
- throw Exception("Invalid `it` type")
- }
- }
- }
-
- val moduleNameAosp = { it: String ->
- when (it) {
- "androidx.constraintlayout:constraintlayout" -> "androidx-constraintlayout_constraintlayout"
- "com.google.auto.value:auto-value-annotations" -> "auto_value_annotations"
- "com.google.guava:guava" -> "guava"
- "com.google.guava:listenablefuture" -> "guava"
- "org.jetbrains.kotlin:kotlin-stdlib" -> "kotlin-stdlib"
- "org.jetbrains.kotlin:kotlin-stdlib-jdk8" -> "kotlin-stdlib-jdk8"
- "org.jetbrains.kotlinx:kotlinx-coroutines-android" -> "kotlinx-coroutines-android"
- else -> it.replace(":", "_")
- }
- }
-
- val isAvailableInAosp = { group: String, artifactId: String ->
+configure<GenerateBpPluginExtension> {
+ targetSdk.set(android.defaultConfig.targetSdk!!)
+ availableInAOSP.set { module: Module ->
when {
- group.startsWith("androidx") -> {
+ module.group.startsWith("androidx") -> {
// We provide our own androidx.{camera,media3} & lifecycle-common
- !group.startsWith("androidx.camera") &&
- !group.startsWith("androidx.media3") &&
- artifactId != "lifecycle-common"
+ !module.group.startsWith("androidx.camera") &&
+ !module.group.startsWith("androidx.media3") &&
+ module.name != "lifecycle-common"
}
- group.startsWith("org.jetbrains") -> true
- group == "com.google.auto.value" -> true
- group == "com.google.guava" -> true
- group == "junit" -> true
+ module.group.startsWith("org.jetbrains") -> true
+ module.group == "com.google.auto.value" -> true
+ module.group == "com.google.guava" -> true
+ module.group == "junit" -> true
else -> false
}
}
-
- // Update app/Android.bp
- File("${project.projectDir.absolutePath}/Android.bp").let { file ->
- // Read dependencies
- val dependencies = "${spaces(8)}// DO NOT EDIT THIS SECTION MANUALLY\n".plus(
- configuration.allDependencies.filter {
- // kotlin-bom does not need to be added to dependencies
- it.group != "org.jetbrains.kotlin" && it.name != "kotlin-bom"
- }.joinToString("\n") {
- if (isAvailableInAosp(it.group!!, it.name)) {
- "${spaces(8)}\"${moduleNameAosp("${it.group}:${it.name}")}\","
- } else {
- "${spaces(8)}\"${moduleName("${it.group}:${it.name}")}\","
- }
- }
- )
-
- // Replace existing dependencies with newly generated ones
- file.writeText(
- file.readText().replace(
- "static_libs: \\[.*?\\]".toRegex(RegexOption.DOT_MATCHES_ALL),
- "static_libs: [%s]".format("\n$dependencies\n${spaces(4)}")
- )
- )
- }
-
- // Update app/libs
- configuration.resolvedConfiguration.resolvedArtifacts.sortedBy {
- moduleString(it.moduleVersion.id)
- }.distinctBy {
- moduleString(it.moduleVersion.id)
- }.forEach {
- val id = it.moduleVersion.id
-
- // Skip modules that are available in AOSP
- if (isAvailableInAosp(id.group, it.name)) {
- return@forEach
- }
-
- // Get file path
- val dirPath = "${libsBase}/${modulePath(id)}"
- val filePath = "${dirPath}/${it.file.name}"
-
- // Copy artifact to app/libs
- it.file.copyTo(File(filePath))
-
- // Parse dependencies
- val dependencies =
- it.file.parentFile.parentFile.walk().filter { file -> file.extension == "pom" }
- .map { file ->
- val ret = mutableListOf<String>()
-
- val pom = XmlParser().parse(file)
- val dependencies = (pom["dependencies"] as NodeList).firstOrNull() as Node?
-
- dependencies?.children()?.forEach { node ->
- val dependency = node as Node
- ret.add(
- "${
- (dependency.get("groupId") as NodeList).text()
- }:${
- (dependency.get("artifactId") as NodeList).text()
- }"
- )
- }
-
- ret
- }.flatten()
-
- var targetSdkVersion = android.defaultConfig.targetSdk
- var minSdkVersion = 14
-
- // Extract AndroidManifest.xml for AARs
- if (it.file.extension == "aar") {
- copy {
- from(zipTree(filePath).matching { include("/AndroidManifest.xml") }.singleFile)
- into(dirPath)
- }
-
- val androidManifest = XmlParser().parse(File("${dirPath}/AndroidManifest.xml"))
-
- val usesSdk = (androidManifest["uses-sdk"] as NodeList).first() as Node
- targetSdkVersion = (usesSdk.get("@targetSdkVersion") as Int?) ?: targetSdkVersion
- minSdkVersion = (usesSdk.get("@minSdkVersion") as Int?) ?: minSdkVersion
- }
-
- // Write Android.bp
- File("$libsBase/Android.bp").let { file ->
- // Add autogenerated header if file is empty
- if (file.length() == 0L) {
- file.writeText("// DO NOT EDIT THIS FILE MANUALLY")
- }
-
- val formatDeps = { addNoDeps: Boolean ->
- val deps = dependencies.filter { dep ->
- when {
- configuration.resolvedConfiguration.resolvedArtifacts.firstOrNull { artifact ->
- dep == "${artifact.moduleVersion.id.group}:${artifact.moduleVersion.id.name}"
- } == null -> {
- val moduleName = if (addNoDeps) {
- moduleName(id)
- } else {
- "${moduleName(id)}-nodeps"
- }
- println("$moduleName: Skipping $dep because it's not in resolvedArtifacts")
- false
- }
- dep == "org.jetbrains.kotlin:kotlin-stdlib-common" -> false
- else -> true
- }
- }.distinct().toMutableList()
-
- if (addNoDeps) {
- // Add -nodeps dependency for android_library/java_library_static
- deps.add(0, "${id.group}_${id.name}-nodeps")
- }
-
- var ret = ""
-
- if (deps.isNotEmpty()) {
- deps.forEach { dep ->
- ret += if (dep.contains(":")) {
- val (group, artifactId) = dep.split(":")
- if (isAvailableInAosp(group, artifactId)) {
- "\n${spaces(8)}\"${moduleNameAosp(dep)}\","
- } else {
- "\n${spaces(8)}\"${moduleName(dep)}\","
- }
- } else {
- "\n${spaces(8)}\"${moduleName(dep)}\","
- }
- }
- ret += "\n${spaces(4)}"
- }
-
- ret
- }
-
- when (it.extension) {
- "aar" -> {
- file.appendText(
- """
-
- android_library_import {
- name: "${moduleName(id)}-nodeps",
- aars: ["${modulePath(id)}/${it.file.name}"],
- sdk_version: "$targetSdkVersion",
- min_sdk_version: "$minSdkVersion",
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- static_libs: [%s],
- }
-
- android_library {
- name: "${moduleName(id)}",
- sdk_version: "$targetSdkVersion",
- min_sdk_version: "$minSdkVersion",
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- manifest: "${modulePath(id)}/AndroidManifest.xml",
- static_libs: [%s],
- java_version: "1.7",
- }
-
- """.trimIndent().format(formatDeps(false), formatDeps(true))
- )
- }
- "jar" -> {
- file.appendText(
- """
-
- java_import {
- name: "${moduleName(id)}-nodeps",
- jars: ["${modulePath(id)}/${it.file.name}"],
- sdk_version: "$targetSdkVersion",
- min_sdk_version: "$minSdkVersion",
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- }
-
- java_library_static {
- name: "${moduleName(id)}",
- sdk_version: "$targetSdkVersion",
- min_sdk_version: "$minSdkVersion",
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- static_libs: [%s],
- java_version: "1.7",
- }
-
- """.trimIndent().format(formatDeps(true))
- )
- }
- else -> throw Exception("Unknown file extension: ${it.extension}")
- }
- }
- }
}