Skip to content

Commit 6ed01d8

Browse files
committed
plugin logic
1 parent eb811fc commit 6ed01d8

File tree

10 files changed

+222
-42
lines changed

10 files changed

+222
-42
lines changed

src/main/kotlin/StringCare.kt

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,84 @@
1+
import components.*
12
import models.Configuration
23
import models.Extension
3-
import org.gradle.api.NamedDomainObjectContainer
44
import org.gradle.api.Plugin
55
import org.gradle.api.Project
6-
import components.absolutePath
7-
import components.createConfiguration
8-
import components.createExtension
96

107
class StringCare : Plugin<Project> {
118

129
private lateinit var absoluteProjectPath: String
1310
private lateinit var project: Project
1411
private lateinit var extension: Extension
15-
private lateinit var configuration: NamedDomainObjectContainer<Configuration>
12+
private val moduleMap: MutableMap<String, Configuration> = mutableMapOf()
13+
1614

1715
override fun apply(target: Project) {
1816
this@StringCare.project = target
19-
defineExtension()
20-
}
2117

22-
private fun defineExtension() {
2318
extension = project.createExtension()
24-
configuration = project.createConfiguration()
2519
absoluteProjectPath = project.absolutePath()
20+
21+
this.project.afterEvaluate {
22+
extension.modules.forEach { module ->
23+
when {
24+
module.stringFiles != null && module.srcFolders != null -> {
25+
moduleMap[module.name!!] = Configuration(module.name, module.stringFiles, module.srcFolders)
26+
}
27+
module.srcFolders != null -> {
28+
moduleMap[module.name!!] =
29+
Configuration(module.name, defaultConfig().stringFiles, module.srcFolders)
30+
}
31+
module.stringFiles != null -> {
32+
moduleMap[module.name!!] =
33+
Configuration(module.name, module.stringFiles, defaultConfig().srcFolders)
34+
}
35+
}
36+
}
37+
}
38+
this.project.gradle.addBuildListener(ExecutionListener(
39+
debug = extension.debug,
40+
dataFound = { _, _ ->
41+
// nothing to do here
42+
}, mergeResourcesStart = { module, variant ->
43+
fingerPrint(module, variant, extension.debug) { key ->
44+
if ("none" == key) {
45+
return@fingerPrint
46+
}
47+
when {
48+
moduleMap.containsKey(module) -> {
49+
PrintUtils.print(module, "$variant:$key")
50+
PrintUtils.print(module, backupStringRes)
51+
moduleMap[module]?.let { configuration ->
52+
backupFiles(absoluteProjectPath, configuration)
53+
}
54+
moduleMap[module]?.let { configuration ->
55+
val files = locateFiles(absoluteProjectPath, configuration)
56+
files.forEach { file ->
57+
modifyXML(file.file, extension.main_module, key, extension.debug)
58+
}
59+
}
60+
PrintUtils.print(module, obfuscateStringRes)
61+
}
62+
else -> {
63+
val defaultConfiguration = defaultConfig().apply {
64+
name = module
65+
}
66+
PrintUtils.print(module, "$variant:$key")
67+
PrintUtils.print(module, backupStringRes)
68+
backupFiles(absoluteProjectPath, defaultConfiguration)
69+
PrintUtils.print(module, obfuscateStringRes)
70+
val files = locateFiles(absoluteProjectPath, defaultConfiguration)
71+
files.forEach { file ->
72+
modifyXML(file.file, extension.main_module, key, extension.debug)
73+
}
74+
}
75+
}
76+
}
77+
78+
}, mergeResourcesFinish = { module, _ ->
79+
restoreFiles(absoluteProjectPath, module)
80+
}
81+
))
2682
}
2783

28-
}
84+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package components
2+
3+
import org.gradle.BuildListener
4+
import org.gradle.BuildResult
5+
import org.gradle.api.Task
6+
import org.gradle.api.execution.TaskExecutionListener
7+
import org.gradle.api.initialization.Settings
8+
import org.gradle.api.invocation.Gradle
9+
import org.gradle.api.tasks.TaskState
10+
11+
class ExecutionListener(
12+
private val debug: Boolean = false,
13+
val dataFound: (module: String, variant: String) -> Unit,
14+
val mergeResourcesStart: (module: String, variant: String) -> Unit,
15+
val mergeResourcesFinish: (module: String, variant: String) -> Unit
16+
) : BuildListener,
17+
TaskExecutionListener {
18+
19+
override fun beforeExecute(task: Task) {
20+
when {
21+
task.dataFound() -> task.getModuleName()?.let {
22+
dataFound(it, PrintUtils.uncapitalize(task.dataFoundVariant()))
23+
}
24+
task.onMergeResourcesStarts() -> task.getModuleName()?.let {
25+
if (debug) {
26+
PrintUtils.print(it, "Module: $it", true)
27+
}
28+
mergeResourcesStart(it, PrintUtils.uncapitalize(task.onMergeResourcesStartsVariant()))
29+
}
30+
}
31+
}
32+
33+
override fun afterExecute(task: Task, state: TaskState) {
34+
when {
35+
task.onMergeResourcesFinish() -> task.getModuleName()?.let {
36+
mergeResourcesFinish(it, PrintUtils.uncapitalize(task.onMergeResourcesFinishVariant()))
37+
}
38+
}
39+
}
40+
41+
override fun settingsEvaluated(settings: Settings) {
42+
// nothing to do here
43+
}
44+
45+
override fun buildFinished(result: BuildResult) {
46+
// nothing to do here
47+
}
48+
49+
override fun projectsLoaded(gradle: Gradle) {
50+
// nothing to do here
51+
}
52+
53+
override fun buildStarted(gradle: Gradle) {
54+
// nothing to do here
55+
}
56+
57+
override fun projectsEvaluated(gradle: Gradle) {
58+
// nothing to do here
59+
}
60+
}

