From bb32461a1284a2daa97355cd227036ecf35747be Mon Sep 17 00:00:00 2001 From: hinerm Date: Wed, 18 Sep 2024 15:20:39 -0500 Subject: [PATCH] Execute global directives before runtime config Global directives are necessarily runtime-agnostic, and may have impact on building the subsequent runtimes (e.g. in the case of applying updates and then building a classpath that includes those updated libraries). Thus we split directive execution into two phases: first global directives, then runtime directives (after runtimes have been configured). Closes https://github.com/apposed/jaunch/issues/47 Closes https://github.com/apposed/jaunch/issues/55 --- src/commonMain/kotlin/main.kt | 66 +++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/commonMain/kotlin/main.kt b/src/commonMain/kotlin/main.kt index c8d9b04..3f7e0c5 100644 --- a/src/commonMain/kotlin/main.kt +++ b/src/commonMain/kotlin/main.kt @@ -75,9 +75,21 @@ fun main(args: Array) { applyModeHints(config.modes, hints, vars) - val runtimes = configureRuntimes(config, configDir, hints, vars) val (launchDirectives, configDirectives) = calculateDirectives(config, hints, vars) + // Declare the global (runtime-agnostic) directives. + val globalDirectiveFunctions: DirectivesMap = mutableMapOf( + "help" to { _ -> help(exeFile, programName, supportedOptions) }, + "apply-update" to { _ -> applyUpdate(appDir, appDir / "update") } + ) + + // Execute the global directives (e.g. applying updates) before configuring + // runtimes (e.g. building classpaths) + val nonGlobalDirectives = executeGlobalDirectives(globalDirectiveFunctions, + configDirectives, userArgs) + + val runtimes = configureRuntimes(config, configDir, hints, vars) + debugBanner("BUILDING ARGUMENT LISTS") // Ensure that the user arguments meet our expectations. @@ -96,16 +108,9 @@ fun main(args: Array) { vars.interpolateInto(programArgs.main) } - // Declare the global (runtime-agnostic) directives. - val globalDirectiveFunctions: DirectivesMap = mutableMapOf( - "help" to { _ -> help(exeFile, programName, supportedOptions) }, - "apply-update" to { _ -> applyUpdate(appDir, appDir / "update") } - ) - // Finally, execute all the directives! \^_^/ - executeDirectives(globalDirectiveFunctions, - configDirectives, launchDirectives, - runtimes, userArgs, argsInContext) + executeDirectives(nonGlobalDirectives, launchDirectives, runtimes, userArgs, + argsInContext) } // -- Program flow functions -- @@ -490,8 +495,39 @@ private fun unknownArg( return runtimes.firstOrNull { it.recognizes(arg) > 0 } == null } -private fun executeDirectives( +/** + * Executes any global (runtime-independent) directives in the given + * configDirectives list. + * + * Returns a new immutable list containing any directives that could not be + * executed globally. + */ +private fun executeGlobalDirectives( globalDirectiveFunctions: DirectivesMap, + configDirectives: List, + userArgs: ProgramArgs +): List { + debugBanner("EXECUTING GLOBAL DIRECTIVES") + + // Execute the runtime-independent directives. + debug() + debug("Executing runtime-independent directives...") + val runtimeDirectives = mutableListOf() + for (directive in configDirectives) { + // Execute the directive globally if possible. + val doDirective = globalDirectiveFunctions[directive] + if (doDirective != null) { + doDirective(userArgs) + continue + } + + // Any non-global directives will need to be handled by the runtimes + runtimeDirectives.add(directive) + } + return runtimeDirectives.toList() +} + +private fun executeDirectives( configDirectives: List, launchDirectives: List, runtimes: List, @@ -504,14 +540,6 @@ private fun executeDirectives( debug() debug("Executing configurator-side directives...") for (directive in configDirectives) { - // Execute the directive globally if possible. - val doDirective = globalDirectiveFunctions[directive] - if (doDirective != null) { - doDirective(userArgs) - continue - } - - // Not a global directive -- delegate execution to the runtimes. var success = false val (activatedRuntimes, dormantRuntimes) = runtimes.partition { it.directive in launchDirectives }