Skip to content

Instantly share code, notes, and snippets.

@rayworks
Created April 23, 2025 03:30
Show Gist options
  • Save rayworks/7d690b3c5b6a4e198a4965f417b41725 to your computer and use it in GitHub Desktop.
Save rayworks/7d690b3c5b6a4e198a4965f417b41725 to your computer and use it in GitHub Desktop.
Image resource cleaner for Android project
import java.io.File
import java.util.regex.Pattern
import kotlin.system.exitProcess
fun findMatches(directory: File, pattern: Pattern, extensions: List<String>): Set<String> {
val result = mutableSetOf<String>()
directory.walkTopDown()
.filter { it.isFile && it.extension in extensions }
.forEach { file ->
file.readLines().forEach { line ->
val matcher = pattern.matcher(line)
while (matcher.find()) {
val element = matcher.group()
result.add(element.substring(element.lastIndexOf('.') + 1))
}
val pat = Pattern.compile("@drawable/[0-9a-zA-Z_]*")
val xmlMatcher = pat.matcher(line)
while (xmlMatcher.find()) {
val element = xmlMatcher.group()
println("found in xml : $element")
result.add(element.substring(element.lastIndexOf('/') + 1))
}
}
}
return result
}
fun cleanFiles(directory: File, filesInUse: Set<String>, deleted: Boolean = true): List<File> {
var size: Long = 0L
val result = mutableListOf<File>()
directory.walkTopDown()
.filter {
it.isFile && it.parentFile.isDirectory && it.parentFile.name.contains("drawable")
&& it.extension in setOf("png", "jpg", "jpeg", "webp")
}
.forEach { file ->
if (!filesInUse.contains(file.nameWithoutExtension)) {
println("file ${file.absolutePath} is NOT in use")
result.add(file)
size += file.length()
if (deleted) file.delete()
}
}
println("Cleaned size : ${size / 1024} KB")
return result
}
fun main(args: Array<String>) {
if (args.isEmpty()) {
System.err.println("Usage: prog <app_folder>")
exitProcess(1)
}
println(">>> searching... ${args.joinToString(",")}")
val srcPath = args[0]
println("working dir: $srcPath")
val targetFile = File(srcPath)
val pattern = Pattern.compile("R\\.drawable\\.[0-9a-zA-Z_]*")
val extensions = listOf("java", "kt", "gradle", "gradle.kts", "xml")
val res = findMatches(targetFile, pattern, extensions)
println("Matched Result: ${res.size}")
println("Matched Result: \n${res.joinToString("\n")}")
val filesToDelete = cleanFiles(targetFile, res)
println("To be Deleted file size : ${filesToDelete.size}")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment