Skip to content

Instantly share code, notes, and snippets.

@saifc
Created November 3, 2022 17:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saifc/74ed2246a40616427ec90e771e6ccf4d to your computer and use it in GitHub Desktop.
Save saifc/74ed2246a40616427ec90e771e6ccf4d to your computer and use it in GitHub Desktop.
non-transitive R class scripts
#!/usr/bin/env bash
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
if [[ "$machine" == Mac ]]; then
echo ""
echo "Setting up live templates..."
ls -d ~/Library/Application\ Support/Google/AndroidStudio* | xargs -I{} cp -R config/templates {}
echo "Live templates set! This will take effect after restarting Studio."
fi
import java.io.File
import java.nio.file.Files
import java.nio.file.StandardCopyOption
private const val ARG_PROJECT_DIR = "-projectDir"
private val IMPORT_ALIASES = mapOf(
"slack.l10n" to "L10nR",
"slack.uikit.resources" to "SlackKitR",
"slack.uikit" to "UiKitR",
"slack.coreui" to "CoreUiR"
)
fun main(args: Array<String>) {
val indexOfProjectPath = args.indexOf(ARG_PROJECT_DIR)
require(indexOfProjectPath > -1)
val projectPath = args[indexOfProjectPath + 1]
val script = FullyQualifiedResourceToImportAlias(projectPath)
IMPORT_ALIASES.forEach { (packageName, rReplacement) ->
script.run(packageName, rReplacement)
}
}
private class FullyQualifiedResourceToImportAlias(
private val projectPath: String
) {
private val packageRegex = "package ([a-zA-Z0-9_.]+)".toRegex()
fun run(packageName: String, rReplacement: String) {
println("Looking for $packageName.R usages")
val rRegex = "($packageName\\.R)\\.".toRegex()
File("$projectPath/").walk()
.filter {
!it.isDirectory && it.isKotlinFile()
}
.forEach { file ->
val shouldAddImport = refactorFqNames(file, rRegex, rReplacement)
if (shouldAddImport) {
addImport(file, packageName, rReplacement)
}
}
}
private fun refactorFqNames(file: File, rRegex: Regex, rReplacement: String): Boolean {
val br = file.bufferedReader()
var writeFile = false
val newFile = File(file.absolutePath + "_tmp").apply {
createNewFile()
}
newFile.bufferedWriter().use { bw ->
var line = br.readLine()
while (line != null) {
val matches = rRegex.findAll(line).toList().reversed()
matches.forEach {
val (prefix) = it.destructured
if (prefix != "R") {
line = line.replaceRange(it.groups[1]!!.range, rReplacement)
writeFile = true
}
}
bw.write(line)
line = br.readLine()
if (line != null) {
bw.newLine()
}
}
}
br.close()
if (writeFile) {
println("Refactoring ${file.name}")
Files.move(newFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING)
} else {
newFile.delete()
}
return writeFile
}
private fun addImport(file: File, packageName: String, rReplacement: String) {
val newestFile = File(file.absolutePath + "_tmp1").apply {
createNewFile()
}
newestFile.bufferedWriter().use { bw ->
var matchFound = false
val bufferedReader = file.bufferedReader()
var line = bufferedReader.readLine()
while (line != null) {
if (!matchFound) {
val match = packageRegex.find(line)
if (match != null) {
matchFound = true
bw.write(match.value)
bw.newLine()
bw.newLine()
line = "import $packageName.R as $rReplacement"
}
}
bw.write(line)
line = bufferedReader.readLine()
bw.newLine()
}
}
Files.move(newestFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
private fun File.isKotlinFile() = name.endsWith(".kt")
}
<templateSet group="SlackAndroid">
<template name="rl10n" description="Import alias for strings"
value="import slack.l10n.R as L10nR&#10;" toReformat="false" toShortenFQNames="true">
<context>
<option name="KOTLIN_TOPLEVEL" value="true" />
</context>
</template>
<template name="rslackkit" description="Import alias for SlackKit resources"
value="import slack.uikit.resources.R as SlackKitR&#10;" toReformat="false" toShortenFQNames="true">
<context>
<option name="KOTLIN_TOPLEVEL" value="true" />
</context>
</template>
<template name="rcoreui" description="Import alias for CoreUi resources"
value="import slack.coreui.R as CoreUiR&#10;" toReformat="false" toShortenFQNames="true">
<context>
<option name="KOTLIN_TOPLEVEL" value="true" />
</context>
</template>
<template name="ruikit" description="Import alias for SlackKit/UiKit"
value="import slack.uikit.R as UiKitR&#10;" toReformat="false" toShortenFQNames="true">
<context>
<option name="KOTLIN_TOPLEVEL" value="true" />
</context>
</template>
</templateSet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment