improve function resolve
This commit is contained in:
parent
c2fc62e13a
commit
bfc459b667
2 changed files with 26 additions and 32 deletions
|
@ -69,6 +69,7 @@ fun hostUserHome(): String = System.getProperty("user.home") + fileSeparator()
|
||||||
fun String.escapeAndEncloseByDoubleQuoteForShell(): String {
|
fun String.escapeAndEncloseByDoubleQuoteForShell(): String {
|
||||||
return "\"" + this.escapeForShell() + "\""
|
return "\"" + this.escapeForShell() + "\""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.escapeForShell(): String {
|
fun String.escapeForShell(): String {
|
||||||
// see https://www.shellscript.sh/escape.html
|
// see https://www.shellscript.sh/escape.html
|
||||||
return this.escapeBackslash().escapeBacktick().escapeDoubleQuote().escapeDollar()
|
return this.escapeBackslash().escapeBacktick().escapeDoubleQuote().escapeDollar()
|
||||||
|
@ -123,40 +124,33 @@ fun getResourceResolved(path: String, values: Map<String, String>): String {
|
||||||
/**
|
/**
|
||||||
* Returns a String in which placeholders (e.g. $var or ${var}) are replaced by the specified values.
|
* Returns a String in which placeholders (e.g. $var or ${var}) are replaced by the specified values.
|
||||||
* This function can be used for resolving templates at RUNTIME (e.g. for templates read from files) as
|
* This function can be used for resolving templates at RUNTIME (e.g. for templates read from files) as
|
||||||
* for compile time this functionality is already provided by the compiler out-of-the-box, of course.
|
* for compile time this functionality is already provided by the compiler out-of-the-box.
|
||||||
|
*
|
||||||
* For a usage example see the corresponding test.
|
* For a usage example see the corresponding test.
|
||||||
*/
|
*/
|
||||||
fun String.resolve(
|
fun String.resolve(values: Map<String, String>): String {
|
||||||
values: Map<String, String>
|
|
||||||
): String {
|
|
||||||
var text = this
|
|
||||||
|
|
||||||
// replace all simple variable patterns (i.e. without curly braces)
|
val result = StringBuilder()
|
||||||
val matcherSimple = Regex("\\$([a-zA-Z_][a-zA-Z_0-9]*)")
|
|
||||||
var match = matcherSimple.find(text)
|
val matcherSimple = "\\$([a-zA-Z_][a-zA-Z_0-9]*)" // simple placeholder e.g. $var
|
||||||
while (match != null) {
|
val matcherWithBraces = "\\$\\{([a-zA-Z_][a-zA-Z_0-9]*)}" // placeholder within braces e.g. ${var}
|
||||||
val variableName = match.groupValues.get(1)
|
|
||||||
val newText = values.get(variableName)
|
// match a placeholder (like $var or ${var}) or ${'$'} (escaped dollar)
|
||||||
require(newText != null, { "No value found for: " + variableName })
|
val allMatches = Regex("$matcherSimple|$matcherWithBraces|\\\$\\{'(\\\$)'}").findAll(this)
|
||||||
text = text.replace("\$$variableName", newText)
|
|
||||||
match = matcherSimple.find(text)
|
var position = 0
|
||||||
|
allMatches.forEach {
|
||||||
|
val range = it.range
|
||||||
|
val placeholder = this.substring(range)
|
||||||
|
val variableName = it.groups.filterNotNull()[1].value
|
||||||
|
val newText =
|
||||||
|
if ("\${'\$'}" == placeholder) "$"
|
||||||
|
else values[variableName] ?: throw IllegalArgumentException("Could not resolve placeholder $placeholder")
|
||||||
|
result.append(this.substring(position, range.start)).append(newText)
|
||||||
|
position = range.last + 1
|
||||||
}
|
}
|
||||||
|
result.append(this.substring(position))
|
||||||
// replace all variables within curly braces
|
return result.toString()
|
||||||
val matcherWithBraces = Regex("\\$\\{([a-zA-Z_][a-zA-Z_0-9]*)}")
|
|
||||||
match = matcherWithBraces.find(text)
|
|
||||||
while (match != null) {
|
|
||||||
val variableName = match.groupValues.get(1)
|
|
||||||
val newText = values.get(variableName)
|
|
||||||
require(newText != null, { "No value found for: " + variableName })
|
|
||||||
text = text.replace("\${$variableName}", newText)
|
|
||||||
match = matcherWithBraces.find(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace escaped dollars
|
|
||||||
text = text.replace("\${'$'}", "\$")
|
|
||||||
|
|
||||||
return text
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -120,6 +120,6 @@ internal class UtilsKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(e.message, "No value found for: var3")
|
assertEquals(e.message, "Could not resolve placeholder \${var3}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue