From 37b3feea3aab91b1ae8057edfa3163074db3a65d Mon Sep 17 00:00:00 2001 From: Yuzu Date: Thu, 2 Jan 2025 11:13:12 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20environment=20config=20patc?= =?UTF-8?q?her?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.gitignore | 38 +++++ ...inikura-environment-config-patcher.run.xml | 32 ++++ .../dependency-reduced-pom.xml | 138 ++++++++++++++++ .../MinikuraEnvironmentConfigPatcher/pom.xml | 126 +++++++++++++++ .../src/main/kotlin/Main.kt | 147 ++++++++++++++++++ 5 files changed, 481 insertions(+) create mode 100644 plugins/MinikuraEnvironmentConfigPatcher/.gitignore create mode 100644 plugins/MinikuraEnvironmentConfigPatcher/.run/minikura-environment-config-patcher.run.xml create mode 100644 plugins/MinikuraEnvironmentConfigPatcher/dependency-reduced-pom.xml create mode 100644 plugins/MinikuraEnvironmentConfigPatcher/pom.xml create mode 100644 plugins/MinikuraEnvironmentConfigPatcher/src/main/kotlin/Main.kt diff --git a/plugins/MinikuraEnvironmentConfigPatcher/.gitignore b/plugins/MinikuraEnvironmentConfigPatcher/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/plugins/MinikuraEnvironmentConfigPatcher/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/plugins/MinikuraEnvironmentConfigPatcher/.run/minikura-environment-config-patcher.run.xml b/plugins/MinikuraEnvironmentConfigPatcher/.run/minikura-environment-config-patcher.run.xml new file mode 100644 index 0000000..a23a18c --- /dev/null +++ b/plugins/MinikuraEnvironmentConfigPatcher/.run/minikura-environment-config-patcher.run.xml @@ -0,0 +1,32 @@ + + + + + + + + \ No newline at end of file diff --git a/plugins/MinikuraEnvironmentConfigPatcher/dependency-reduced-pom.xml b/plugins/MinikuraEnvironmentConfigPatcher/dependency-reduced-pom.xml new file mode 100644 index 0000000..f97a89d --- /dev/null +++ b/plugins/MinikuraEnvironmentConfigPatcher/dependency-reduced-pom.xml @@ -0,0 +1,138 @@ + + + 4.0.0 + cafe.kirameki + minikura-environment-config-patcher + 1.0-SNAPSHOT + + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + 2.0.20 + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + MainKt + + + + maven-jar-plugin + 3.2.2 + + + + MainKt + + + + + + maven-shade-plugin + 3.4.1 + + + package + + shade + + + true + + + MainKt + + + + + + + + + + + mavenCentral + https://repo1.maven.org/maven2/ + + + + + org.jetbrains.kotlin + kotlin-test-junit5 + 2.0.20 + test + + + kotlin-test + org.jetbrains.kotlin + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + junit-platform-launcher + org.junit.platform + + + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + + + junit-jupiter-params + org.junit.jupiter + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + + + + official + UTF-8 + 1.8 + + diff --git a/plugins/MinikuraEnvironmentConfigPatcher/pom.xml b/plugins/MinikuraEnvironmentConfigPatcher/pom.xml new file mode 100644 index 0000000..821437b --- /dev/null +++ b/plugins/MinikuraEnvironmentConfigPatcher/pom.xml @@ -0,0 +1,126 @@ + + + 4.0.0 + + cafe.kirameki + minikura-environment-config-patcher + 1.0-SNAPSHOT + + + UTF-8 + official + 1.8 + + + + + mavenCentral + https://repo1.maven.org/maven2/ + + + + + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + 2.0.20 + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + MainKt + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + MainKt + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + true + + + MainKt + + + + + + + + + + + + org.jetbrains.kotlin + kotlin-test-junit5 + 2.0.20 + test + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + + + org.jetbrains.kotlin + kotlin-stdlib + 2.0.20 + + + org.yaml + snakeyaml + 2.0 + + + + \ No newline at end of file diff --git a/plugins/MinikuraEnvironmentConfigPatcher/src/main/kotlin/Main.kt b/plugins/MinikuraEnvironmentConfigPatcher/src/main/kotlin/Main.kt new file mode 100644 index 0000000..2cce665 --- /dev/null +++ b/plugins/MinikuraEnvironmentConfigPatcher/src/main/kotlin/Main.kt @@ -0,0 +1,147 @@ +import org.yaml.snakeyaml.DumperOptions +import org.yaml.snakeyaml.LoaderOptions +import org.yaml.snakeyaml.Yaml +import org.yaml.snakeyaml.constructor.Constructor +import java.io.File + +const val PREFIX = "minikura-environment-config-patcher" + +fun main() { + val envVars = System.getenv() + + val patchConfigVars = envVars.filter { it.key.startsWith("PATCH_YAML_CONFIG_") } + + for ((key, value) in patchConfigVars) { + println("[${getCurrentTime()} INFO] [$PREFIX]: Processing $key") + + val lines = splitWithEscapedPipe(value) + if (lines.size < 2) { + println("[${getCurrentTime()} INFO] [$PREFIX]: Skipping. Insufficient data.") + continue + } + + val yamlFilePath = lines[0].trim() + val yamlFile = File(yamlFilePath) + if (!yamlFile.exists()) { + println("[${getCurrentTime()} INFO] [$PREFIX]: Skipping. File does not exist.") + continue + } + + val replacements = mutableMapOf() + + lines.drop(1).forEach { line -> + val keyValue = line.split("=", limit = 2) + if (keyValue.size == 2) { + val key = keyValue[0].trim() + val value = parseValue(keyValue[1].trim()) + + val (baseKey, index, subKey) = parseKeyWithIndex(key) + + if (index != null) { + val arrayData = replacements.computeIfAbsent(baseKey) { mutableListOf>() } as MutableList> + + while (arrayData.size <= index) { + arrayData.add(mutableMapOf()) + } + + val arrayItem = arrayData[index] + arrayItem[subKey] = value + println("[${getCurrentTime()} INFO] [$PREFIX]: Editing key: $baseKey[$index].$subKey") + } else { + replacements[baseKey] = value + println("[${getCurrentTime()} INFO] [$PREFIX]: Editing key: $baseKey") + } + } else { + println("[${getCurrentTime()} WARN] [$PREFIX]: Skipping malformed line.") + } + } + + try { + val updatedYaml = updateYaml(yamlFile, replacements) + yamlFile.writeText(updatedYaml) + println("[${getCurrentTime()} INFO] [$PREFIX]: Successfully updated $yamlFilePath") + } catch (e: Exception) { + println("[${getCurrentTime()} ERROR] [$PREFIX]: Error processing $yamlFilePath. ${e.message}") + } + } + + println("[${getCurrentTime()} INFO] [$PREFIX]: Patch completed") +} + +fun getCurrentTime(): String { + val currentDate = java.time.LocalTime.now() + return currentDate.toString().substring(0, 8) +} + +fun splitWithEscapedPipe(value: String): List { + val regex = "(? true + value.equals("false", ignoreCase = true) -> false + value.startsWith("\"") && value.endsWith("\"") -> value.substring(1, value.length - 1) + value.startsWith("'") && value.endsWith("'") -> value.substring(1, value.length - 1) + value.toIntOrNull() != null -> value.toInt() + value.startsWith("[") && value.endsWith("]") -> parseArray(value) + else -> value + } +} + +fun parseArray(value: String): List> { + val arrayContent = value.substring(1, value.length - 1).trim() + return arrayContent.split(",").map { item -> + val keyValue = item.split("=") + if (keyValue.size == 2) { + keyValue[0].trim() to parseValue(keyValue[1].trim()) + } else { + keyValue[0].trim() to parseValue(keyValue[0].trim()) + } + }.map { mapOf(it) } +} + +fun parseKeyWithIndex(key: String): Triple { + val regex = """([^\[]+)(?:\[(\d+)\])?(\.[^\[]+)*""".toRegex() + val matchResult = regex.matchEntire(key) + return if (matchResult != null) { + val (baseKey, indexStr, subKey) = matchResult.destructured + val index = indexStr.toIntOrNull() + val finalKey = subKey.trimStart('.') + Triple(baseKey, index, finalKey) + } else { + Triple(key, null, "") + } +} + +fun updateYaml(file: File, replacements: Map): String { + val loaderOptions = LoaderOptions() + val yaml = Yaml(Constructor(loaderOptions)) + + val options = DumperOptions().apply { + defaultFlowStyle = DumperOptions.FlowStyle.BLOCK + isPrettyFlow = true + } + val yamlDumper = Yaml(options) + + val yamlData = yaml.load>(file.readText()).toMutableMap() + + for ((keyPath, value) in replacements) { + applyReplacement(yamlData, keyPath.split("."), value) + } + + return yamlDumper.dump(yamlData) +} + +fun applyReplacement(data: MutableMap, keys: List, value: Any) { + val key = keys.first() + if (keys.size == 1) { + println("[${getCurrentTime()} INFO] [$PREFIX]: Editing key: $key") + data[key] = value + } else { + val nestedData = data[key] as? MutableMap + ?: mutableMapOf().also { data[key] = it } + applyReplacement(nestedData, keys.drop(1), value) + } +}