diff options
Diffstat (limited to 'support/arara/source/src/main/kotlin/org/islandoftex/arara/model')
6 files changed, 0 insertions, 826 deletions
diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/AraraException.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/AraraException.kt deleted file mode 100644 index 6bf2d1e617..0000000000 --- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/AraraException.kt +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -package org.islandoftex.arara.model - -/** - * Implements the specific exception model for arara. - * - * @author Island of TeX - * @version 5.0 - * @since 4.0 - */ -class AraraException : Exception { - /** - * The underlying exception, used to hold more details - * on what really happened - */ - val exception: Exception? - - /** - * Constructor. Takes the exception message. - * @param message The exception message. - */ - constructor(message: String) : super(message) { - this.exception = null - } - - /** - * Constructor. Takes the exception message and the underlying exception. - * @param message The exception message. - * @param exception The underlying exception object. - */ - constructor(message: String, exception: Exception) : super(message) { - this.exception = exception - } - - /** - * Constructor. Takes the exception message and the underlying exception. - * @param message The exception message. - * @param throwable The underlying exception as generic throwable. - */ - constructor(message: String, throwable: Throwable) : super(message) { - this.exception = RuntimeException(throwable) - } - - /** - * Checks if there is an underlying exception defined in the current object. - * @return A boolean value indicating if the current object has an - * underlying exception. - */ - fun hasException(): Boolean = exception?.message != null -} diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Evaluator.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Evaluator.kt deleted file mode 100644 index 78b98e709a..0000000000 --- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Evaluator.kt +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -package org.islandoftex.arara.model - -import org.islandoftex.arara.Arara -import org.islandoftex.arara.configuration.AraraSpec -import org.islandoftex.arara.localization.LanguageController -import org.islandoftex.arara.localization.Messages -import org.islandoftex.arara.ruleset.Conditional -import org.islandoftex.arara.utils.Methods -import org.mvel2.templates.TemplateRuntime - -/** - * Implements the evaluator model, on which a conditional can be analyzed and - * processed. - * - * @author Island of TeX - * @version 5.0 - * @since 4.0 - */ -class Evaluator { - // this attribute holds the maximum number of - // loops arara will accept; it's like - // reaching infinity - private val loops: Int = Arara.config[AraraSpec.Execution.maxLoops] - - // the counter for the current execution, it - // helps us keep track of the number of times - // this evaluation has happened, and also to - // prevent potential infinite loops - private var counter: Int = 0 - - // a flag that indicates the - // evaluation to halt regardless - // of the the result - private var halt: Boolean = false - - /** - * Check if a condition is of type if or unless and whether halt - * is set. - * @param type The type to check. - * @param haltCheck The value [halt] should have. - * @return `(type == if || type == unless) && haltCheck` - */ - private fun isIfUnlessAndHalt( - type: Conditional.ConditionalType, - haltCheck: Boolean = true - ): Boolean = - (type == Conditional.ConditionalType.IF || - type == Conditional.ConditionalType.UNLESS) && - halt == haltCheck - - /** - * Only run the evaluation of the conditional including a check whether - * the result needs to be inverted. - * @param conditional The conditional. - * @return The result of the evaluation. - */ - @Throws(AraraException::class, RuntimeException::class) - private fun evaluateCondition(conditional: Conditional): Boolean { - val result = TemplateRuntime.eval("@{ " + conditional.condition + " }", - Methods.getConditionalMethods()) - return if (result is Boolean) { - if (conditional.type == Conditional.ConditionalType.UNLESS || - conditional.type == Conditional.ConditionalType.UNTIL) - !result - else - result - } else { - throw AraraException(messages.getMessage( - Messages.ERROR_EVALUATE_NOT_BOOLEAN_VALUE)) - } - } - - /** - * Evaluate the provided conditional. - * - * @param conditional The conditional object. - * @return A boolean value indicating if the conditional holds. - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @Throws(AraraException::class) - @Suppress("TooGenericExceptionCaught") - fun evaluate(conditional: Conditional): Boolean { - // when in dry-run mode or not evaluating a - // conditional, arara always ignores conditional - // evaluations - if (conditional.type == Conditional.ConditionalType.NONE || - Arara.config[AraraSpec.Execution.dryrun] || - isIfUnlessAndHalt(conditional.type, true)) - return false - else if (isIfUnlessAndHalt(conditional.type, false)) { - halt = true - } - - // check counters and see if the execution - // has reached our concept of infinity, - // thus breaking the cycles - counter++ - return when { - conditional.type === Conditional.ConditionalType.WHILE - && counter > loops -> false - conditional.type === Conditional.ConditionalType.UNTIL - && counter >= loops -> false - else -> { - try { - evaluateCondition(conditional) - } catch (exception: RuntimeException) { - throw AraraException(messages.getMessage(Messages - .ERROR_EVALUATE_COMPILATION_FAILED), - exception) - } - } - } - } - - companion object { - // the application messages obtained from the - // language controller - private val messages = LanguageController - } -} diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Extractor.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Extractor.kt deleted file mode 100644 index ed4d811d22..0000000000 --- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Extractor.kt +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -package org.islandoftex.arara.model - -import java.io.File -import java.io.IOException -import java.nio.charset.Charset -import org.islandoftex.arara.localization.LanguageController -import org.islandoftex.arara.localization.Messages -import org.islandoftex.arara.ruleset.Directive -import org.islandoftex.arara.ruleset.DirectiveUtils -import org.islandoftex.arara.utils.CommonUtils - -/** - * Extractor for directives from the provided main file. - * - * @author Island of TeX - * @version 5.0 - * @since 4.0 - */ -object Extractor { - // the application messages obtained from the - // language controller - private val messages = LanguageController - - /** - * Extracts a list of directives from the provided main file, obtained from - * the configuration controller. - * @param file The file to extract the directives from. - * @param charset The charset of the file. - * @return A list of directives. - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @Throws(AraraException::class) - fun extract(file: File, charset: Charset = Charsets.UTF_8): - List<Directive> { - try { - val content = CommonUtils.preambleContent.toMutableList() - content.addAll(file.readLines(charset)) - return DirectiveUtils.extractDirectives(content) - } catch (ioexception: IOException) { - throw AraraException( - messages.getMessage( - Messages.ERROR_EXTRACTOR_IO_ERROR - ), - ioexception - ) - } - } -} diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/FileType.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/FileType.kt deleted file mode 100644 index e6ed27d51a..0000000000 --- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/FileType.kt +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -package org.islandoftex.arara.model - -import java.util.regex.PatternSyntaxException -import kotlinx.serialization.Serializable -import org.islandoftex.arara.configuration.ConfigurationUtils -import org.islandoftex.arara.localization.LanguageController -import org.islandoftex.arara.localization.Messages -import org.islandoftex.arara.utils.CommonUtils - -/** - * Implements the file type model. - * - * @author Island of TeX - * @version 5.0 - * @since 4.0 - */ -@Serializable -class FileType { - // string representing the - // file extension - var extension: String = INVALID_EXTENSION - get() = CommonUtils.removeKeywordNotNull(field) - private set - // string representing the - // file pattern to be used - // as directive lookup - var pattern: String = INVALID_PATTERN - @Throws(AraraException::class) - get() { - CommonUtils.removeKeywordNotNull(field) - if (field == INVALID_PATTERN) { - field = ConfigurationUtils.defaultFileTypePatterns[extension] - ?: throw AraraException( - LanguageController.getMessage( - Messages.ERROR_FILETYPE_UNKNOWN_EXTENSION, - extension, - CommonUtils.fileTypesList - ) - ) - } - return field - } - private set - - constructor(extension: String, pattern: String) { - this.extension = extension - this.pattern = pattern - - try { - pattern.toPattern() - } catch (e: PatternSyntaxException) { - if (!ConfigurationUtils.defaultFileTypePatterns.containsKey(extension)) - throw AraraException( - LanguageController.getMessage( - Messages.ERROR_FILETYPE_UNKNOWN_EXTENSION, - extension, - CommonUtils.fileTypesList - ) - ) - } - } - - companion object { - /** - * This constant identifies an invalid extension. As unices do not - * allow a forward and Windows does not allow a backward slash, this - * should suffice. - */ - const val INVALID_EXTENSION = "/\\" - /** - * This constant identifies an invalid pattern. This is a opening - * character class which is invalid. - */ - const val INVALID_PATTERN = "[" - } - - /** - * Provides a textual representation of the current file type object. - * @return A string containing a textual representation of the current file - * type object. - */ - override fun toString(): String { - return ".$extension" - } - - /** - * Implements the file type equals method, checking if one file type is - * equal to another. Note that only the file extension is considered. - * @param other The object to be analyzed. - * @return A boolean value indicating if those two objects are equal. - */ - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as FileType - if (extension != other.extension) return false - return true - } - - /** - * Implements the file type hash code. Note that only the file extension is - * considered. - * @return An integer representing the file type hash code. - */ - override fun hashCode(): Int { - return extension.hashCode() - } -} diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Interpreter.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Interpreter.kt deleted file mode 100644 index 49cf40f1a2..0000000000 --- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Interpreter.kt +++ /dev/null @@ -1,375 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -package org.islandoftex.arara.model - -import java.io.File -import kotlin.time.ExperimentalTime -import org.islandoftex.arara.Arara -import org.islandoftex.arara.configuration.AraraSpec -import org.islandoftex.arara.localization.LanguageController -import org.islandoftex.arara.localization.Messages -import org.islandoftex.arara.ruleset.Argument -import org.islandoftex.arara.ruleset.Command -import org.islandoftex.arara.ruleset.Conditional -import org.islandoftex.arara.ruleset.Directive -import org.islandoftex.arara.ruleset.Rule -import org.islandoftex.arara.ruleset.RuleCommand -import org.islandoftex.arara.ruleset.RuleUtils -import org.islandoftex.arara.utils.CommonUtils -import org.islandoftex.arara.utils.DisplayUtils -import org.islandoftex.arara.utils.InterpreterUtils -import org.islandoftex.arara.utils.Methods -import org.mvel2.templates.TemplateRuntime -import org.slf4j.LoggerFactory - -/** - * Interprets the list of directives. - * - * @author Island of TeX - * @version 5.0 - * @since 4.0 - */ -class Interpreter( - /** - * The list of directives to be interpreted and evaluated. - */ - val directives: List<Directive> -) { - /** - * Exception class to represent that the interpreter should stop for some - * reason - */ - private class HaltExpectedException(msg: String) : Exception(msg) - - /** - * Gets the rule according to the provided directive. - * - * @param directive The provided directive. - * @return The absolute canonical path of the rule, given the provided - * directive. - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @Throws(AraraException::class) - private fun getRule(directive: Directive): File { - return InterpreterUtils.buildRulePath(directive.identifier) - ?: throw AraraException( - messages.getMessage( - Messages.ERROR_INTERPRETER_RULE_NOT_FOUND, - directive.identifier, - "(" + CommonUtils.allRulePaths - .joinToString("; ") + ")" - ) - ) - } - - // TODO: in the following, extract the printing into the higher level - // function - /** - * "Run" a boolean return value - * @param value The boolean. - * @param conditional The conditional to print in dry-run mode. - * @param authors The authors of the rule. - * @return Returns [value] - */ - private fun runBoolean( - value: Boolean, - conditional: Conditional, - authors: List<String> - ): Boolean { - logger.info(messages.getMessage(Messages.LOG_INFO_BOOLEAN_MODE, - value.toString())) - - if (Arara.config[AraraSpec.Execution.dryrun]) { - DisplayUtils.printAuthors(authors) - DisplayUtils.wrapText(messages.getMessage(Messages - .INFO_INTERPRETER_DRYRUN_MODE_BOOLEAN_MODE, - value)) - DisplayUtils.printConditional(conditional) - } - - return value - } - - /** - * Run a command - * @param command The command to run. - * @param conditional The conditional applied to the run (only for printing). - * @param authors The rule authors (only for printing). - * @param ruleCommandExitValue The exit value of the rule command. - * @return Success of the execution. - * @throws AraraException Execution failed. - */ - @ExperimentalTime - @Throws(AraraException::class) - @Suppress("TooGenericExceptionCaught") - private fun runCommand( - command: Command, - conditional: Conditional, - authors: List<String>, - ruleCommandExitValue: String? - ): Boolean { - logger.info(messages.getMessage(Messages.LOG_INFO_SYSTEM_COMMAND, - command)) - var success = true - - if (!Arara.config[AraraSpec.Execution.dryrun]) { - val code = InterpreterUtils.run(command) - val check: Any = try { - val context = mapOf<String, Any>("value" to code) - TemplateRuntime.eval( - "@{ " + (ruleCommandExitValue ?: "value == 0") + " }", - context) - } catch (exception: RuntimeException) { - throw AraraException(CommonUtils.ruleErrorHeader + - messages.getMessage(Messages - .ERROR_INTERPRETER_EXIT_RUNTIME_ERROR), - exception) - } - - success = if (check is Boolean) { - check - } else { - throw AraraException( - CommonUtils.ruleErrorHeader + messages.getMessage( - Messages.ERROR_INTERPRETER_WRONG_EXIT_CLOSURE_RETURN - ) - ) - } - } else { - DisplayUtils.printAuthors(authors) - DisplayUtils.wrapText(messages.getMessage( - Messages.INFO_INTERPRETER_DRYRUN_MODE_SYSTEM_COMMAND, - command)) - DisplayUtils.printConditional(conditional) - } - - return success - } - - /** - * Converts the command evaluation result to a flat list. - * @param result The result - * @return A flat list. - */ - private fun resultToList(result: Any) = if (result is List<*>) { - CommonUtils.flatten(result) - } else { - listOf(result) - } - - /** - * Execute a command. - * @param command The command to evaluate. - * @param conditional Under which condition to execute. - * @param rule The rule (only passed for output purposes). - * @param parameters The parameters for evaluation - * @throws AraraException Running the command failed. - */ - @ExperimentalTime - @Throws(AraraException::class) - @Suppress("TooGenericExceptionCaught", "ThrowsCount") - private fun executeCommand( - command: RuleCommand, - conditional: Conditional, - rule: Rule, - parameters: Map<String, Any> - ) { - val result: Any = try { - TemplateRuntime.eval(command.command!!, parameters) - } catch (exception: RuntimeException) { - throw AraraException(CommonUtils.ruleErrorHeader + - messages.getMessage(Messages - .ERROR_INTERPRETER_COMMAND_RUNTIME_ERROR), - exception) - } - - // TODO: check nullability - resultToList(result).filter { it.toString().isNotBlank() } - .forEach { current -> - DisplayUtils.printEntry(rule.name, command.name - ?: messages.getMessage(Messages - .INFO_LABEL_UNNAMED_TASK)) - - val success = when (current) { - is Boolean -> runBoolean(current, conditional, - rule.authors) - is Command -> runCommand(current, conditional, - rule.authors, command.exit) - else -> TODO("error: this should not happen" + - "we are only supporting boolean + command") - } - - DisplayUtils.printEntryResult(success) - - if (Arara.config[AraraSpec.Execution.haltOnErrors] && !success) - // TODO: localize - throw HaltExpectedException("Command failed") - - // TODO: document this key - val haltKey = "arara:${Arara.config[AraraSpec - .Execution.reference].name}:halt" - if (Session.contains(haltKey)) { - Arara.config[AraraSpec.Execution.status] = - Session[haltKey].toString().toInt() - // TODO: localize - throw HaltExpectedException("User requested halt") - } - } - } - - /** - * Executes each directive, throwing an exception if something bad has - * happened. - * - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @ExperimentalTime - @Throws(AraraException::class) - @Suppress("NestedBlockDepth") - fun execute() { - for (directive in directives) { - logger.info(messages.getMessage(Messages.LOG_INFO_INTERPRET_RULE, - directive.identifier)) - - Arara.config[AraraSpec.Execution.file] = - directive.parameters.getValue("reference") as File - val file = getRule(directive) - - logger.info(messages.getMessage(Messages.LOG_INFO_RULE_LOCATION, - file.parent)) - - Arara.config[AraraSpec.Execution.InfoSpec.ruleId] = - directive.identifier - Arara.config[AraraSpec.Execution.InfoSpec.rulePath] = - file.parent - Arara.config[AraraSpec.Execution.DirectiveSpec.lines] = - directive.lineNumbers - - // parse the rule identified by the directive - // (may throw an exception) - val rule = RuleUtils.parseRule(file, directive.identifier) - val parameters = parseArguments(rule, directive) - .plus(Methods.getRuleMethods()) - - val evaluator = Evaluator() - - var available = true - if (InterpreterUtils.runPriorEvaluation(directive.conditional)) { - available = evaluator.evaluate(directive.conditional) - } - - // if this directive is conditionally disabled, skip - if (!available) continue - // if not execute the commands associated with the directive - do { - rule.commands.forEach { command -> - try { - executeCommand(command, directive.conditional, rule, parameters) - } catch (_: HaltExpectedException) { - // if the user uses the halt rule to trigger - // a halt, this will be raised - return - } - } - } while (evaluator.evaluate(directive.conditional)) - } - } - - /** - * Parses the rule arguments against the provided directive. - * - * @param rule The rule object. - * @param directive The directive. - * @return A map containing all arguments resolved according to the - * directive parameters. - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @Throws(AraraException::class) - private fun parseArguments(rule: Rule, directive: Directive): - Map<String, Any> { - val arguments = rule.arguments - val unknown = CommonUtils.getUnknownKeys(directive.parameters, - arguments).minus("reference") - if (unknown.isNotEmpty()) - throw AraraException(CommonUtils.ruleErrorHeader + - messages.getMessage( - Messages.ERROR_INTERPRETER_UNKNOWN_KEYS, - "(" + unknown.joinToString(", ") + ")")) - - val resolvedArguments = mutableMapOf<String, Any>() - resolvedArguments["reference"] = directive.parameters - .getValue("reference") - - val context = mapOf( - "parameters" to directive.parameters, - "reference" to directive.parameters.getValue("reference") - ).plus(Methods.getRuleMethods()) - - arguments.forEach { argument -> - resolvedArguments[argument.identifier!!] = processArgument(argument, - directive.parameters.containsKey(argument.identifier!!), - context) - } - - return resolvedArguments - } - - /** - * Process a single argument and return the evaluated result. - * @param argument The argument to process. - * @param idInDirectiveParams Whether the argument's identifier is - * contained in the directive's parameters field. - * @param context The context for the evaluation. - * @return The result of the evaluation. - * @throws AraraException The argument could not be processed. - */ - @Throws(AraraException::class) - @Suppress("TooGenericExceptionCaught", "ThrowsCount") - private fun processArgument( - argument: Argument, - idInDirectiveParams: Boolean, - context: Map<String, Any> - ): Any { - if (argument.isRequired && !idInDirectiveParams) - throw AraraException(CommonUtils.ruleErrorHeader + - messages.getMessage( - Messages.ERROR_INTERPRETER_ARGUMENT_IS_REQUIRED, - argument.identifier!!)) - - var ret = argument.default?.let { - try { - TemplateRuntime.eval(it, context) - } catch (exception: RuntimeException) { - throw AraraException(CommonUtils.ruleErrorHeader + - messages.getMessage(Messages - .ERROR_INTERPRETER_DEFAULT_VALUE_RUNTIME_ERROR), - exception) - } - } ?: "" - - if (argument.flag != null && idInDirectiveParams) { - ret = try { - TemplateRuntime.eval(argument.flag!!, context) - } catch (exception: RuntimeException) { - throw AraraException(CommonUtils.ruleErrorHeader + messages - .getMessage(Messages - .ERROR_INTERPRETER_FLAG_RUNTIME_EXCEPTION), - exception) - } - } - - return ret - } - - companion object { - // the application messages obtained from the - // language controller - private val messages = LanguageController - - // the class logger obtained from - // the logger factory - private val logger = LoggerFactory.getLogger(Interpreter::class.java) - } -} diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Session.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Session.kt deleted file mode 100644 index c2093429e1..0000000000 --- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/model/Session.kt +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -package org.islandoftex.arara.model - -import org.islandoftex.arara.localization.LanguageController -import org.islandoftex.arara.localization.Messages - -/** - * Implements the session. - * - * This class wraps a map that holds the execution session, that is, a dirty - * maneuver to exchange pretty much any data between commands and even rules. - * - * @author Island of TeX - * @version 5.0 - * @since 4.0 - */ -object Session { - // the application messages obtained from the - // language controller - private val messages = LanguageController - - // the session map which holds the execution session; - // the idea here is to provide wrappers to the map - // methods, so it could be easily manipulated - private val map = mutableMapOf<String, Any>() - - /** - * Gets the object indexed by the provided key from the session. This method - * holds the map method of the very same name. - * - * @param key The provided key. - * @return The object indexed by the provided key. - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @Throws(AraraException::class) - operator fun get(key: String): Any { - return if (contains(key)) { - map.getValue(key) - } else { - throw AraraException( - messages.getMessage( - Messages.ERROR_SESSION_OBTAIN_UNKNOWN_KEY, - key - ) - ) - } - } - - /** - * Inserts (or overwrites) the object indexed by the provided key into the - * session. This method holds the map method of the very same name. - * - * @param key The provided key. - * @param value The value to be inserted. - */ - fun put(key: String, value: Any) { - map[key] = value - } - - /** - * Removes the entry indexed by the provided key from the session. This method - * holds the map method of the same name. - * - * @param key The provided key. - * @throws AraraException Something wrong happened, to be caught in the - * higher levels. - */ - @Throws(AraraException::class) - fun remove(key: String) { - if (contains(key)) { - map.remove(key) - } else { - throw AraraException( - messages.getMessage( - Messages.ERROR_SESSION_REMOVE_UNKNOWN_KEY, - key - ) - ) - } - } - - /** - * Checks if the provided key exists in the session. - * - * @param key The provided key. - * @return A boolean value indicating if the provided key exists in the - * session. - */ - operator fun contains(key: String): Boolean = map.containsKey(key) - - /** - * Clears the session (map). This method, as usual, holds the map method of - * the same name. - */ - fun clear() = map.clear() - - /** - * Update the environment variables stored in the session. - * - * @param additionFilter Which environment variables to include. You can - * filter their names (the string parameter) but not their values. By - * default all values will be added. - * @param removalFilter Which environment variables to remove beforehand. - * By default all values will be removed. - */ - fun updateEnvironmentVariables( - additionFilter: (String) -> Boolean = { true }, - removalFilter: (String) -> Boolean = { true } - ) { - // remove all current environment variables to clean up the session - map.filterKeys { it.startsWith("environment:") } - .filterKeys(removalFilter) - .forEach { remove(it.key) } - // add all relevant new environment variables - System.getenv().filterKeys(additionFilter) - .forEach { map["environment:${it.key}"] = it.value } - } -} |