Skip to content

Commit

Permalink
Added task to simplify migration to ResourceManager.
Browse files Browse the repository at this point in the history
  • Loading branch information
vsnappy1 committed Nov 1, 2024
1 parent b0d034c commit 2bf9cae
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
2 changes: 2 additions & 0 deletions resourcemanager/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ plugins {
id("maven-publish")
}

apply("gradle/migration.gradle.kts")

/**
* Retrieves the KSP (Kotlin Symbol Processing) version to be used in the project.
*
Expand Down
102 changes: 102 additions & 0 deletions resourcemanager/gradle/migration.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
val replacements: Map<Regex, String> by lazy {
mapOf(
Regex("(?:\\w+\\s*\\.)*\\s*getString\\(\\s*R\\.\\s*string\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Strings.",
Regex("(?:\\w+\\s*\\.)*\\s*getString\\(\\s*R\\.\\s*string\\.\\s*(\\w+)\\s*,\\s*(.*)\\s*\\)") to "ResourceManager.Strings.",
Regex("(?:\\w+\\s*\\.)*\\s*getString\\(\\s*\\w+\\s*,\\s*R\\.\\s*string\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Strings.",
Regex("(?:\\w+\\s*\\.)*\\s*getColor\\(\\s*R\\.\\s*color\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Colors.",
Regex("(?:\\w+\\s*\\.)*\\s*getColor\\(\\s*R\\.\\s*color\\.\\s*(\\w+)\\s*,\\s*(.*)\\s*\\)") to "ResourceManager.Colors.",
Regex("(?:\\w+\\s*\\.)*\\s*getColor\\(\\s*\\w+\\s*,\\s*R\\.\\s*color\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Colors.",
Regex("(?:\\w+\\s*\\.)*\\s*getDrawable\\(\\s*R\\.\\s*drawable\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Drawables.",
Regex("(?:\\w+\\s*\\.)*\\s*getDrawable\\(\\s*R\\.\\s*drawable\\.\\s*(\\w+)\\s*,\\s*(.*)\\s*\\)") to "ResourceManager.Drawables.",
Regex("(?:\\w+\\s*\\.)*\\s*getDrawable\\(\\s*\\w+\\s*,\\s*R\\.\\s*drawable\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Drawables.",
Regex("(?:\\w+\\s*\\.)*\\s*getStringArray\\(\\s*R\\.\\s*array\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.StringArrays.",
Regex("(?:\\w+\\s*\\.)*\\s*getIntArray\\(\\s*R\\.\\s*array\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.IntArrays.",
Regex("(?:\\w+\\s*\\.)*\\s*getBoolean\\(\\s*R\\.\\s*bool\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Booleans.",
Regex("(?:\\w+\\s*\\.)*\\s*getFraction\\(\\s*R\\.\\s*fraction\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Fractions.",
Regex("(?:\\w+\\s*\\.)*\\s*getDimension\\(\\s*R\\.\\s*dimen\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Dimensions.",
Regex("(?:\\w+\\s*\\.)*\\s*getInteger\\(\\s*R\\.\\s*integer\\.\\s*(\\w+)\\s*\\)") to "ResourceManager.Integers.",
Regex("(?:\\w+\\s*\\.)*\\s*getFraction\\(\\s*R\\.\\s*fraction\\.\\s*(\\w+)\\s*,\\s*(.*)\\s*\\)") to "ResourceManager.Fractions.",
Regex("(?:\\w+\\s*\\.)*\\s*getQuantityString\\(\\s*R\\.\\s*plurals\\.\\s*(\\w+)\\s*,\\s*(.*)\\s*\\)") to "ResourceManager.Plurals."
)
}

tasks.register("migrateToResourceManager") {
group = "migration"
description =
"Replaces android resource access calls with the ResourceManager equivalents across the specified module."

// Check for module flag
if (!project.hasProperty("module")) {
val message = "Error: Missing module name. Specify the module to migrate using -Pmodule=<module_name>."
throw GradleException("Migration cancelled. $message")
}

// Check for confirmation flag
if (!project.hasProperty("confirmMigration")) {
println("Warning: This task will modify project files.")
val message = "Error: Confirmation flag missing. To proceed, rerun the task with -PconfirmMigration=true."
throw GradleException("Migration cancelled. $message")
}

val module = project.properties["module"]
val modulePath = file("${file(projectDir.absolutePath).parent}/$module/src/main")

// Check if given module exist
if (!modulePath.exists()) {
throw IllegalArgumentException("The specified module path does not exist: $modulePath. Please check the module name: '$module'.")
}

val codeFiles =
fileTree(modulePath).files.filter { it.extension == "kt" || it.extension == "java" }

println("\n***************** MIGRATION START *****************\n")
var totalChangesCount = 0
var fileUpdateCount = 0

codeFiles.forEach { file ->
var changesCount = 0
var content = file.readText()

replacements.forEach { (regex, s) ->
val matches = regex.findAll(content)
matches.forEach { matchResult ->
val resourceId = matchResult.groups[1]?.value.orEmpty()
val resourceIdCamelCase =
"${s}${resourceId.toCamelCase().replaceFirstChar { id -> id.lowercase() }}"

content = when (matchResult.groups.size) {
2 -> {
content.replace(matchResult.value, "${resourceIdCamelCase}()")
}

3 -> {
val param = matchResult.groups[2]?.value.orEmpty()
content.replace(matchResult.value, "${resourceIdCamelCase}($param)")
}

else -> {
content
}
}
changesCount++
}
}
if (changesCount > 0) {
file.writeText(content)
println("Updated file '${file.name}' (${file.path}:) with $changesCount change(s).")
fileUpdateCount++
}
totalChangesCount += changesCount
}
println("\nModified $fileUpdateCount file(s) with a total of $totalChangesCount changes applied.")
println("\n***************** MIGRATION END *****************\n")
}

fun String.toCamelCase(): String {
return split('_') // Split by underscores
.mapIndexed { index, word ->
if (index == 0) word.lowercase() // First word stays lowercase
else word.replaceFirstChar { it.uppercase() } // Capitalize the first letter of subsequent words
}
.joinToString("") // Join the words back together without spaces
}

0 comments on commit 2bf9cae

Please sign in to comment.