Last active
February 26, 2023 17:42
-
-
Save MathieuLorber/4161bbeb5751d2ec73d5971d347b1c42 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
implementation("org.yaml:snakeyaml:1.33") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package templatecloner.utils | |
import com.google.common.io.CharStreams | |
import java.io.InputStream | |
import java.io.InputStreamReader | |
import java.time.ZoneId | |
import org.yaml.snakeyaml.Yaml | |
object YamlParser { | |
fun yamlToMap(vararg files: InputStream): Map<String, String> = | |
yamlFilesToPairs(*files) | |
.mapNotNull { pair -> pair.second?.let { pair.first to it } } | |
.toMap() | |
fun yamlToMapWithNull(vararg files: InputStream, zoneId: ZoneId): Map<String, String?> = | |
yamlFilesToPairs(*files).toMap() | |
fun getListByKeyPrefix(map: Map<String, String>, keyPrefix: String) = | |
map.keys.filter { it.startsWith(keyPrefix) }.map { map.getValue(it) } | |
private fun yamlFilesToPairs(vararg files: InputStream): List<Pair<String, String?>> = | |
files | |
.map { CharStreams.toString(InputStreamReader(it, Charsets.UTF_8)) } | |
.map { Yaml().load<Map<String, Any>>(it) } | |
.flatMap { flattenConf(it) } | |
// we want to delete the duplicates | |
// but distinct() will keep the first item for each key, and we want the last | |
// so we reverse, distinct, and re-reverse | |
.reversed() | |
// toMap() would have removed the duplicates, but with distinct we're sure of the order | |
.distinct() | |
.reversed() | |
// replace system env vars | |
.map { | |
it.first to | |
it.second | |
?.replace("\\$\\{[^}]*}".toRegex()) { | |
System.getenv(it.value.drop(2).dropLast(1)) ?: "" | |
} | |
?.let { it.ifEmpty { null } } | |
} | |
private fun flattenConf(map: Map<String, Any>): List<Pair<String, String?>> = | |
map.keys.flatMap { key -> | |
val value = map[key] | |
when (value) { | |
// TODO null or not here ?? (if use getValue is useless) | |
null -> listOf(key to null) | |
is Boolean, | |
is Int, | |
is Long, | |
is String -> listOf(key to "$value") | |
is Map<*, *> -> | |
flattenConf(value as Map<String, Any>).map { | |
(key + "." + it.first) to it.second | |
} | |
is List<*> -> | |
value.flatMapIndexed { index, v -> flattenConf(mapOf("$key[$index]" to v as Any)) } | |
else -> listOf(key to "$value") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment