Skip to content

Commit 7202fed

Browse files
committed
Refactor StringCare plugin: remove ExecutionListener, streamline variant registration, and update task handling. Adjust variable visibility in Vars.kt and update test annotations to JUnit 5.
1 parent 881643c commit 7202fed

10 files changed

Lines changed: 379 additions & 183 deletions

File tree

Lines changed: 24 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11

2-
import components.*
2+
import components.PrintUtils
3+
import components.config
4+
import components.createExtension
5+
import components.defaultConfig
6+
import components.registerTask
7+
import components.registerVariantObfuscationTasks
8+
import components.absolutePath
9+
import components.tempPath
310
import org.gradle.api.Plugin
411
import org.gradle.api.Project
512

@@ -26,7 +33,6 @@ open class StringCare : Plugin<Project> {
2633

2734
@JvmStatic
2835
internal var variantMap = mutableMapOf<String, String>()
29-
3036
}
3137

3238
private lateinit var project: Project
@@ -38,107 +44,26 @@ open class StringCare : Plugin<Project> {
3844
extension = project.createExtension()
3945
absoluteProjectPath = project.absolutePath()
4046

41-
this.project.afterEvaluate {
42-
this.project.applicationVariants()?.forEach { variant ->
43-
variantMap[variant.name] = variant.applicationId
47+
project.plugins.withId("com.android.application") {
48+
// Must register onVariants early; cannot call it from afterEvaluate.
49+
val config = project.config(extension)
50+
configuration = config
51+
project.registerVariantObfuscationTasks(extension, config)
52+
project.afterEvaluate {
53+
if (configuration.debug) {
54+
PrintUtils.print("PATH", absoluteProjectPath)
55+
}
56+
project.registerTask(configuration)
4457
}
45-
configuration = this.project.config(extension)
58+
}
4659

47-
if (configuration.debug) {
48-
PrintUtils.print("PATH", absoluteProjectPath)
60+
// Fallback when applied to non-application project: still register preview/test tasks
61+
if (!project.plugins.hasPlugin("com.android.application")) {
62+
project.afterEvaluate {
63+
configuration = project.config(extension)
64+
project.registerTask(configuration)
4965
}
50-
this.project.registerTask(configuration)
5166
}
52-
this.project.gradle.addBuildListener(
53-
ExecutionListener(
54-
debug = configuration.debug,
55-
dataFound = { _, _ ->
56-
// nothing to do here
57-
},
58-
mergeResourcesStart = { module, variant ->
59-
configuration.name = module
60-
if (variantMap.containsKey(variant)) {
61-
configuration.applicationId = variantMap[variant] ?: ""
62-
}
63-
PrintUtils.print("", "ApplicationId: ${configuration.applicationId}", tab = true)
64-
fingerPrint(module, variant, configuration) { key ->
65-
if (configuration.skip) {
66-
PrintUtils.print(module, "Skipping $variant")
67-
return@fingerPrint
68-
}
69-
70-
if ("none" == key || key.trim().isEmpty()) {
71-
PrintUtils.print("No SHA1 key found for :$module:$variant")
72-
return@fingerPrint
73-
}
74-
75-
PrintUtils.print(module, "$variant:$key")
76-
PrintUtils.print(module, backupStringRes)
77-
backupResourceFiles(absoluteProjectPath, configuration)
78-
79-
80-
val files = locateResourceFiles(absoluteProjectPath, configuration)
81-
files.forEach { file ->
82-
modifyXML(file.file, key, configuration)
83-
}
84-
}
85-
PrintUtils.print(module, obfuscateStringRes)
86-
},
87-
mergeResourcesFinish = { module, _ ->
88-
if (configuration.skip) {
89-
return@ExecutionListener
90-
}
91-
PrintUtils.print(module, restoreStringRes)
92-
restoreResourceFiles(absoluteProjectPath, module)
93-
},
94-
mergeAssetsStart = { module, variant ->
95-
configuration.name = module
96-
if (variantMap.containsKey(variant)) {
97-
configuration.applicationId = variantMap[variant] ?: ""
98-
}
99-
PrintUtils.print("", "ApplicationId: ${configuration.applicationId}", tab = true)
100-
fingerPrint(module, variant, configuration) { key ->
101-
if (configuration.skip) {
102-
PrintUtils.print(module, "Skipping $variant")
103-
return@fingerPrint
104-
}
105-
106-
if ("none" == key || key.trim().isEmpty()) {
107-
PrintUtils.print("No SHA1 key found for :$module:$variant")
108-
return@fingerPrint
109-
}
110-
111-
PrintUtils.print(module, "$variant:$key")
112-
PrintUtils.print(module, backupAssets)
113-
backupAssetsFiles(absoluteProjectPath, configuration)
114-
115-
116-
val files = locateAssetsFiles(absoluteProjectPath, configuration)
117-
files.forEach { file ->
118-
if (configuration.debug) {
119-
PrintUtils.print(null, file.file.getContent())
120-
}
121-
obfuscateFile(
122-
key,
123-
file.file,
124-
configuration.applicationId
125-
)
126-
if (configuration.debug) {
127-
PrintUtils.print(null, file.file.getContent())
128-
}
129-
}
130-
PrintUtils.print(module, obfuscateAssets)
131-
}
132-
},
133-
mergeAssetsFinish = { module, _ ->
134-
if (configuration.skip) {
135-
return@ExecutionListener
136-
}
137-
PrintUtils.print(module, restoreAssets)
138-
restoreAssetsFiles(absoluteProjectPath, module)
139-
}
140-
141-
))
14267
}
14368

14469
open class Extension {
@@ -159,7 +84,4 @@ open class StringCare : Plugin<Project> {
15984
var applicationId = ""
16085
var mockedFingerprint = ""
16186
}
162-
16387
}
164-
165-

plugin/src/main/kotlin/components/ExecutionListener.kt

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package components
2+
3+
import StringCare
4+
import StringCare.Configuration
5+
import StringCare.Extension
6+
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
7+
import com.google.gson.Gson
8+
import org.gradle.api.Project
9+
import task.ObfuscateAssetsTask
10+
import task.ObfuscateStringsTask
11+
import task.RestoreAssetsTask
12+
import task.RestoreStringsTask
13+
14+
private fun String.variantTaskSuffix(): String = replaceFirstChar { it.uppercase() }
15+
16+
/**
17+
* Registers per-variant obfuscation tasks and wires them to merge/generate tasks.
18+
* Replaces the BuildListener (ExecutionListener) approach.
19+
* Wiring to merge/generate tasks is deferred to afterEvaluate since those tasks are created after onVariants.
20+
*/
21+
fun Project.registerVariantObfuscationTasks(extension: Extension, config: Configuration) {
22+
val androidComponents = extensions.findByType(ApplicationAndroidComponentsExtension::class.java)
23+
?: return
24+
25+
val gson = Gson()
26+
val projectPath = StringCare.absoluteProjectPath
27+
val moduleName = config.name
28+
val variantNames = mutableListOf<String>()
29+
30+
androidComponents.onVariants(androidComponents.selector().all()) { variant ->
31+
val variantName: String = variant.name
32+
val applicationId = variant.applicationId.get()
33+
StringCare.variantMap[variantName] = applicationId
34+
val variantCapitalized = variantName.variantTaskSuffix()
35+
36+
// Strings: before merge*Resources -> obfuscate; after merge*Resources -> restore
37+
val beforeStrings = tasks.register(
38+
"stringcareBeforeMergeResources$variantCapitalized",
39+
ObfuscateStringsTask::class.java
40+
) {
41+
it.projectPath = projectPath
42+
it.moduleName = moduleName
43+
it.variantName = variantName
44+
it.applicationId = applicationId
45+
it.skip = config.skip
46+
it.debug = config.debug
47+
it.mockedFingerprint = config.mockedFingerprint
48+
it.srcFoldersJson = gson.toJson(config.srcFolders)
49+
it.stringFilesJson = gson.toJson(config.stringFiles)
50+
it.assetsFilesJson = gson.toJson(config.assetsFiles)
51+
}
52+
val afterStrings = tasks.register(
53+
"stringcareAfterMergeResources$variantCapitalized",
54+
RestoreStringsTask::class.java
55+
) {
56+
it.projectPath = projectPath
57+
it.moduleName = moduleName
58+
it.skip = config.skip
59+
}
60+
variantNames.add(variantCapitalized)
61+
62+
// Assets: before generate*Assets -> obfuscate; after merge*Assets -> restore
63+
val beforeAssets = tasks.register(
64+
"stringcareBeforeMergeAssets$variantCapitalized",
65+
ObfuscateAssetsTask::class.java
66+
) {
67+
it.projectPath = projectPath
68+
it.moduleName = moduleName
69+
it.variantName = variantName
70+
it.applicationId = applicationId
71+
it.skip = config.skip
72+
it.debug = config.debug
73+
it.mockedFingerprint = config.mockedFingerprint
74+
it.srcFoldersJson = gson.toJson(config.srcFolders)
75+
it.stringFilesJson = gson.toJson(config.stringFiles)
76+
it.assetsFilesJson = gson.toJson(config.assetsFiles)
77+
}
78+
val afterAssets = tasks.register(
79+
"stringcareAfterMergeAssets$variantCapitalized",
80+
RestoreAssetsTask::class.java
81+
) {
82+
it.projectPath = projectPath
83+
it.moduleName = moduleName
84+
it.skip = config.skip
85+
}
86+
}
87+
88+
project.afterEvaluate {
89+
for (variantCapitalized in variantNames) {
90+
val mergeRes = "merge${variantCapitalized}Resources"
91+
val beforeRes = "stringcareBeforeMergeResources$variantCapitalized"
92+
val afterRes = "stringcareAfterMergeResources$variantCapitalized"
93+
val processRes = "process${variantCapitalized}Resources"
94+
tasks.findByName(mergeRes)?.dependsOn(beforeRes)
95+
tasks.findByName(afterRes)?.dependsOn(mergeRes)
96+
tasks.findByName(processRes)?.dependsOn(afterRes)
97+
val genAssets = "generate${variantCapitalized}Assets"
98+
val beforeAssets = "stringcareBeforeMergeAssets$variantCapitalized"
99+
val mergeAssets = "merge${variantCapitalized}Assets"
100+
val afterAssets = "stringcareAfterMergeAssets$variantCapitalized"
101+
tasks.findByName(genAssets)?.dependsOn(beforeAssets)
102+
tasks.findByName(afterAssets)?.dependsOn(mergeAssets)
103+
tasks.findByName("compress${variantCapitalized}Assets")?.dependsOn(afterAssets)
104+
}
105+
}
106+
}

plugin/src/main/kotlin/components/Vars.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ internal const val wrapperWindows = "gradlew.bat"
1313
internal const val copyCommandOsX = "cp"
1414
internal const val copyCommandWindows = "copy"
1515
internal const val emptyChar = ""
16-
internal const val backupStringRes = "backupStringResources"
17-
internal const val obfuscateStringRes = "obfuscateStringResources"
18-
internal const val restoreStringRes = "restoreStringResources"
19-
internal const val backupAssets = "backupAssets"
20-
internal const val obfuscateAssets = "obfuscateAssets"
21-
internal const val restoreAssets = "restoreAssets"
16+
const val backupStringRes = "backupStringResources"
17+
const val obfuscateStringRes = "obfuscateStringResources"
18+
const val restoreStringRes = "restoreStringResources"
19+
const val backupAssets = "backupAssets"
20+
const val obfuscateAssets = "obfuscateAssets"
21+
const val restoreAssets = "restoreAssets"
2222
internal const val test = "Test"
2323
internal const val pre = "pre"
2424
internal const val build = "Build"

0 commit comments

Comments
 (0)