2024-05-15 12:33:10 +00:00
|
|
|
import kotlin.collections.LinkedHashSet
|
2024-05-04 17:57:45 +00:00
|
|
|
import java.io.File
|
|
|
|
|
2024-05-15 12:33:10 +00:00
|
|
|
val templateEnding = Regex("\\.ktstemplate(\\.[^\\.]*)*$")
|
|
|
|
val templateOnlyEnding = Regex("\\.ktstemplate")
|
2024-05-04 17:57:45 +00:00
|
|
|
val singleArgumentRegex = Regex("^[\\w\\d]+$")
|
|
|
|
val splitterRegex = Regex("[ ]*=[ ]*")
|
|
|
|
|
2024-05-15 12:33:10 +00:00
|
|
|
sealed interface Mode {
|
|
|
|
fun filesList(folder: File): Sequence<File>
|
|
|
|
|
|
|
|
data object Recursive : Mode {
|
|
|
|
override fun filesList(folder: File): Sequence<File> {
|
|
|
|
return sequence {
|
|
|
|
val folders = mutableListOf<File>()
|
|
|
|
folders.add(folder)
|
|
|
|
while (folders.isNotEmpty()) {
|
|
|
|
val currentFolder = folders.removeAt(0)
|
|
|
|
currentFolder.listFiles().toList().forEach {
|
|
|
|
when {
|
|
|
|
it.isFile -> yield(it)
|
|
|
|
it.isDirectory -> folders.add(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
data object Plain : Mode {
|
|
|
|
override fun filesList(folder: File): Sequence<File> {
|
|
|
|
return sequence {
|
|
|
|
folder.listFiles().forEach {
|
|
|
|
yield(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var mode: Mode = Mode.Recursive
|
|
|
|
|
|
|
|
val folders = args.mapNotNull {
|
|
|
|
if (it.startsWith("-")) { // assume some arg
|
|
|
|
when (it) {
|
|
|
|
"--plain" -> mode = Mode.Plain
|
|
|
|
"--recursive" -> mode = Mode.Recursive
|
|
|
|
"--help" -> {
|
|
|
|
println("[...pathnames] [--recursive] [--plain]")
|
|
|
|
println("...pathnames - Pass any count of folder or files paths")
|
|
|
|
println("--recursive - (default) Use recursive visiting of folders for each path in pathnames")
|
|
|
|
println("--plain - (default) Use plain (non-recursive) visiting of folders for each path in pathnames")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
null
|
|
|
|
} else {
|
|
|
|
File(it)
|
|
|
|
}
|
|
|
|
}.ifEmpty {
|
|
|
|
listOf(File("./"))
|
|
|
|
}
|
2024-05-04 17:57:45 +00:00
|
|
|
|
|
|
|
fun String.replaceVariables(variables: Map<String, String>): String {
|
|
|
|
var currentLine = this
|
|
|
|
variables.forEach { (k, v) ->
|
|
|
|
currentLine = currentLine.replace("\${${k}}", v)
|
|
|
|
if (k.matches(singleArgumentRegex)) {
|
|
|
|
currentLine = currentLine.replace("\$${k}", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return currentLine
|
|
|
|
}
|
|
|
|
|
2024-05-15 12:33:10 +00:00
|
|
|
fun generateFromTemplate(folder: File, file: File) {
|
|
|
|
val targetFile = File(folder, file.name.replace(templateOnlyEnding, ""))
|
2024-05-04 17:57:45 +00:00
|
|
|
|
|
|
|
val variables = mutableMapOf<String, String>()
|
|
|
|
var writeVariables = true
|
|
|
|
var text = ""
|
2024-05-15 12:33:10 +00:00
|
|
|
|
2024-05-04 17:57:45 +00:00
|
|
|
file.readLines().forEach { line ->
|
|
|
|
when {
|
|
|
|
writeVariables && line.startsWith("#") -> {
|
|
|
|
writeVariables = false
|
|
|
|
}
|
|
|
|
writeVariables -> {
|
|
|
|
val splitted = line.split(splitterRegex)
|
|
|
|
if (splitted.size > 1) {
|
|
|
|
val k = splitted[0]
|
|
|
|
val v = splitted[1].replaceVariables(variables)
|
|
|
|
variables[k] = v
|
|
|
|
}
|
|
|
|
return@forEach
|
|
|
|
}
|
|
|
|
}
|
|
|
|
text += line.let {
|
|
|
|
line.replaceVariables(variables) + "\n"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
targetFile.writeText(text)
|
2024-05-15 12:33:10 +00:00
|
|
|
println("${targetFile.absolutePath} has been recreated")
|
2024-05-04 17:57:45 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 12:33:10 +00:00
|
|
|
if (args.none { it == "--help" }) {
|
|
|
|
folders.forEach { folder ->
|
|
|
|
mode.filesList(folder).forEach { file ->
|
|
|
|
if (file.name.contains(templateEnding)) {
|
|
|
|
generateFromTemplate(file.parentFile, file)
|
|
|
|
}
|
|
|
|
}
|
2024-05-04 17:57:45 +00:00
|
|
|
}
|
|
|
|
}
|