src/main/kotlin/components/Extensions.kt

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import models.Extension
66
import models.ResourceFile
77
import org.gradle.api.NamedDomainObjectContainer
88
import org.gradle.api.Project
9+
import org.gradle.api.Task
910
import org.w3c.dom.Document
1011
import org.xml.sax.InputSource
1112
import java.io.*
@@ -25,17 +26,21 @@ fun String.unescape(): String = StringEscapeUtils.unescapeJava(this)
2526
fun String.removeNewLines(): String = this.replace("\n", "")
2627

2728
fun File.validForConfiguration(configuration: Configuration): Boolean {
28-
var valid = false
29-
configuration.srcFolders.forEach { folder ->
30-
if (this.absolutePath.contains("/$folder/".replace("//", "/"))
29+
var valid = this.absolutePath.contains("/${configuration.name}/")
3130
&& !this.absolutePath.contains("/$resourceBackup/")
32-
) {
33-
valid = true
31+
if (valid) {
32+
valid = false
33+
configuration.srcFolders?.forEach { folder ->
34+
if (this.absolutePath.contains("/$folder/".replace("//", "/"))
35+
&& !this.absolutePath.contains("/$resourceBackup/")
36+
) {
37+
valid = true
38+
}
3439
}
3540
}
3641
if (valid) {
3742
valid = false
38-
configuration.stringFiles.forEach { file ->
43+
configuration.stringFiles?.forEach { file ->
3944
if (this.absolutePath.contains("/$file".replace("//", "/"))) {
4045
valid = true
4146
}
@@ -48,7 +53,7 @@ fun File.resourceFile(configuration: Configuration): ResourceFile? {
4853
var sourceFolder = ""
4954
var validFile: File? = null
5055
var valid = false
51-
configuration.srcFolders.forEach { folder ->
56+
configuration.srcFolders?.forEach { folder ->
5257
if (this.absolutePath.contains("/$folder/".replace("//", "/"))
5358
&& !this.absolutePath.contains("/$resourceBackup/")
5459
) {
@@ -58,24 +63,26 @@ fun File.resourceFile(configuration: Configuration): ResourceFile? {
5863
}
5964
if (valid) {
6065
valid = false
61-
configuration.stringFiles.forEach { file ->
66+
configuration.stringFiles?.forEach { file ->
6267
if (this.absolutePath.contains("/$file".replace("//", "/"))) {
6368
valid = true
6469
validFile = this
6570
}
6671
}
6772
}
68-
return if (valid) ResourceFile(validFile!!, sourceFolder, configuration.name) else null
73+
return if (valid) ResourceFile(validFile!!, sourceFolder, configuration.name!!) else null
6974
}
7075

7176
fun Project.absolutePath(): String = this.file(wrapperWindows).absolutePath.replace(
7277
wrapperWindows,
7378
emptyChar
7479
)
7580

76-
fun Project.createExtension(): Extension = this.extensions.create(extensionName, Extension::class.java)
77-
fun Project.createConfiguration(): NamedDomainObjectContainer<Configuration> =
78-
this.container<Configuration>(Configuration::class.java)
81+
fun Project.createExtension(): Extension {
82+
val extension = this.extensions.create(extensionName, Extension::class.java)
83+
extension.modules = this.container<Configuration>(Configuration::class.java)
84+
return extension
85+
}
7986

8087
fun Process.outputString() = this.inputStream.bufferedReader().use { it.readText() }
8188

@@ -145,3 +152,31 @@ fun File.removeHiddenAttributes() {
145152

146153
fun File.getContent() = this.inputStream().readBytes().toString(Charsets.UTF_8)
147154

155+
fun Task.getModuleName(): String? {
156+
val path = this.project.path
157+
return if (path.isEmpty()) null else path.split(":")[path.split(":").size - 1]
158+
}
159+
160+
fun Task.dataFound(): Boolean = this.name.contains(pre)
161+
&& this.name.contains(build)
162+
&& this.name != "$pre$build"
163+
&& !this.name.contains(test)
164+
165+
fun Task.onMergeResourcesStarts(): Boolean = this.name.contains(merge)
166+
&& this.name.contains(resources)
167+
&& !this.name.contains(test)
168+
169+
fun Task.onMergeResourcesFinish(): Boolean = this.name.contains(merge)
170+
&& this.name.contains(resources)
171+
&& !this.name.contains(test)
172+
173+
fun Task.dataFoundVariant(): String = this.name.substring(pre.length)
174+
.substring(0, this.name.substring(pre.length).length - build.length)
175+
176+
fun Task.onMergeResourcesStartsVariant(): String = this.name.substring(merge.length)
177+
.substring(0, this.name.substring(merge.length).length - resources.length)
178+
179+
fun Task.onMergeResourcesFinishVariant(): String = this.name.substring(merge.length)
180+
.substring(0, this.name.substring(merge.length).length - resources.length)
181+
182+

src/main/kotlin/components/Fingerprint.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ private class Fingerprint {
7575
/**
7676
* Gets the signing report trace and extracts the fingerprint
7777
*/
78-
fun fingerPrint(module: String, variant: String, debug: Boolean): String {
79-
return signingReportTask().runCommand().extractFingerprint(module, variant, debug)
78+
fun fingerPrint(module: String, variant: String, debug: Boolean, keyFound: (key: String) -> Unit) {
79+
signingReportTask().runCommand { _, report ->
80+
keyFound(report.extractFingerprint(module, variant, debug))
81+
}
8082
}
8183

8284
/**
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package components
2+
3+
interface TasksStatus {
4+
5+
fun debug(): Boolean
6+
7+
fun onDataFound(module: String, variant: String)
8+
9+
fun onMergeResourcesStarts(module: String, variant: String)
10+
11+
fun onMergeResourcesFinish(module: String, variant: String)
12+
}

src/main/kotlin/components/Vars.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,12 @@ internal const val osxLib = "libsignKey.dylib"
77
internal const val wrapperOsX = "./gradlew"
88
internal const val wrapperWindows = "gradlew.bat"
99
internal const val emptyChar = ""
10+
11+
internal const val backupStringRes: String = "backupStringResources"
12+
internal const val obfuscateStringRes: String = "obfuscateStringResources"
13+
14+
internal const val test: String = "Test"
15+
internal const val pre: String = "pre"
16+
internal const val build: String = "Build"
17+
internal const val merge: String = "merge"
18+
internal const val resources: String = "Resources"

src/main/kotlin/components/XParser.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ fun backupFiles(projectPath: String, configuration: Configuration): List<File> {
2020
return resourceFiles
2121
}
2222

23-
fun restoreFiles(projectPath: String): List<File> {
24-
val resourceFiles = File("$projectPath${File.separator}$resourceBackup").walkTopDown().toList()
23+
fun restoreFiles(projectPath: String, module: String): List<File> {
24+
val resourceFiles = File("$projectPath${File.separator}$resourceBackup${File.separator}$module").walkTopDown().toList()
2525
resourceFiles.filter { file ->
2626
!file.isDirectory
2727
}.map {
@@ -30,9 +30,9 @@ fun restoreFiles(projectPath: String): List<File> {
3030
return resourceFiles
3131
}
3232

33-
fun parseXML(file: File, module: String, debug: Boolean): List<StringEntity> {
33+
fun parseXML(file: File, debug: Boolean): List<StringEntity> {
3434
if (debug) {
35-
PrintUtils.print(module, file.getContent(), true)
35+
PrintUtils.print(null, file.getContent(), true)
3636
}
3737
val entities = mutableListOf<StringEntity>()
3838

@@ -62,10 +62,10 @@ fun parseXML(file: File, module: String, debug: Boolean): List<StringEntity> {
6262
return entities
6363
}
6464

65-
fun modifyXML(file: File, module: String, key: String, debug: Boolean) {
66-
val stringEntities = parseXML(file, module, debug)
65+
fun modifyXML(file: File, mainModule: String, key: String, debug: Boolean) {
66+
val stringEntities = parseXML(file, debug)
6767
if (debug) {
68-
PrintUtils.print(module, file.getContent(), true)
68+
PrintUtils.print(null, file.getContent(), true)
6969
}
7070

7171
val doc = file.getXML()
@@ -76,7 +76,7 @@ fun modifyXML(file: File, module: String, key: String, debug: Boolean) {
7676
it.tag == "string" && it.index == i
7777
}
7878
entity?.let {
79-
node.firstChild.nodeValue = obfuscate(module, key, it).value
79+
node.firstChild.nodeValue = obfuscate(mainModule, key, it).value
8080
}
8181
}
8282

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package models
22

3-
data class Configuration(val name: String, val stringFiles: List<String>, val srcFolders: List<String>)
3+
class Configuration(var name: String?, val stringFiles: List<String>?, val srcFolders: List<String>?)

src/main/kotlin/models/Extension.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
package models
22

3-
data class Extension(val debug: Boolean, val main_module: String)
3+
import org.gradle.api.NamedDomainObjectContainer
4+
5+
data class Extension(
6+
val debug: Boolean = false,
7+
val main_module: String = "app",
8+
var modules: NamedDomainObjectContainer<Configuration>
9+
)

0 commit comments

Comments
 (0)