Skip to content

Commit e1cebbf

Browse files
authored
Auto-wire ProGuard rules into Android builds via Variant API
1 parent 9ebb1c2 commit e1cebbf

4 files changed

Lines changed: 45 additions & 16 deletions

File tree

featured-gradle-plugin/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ mavenPublishing {
5555
}
5656

5757
dependencies {
58+
compileOnly("com.android.tools.build:gradle:9.1.0")
5859
testImplementation(gradleTestKit())
5960
testImplementation(libs.kotlin.testJunit)
6061
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package dev.androidbroadcast.featured.gradle
2+
3+
import com.android.build.api.variant.AndroidComponentsExtension
4+
import org.gradle.api.Project
5+
import org.gradle.api.tasks.TaskProvider
6+
7+
/**
8+
* Wires the generated ProGuard rules file into every Android variant via the AGP Variant API.
9+
*
10+
* Called lazily — only when `com.android.application` or `com.android.library` is present on
11+
* the project.
12+
*
13+
* AGP 9.x does not propagate implicit Gradle task dependencies through [Variant.proguardFiles],
14+
* so [proguardTask] is also wired explicitly as a dependency of every `minify*WithR8` task.
15+
*/
16+
internal fun wireProguardToVariants(
17+
project: Project,
18+
proguardTask: TaskProvider<GenerateProguardRulesTask>,
19+
) {
20+
val androidComponents =
21+
project.extensions
22+
.getByType(AndroidComponentsExtension::class.java)
23+
androidComponents.onVariants { variant ->
24+
variant.proguardFiles.add(
25+
proguardTask.flatMap { it.outputFile },
26+
)
27+
}
28+
// AGP 9.x does not propagate implicit task dependencies through variant.proguardFiles,
29+
// so we wire an explicit dependsOn on every R8 minify task.
30+
project.tasks.configureEach { task ->
31+
if (task.name.startsWith("minify") && task.name.endsWith("WithR8")) {
32+
task.dependsOn(proguardTask)
33+
}
34+
}
35+
}

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ public class FeaturedPlugin : Plugin<Project> {
5151

5252
registerConfigParamTask(target, resolveTask)
5353
registerFlagRegistrarTask(target, resolveTask)
54-
registerProguardTask(target, resolveTask)
54+
val proguardTask = registerProguardTask(target, resolveTask)
5555
registerIosConstValTask(target, resolveTask)
5656
registerXcconfigTask(target, resolveTask)
5757
wireToRootAggregator(target, resolveTask)
58+
listOf("com.android.application", "com.android.library").forEach { pluginId ->
59+
target.plugins.withId(pluginId) {
60+
wireProguardToVariants(target, proguardTask)
61+
}
62+
}
5863
}
5964

6065
private fun registerResolveFlagsTask(target: Project): TaskProvider<ResolveFlagsTask> =
@@ -99,7 +104,7 @@ public class FeaturedPlugin : Plugin<Project> {
99104
private fun registerProguardTask(
100105
target: Project,
101106
resolveTask: TaskProvider<ResolveFlagsTask>,
102-
) {
107+
): TaskProvider<GenerateProguardRulesTask> =
103108
target.tasks.register(GENERATE_PROGUARD_TASK_NAME, GenerateProguardRulesTask::class.java) { task ->
104109
task.group = "featured"
105110
task.description = "Generates ProGuard/R8 -assumevalues rules for local flags in '${target.path}'."
@@ -108,7 +113,6 @@ public class FeaturedPlugin : Plugin<Project> {
108113
task.outputFile.set(target.layout.buildDirectory.file("featured/proguard-featured.pro"))
109114
task.dependsOn(resolveTask)
110115
}
111-
}
112116

113117
private fun registerIosConstValTask(
114118
target: Project,

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/GenerateProguardRulesTask.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,8 @@ import org.gradle.api.tasks.TaskAction
1919
* [ExtensionFunctionGenerator], so R8 can propagate the exact constant and eliminate
2020
* dead branches in release builds.
2121
*
22-
* Wire the generated file into your Android module's ProGuard configuration:
23-
* ```kotlin
24-
* android {
25-
* buildTypes {
26-
* release {
27-
* proguardFiles(
28-
* getDefaultProguardFile("proguard-android-optimize.txt"),
29-
* layout.buildDirectory.file("featured/proguard-featured.pro").get().asFile,
30-
* )
31-
* }
32-
* }
33-
* }
34-
* ```
22+
* For Android projects the generated file is automatically wired into all variants via the
23+
* AGP Variant API — no manual ProGuard configuration is required.
3524
*/
3625
@CacheableTask
3726
public abstract class GenerateProguardRulesTask : DefaultTask() {

0 commit comments

Comments
 (0)