mirror of
https://github.com/YuzuZensai/Minikura.git
synced 2026-01-06 04:32:37 +00:00
✨ feat: environment config patcher
This commit is contained in:
38
plugins/MinikuraEnvironmentConfigPatcher/.gitignore
vendored
Normal file
38
plugins/MinikuraEnvironmentConfigPatcher/.gitignore
vendored
Normal file
@@ -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
|
||||
@@ -0,0 +1,32 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="minikura-environment-config-patcher" type="MavenRunConfiguration" factoryName="Maven" nameIsGenerated="true">
|
||||
<MavenSettings>
|
||||
<option name="myGeneralSettings" />
|
||||
<option name="myRunnerSettings" />
|
||||
<option name="myRunnerParameters">
|
||||
<MavenRunnerParameters>
|
||||
<option name="cmdOptions" />
|
||||
<option name="profiles">
|
||||
<set />
|
||||
</option>
|
||||
<option name="goals">
|
||||
<list>
|
||||
<option value="package" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="multimoduleDir" />
|
||||
<option name="pomFileName" />
|
||||
<option name="profilesMap">
|
||||
<map />
|
||||
</option>
|
||||
<option name="projectsCmdOptionValues">
|
||||
<list />
|
||||
</option>
|
||||
<option name="resolveToWorkspace" value="false" />
|
||||
<option name="workingDirPath" value="$PROJECT_DIR$" />
|
||||
</MavenRunnerParameters>
|
||||
</option>
|
||||
</MavenSettings>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>cafe.kirameki</groupId>
|
||||
<artifactId>minikura-environment-config-patcher</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>2.0.20</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<mainClass>MainKt</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>MainKt</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<transformers>
|
||||
<transformer>
|
||||
<mainClass>MainKt</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>mavenCentral</id>
|
||||
<url>https://repo1.maven.org/maven2/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<version>2.0.20</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>junit-platform-launcher</artifactId>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<kotlin.code.style>official</kotlin.code.style>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
|
||||
</properties>
|
||||
</project>
|
||||
126
plugins/MinikuraEnvironmentConfigPatcher/pom.xml
Normal file
126
plugins/MinikuraEnvironmentConfigPatcher/pom.xml
Normal file
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>cafe.kirameki</groupId>
|
||||
<artifactId>minikura-environment-config-patcher</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<kotlin.code.style>official</kotlin.code.style>
|
||||
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>mavenCentral</id>
|
||||
<url>https://repo1.maven.org/maven2/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>2.0.20</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<mainClass>MainKt</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>MainKt</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>MainKt</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<version>2.0.20</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>2.0.20</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
147
plugins/MinikuraEnvironmentConfigPatcher/src/main/kotlin/Main.kt
Normal file
147
plugins/MinikuraEnvironmentConfigPatcher/src/main/kotlin/Main.kt
Normal file
@@ -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<String, Any>()
|
||||
|
||||
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<MutableMap<String, Any>>() } as MutableList<MutableMap<String, Any>>
|
||||
|
||||
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<String> {
|
||||
val regex = "(?<!\\\\)\\|".toRegex()
|
||||
return value.split(regex).map { it.replace("\\|", "|") }
|
||||
}
|
||||
|
||||
fun parseValue(value: String): Any {
|
||||
return when {
|
||||
value.equals("true", ignoreCase = true) -> 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<Map<String, Any>> {
|
||||
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<String, Int?, String> {
|
||||
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, Any>): 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<Map<String, Any>>(file.readText()).toMutableMap()
|
||||
|
||||
for ((keyPath, value) in replacements) {
|
||||
applyReplacement(yamlData, keyPath.split("."), value)
|
||||
}
|
||||
|
||||
return yamlDumper.dump(yamlData)
|
||||
}
|
||||
|
||||
fun applyReplacement(data: MutableMap<String, Any>, keys: List<String>, 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<String, Any>
|
||||
?: mutableMapOf<String, Any>().also { data[key] = it }
|
||||
applyReplacement(nestedData, keys.drop(1), value)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user