@@ -42,12 +42,26 @@ import org.scalajs.logging._
4242 *
4343 * @param logger The logger to use in the run. A [[JSEnv ]] is not required to
4444 * log anything.
45+ *
46+ * @param env Additional environment variables for this run.
47+ *
48+ * How these are retrieved in the JS code run inside the [[JSEnv ]] is
49+ * completely up to the implementation, including whether:
50+ * - they are implemented with system environment variables,
51+ * - they share the same namespace than the system environment variables.
52+ *
53+ * However, in any case, the variables in [[env ]] take precedence
54+ * over any (explicitly or implicitly) ambiant environment vars.
55+ *
56+ * This is an optional feature; but [[JSEnv ]]s are required to support an
57+ * empty [[env ]].
4558 */
4659final class RunConfig private (
4760 val onOutputStream : Option [RunConfig .OnOutputStream ],
4861 val inheritOutput : Boolean ,
4962 val inheritError : Boolean ,
5063 val logger : Logger ,
64+ val env : Map [String , String ],
5165 /** An option that will never be supported by anything because it is not exposed.
5266 *
5367 * This is used to test that [[JSEnv ]]s properly validate their configuration.
@@ -62,6 +76,7 @@ final class RunConfig private (
6276 inheritOutput = true ,
6377 inheritError = true ,
6478 logger = NullLogger ,
79+ env = Map .empty,
6580 eternallyUnsupportedOption = false )
6681 }
6782
@@ -77,6 +92,9 @@ final class RunConfig private (
7792 def withLogger (logger : Logger ): RunConfig =
7893 copy(logger = logger)
7994
95+ def withEnv (env : Map [String , String ]): RunConfig =
96+ copy(env = env)
97+
8098 private [jsenv] def withEternallyUnsupportedOption (
8199 eternallyUnsupportedOption : Boolean ): RunConfig =
82100 copy(eternallyUnsupportedOption = eternallyUnsupportedOption)
@@ -85,10 +103,11 @@ final class RunConfig private (
85103 inheritOutput : Boolean = inheritOutput,
86104 inheritError : Boolean = inheritError,
87105 logger : Logger = logger,
106+ env : Map [String , String ] = env,
88107 eternallyUnsupportedOption : Boolean = eternallyUnsupportedOption
89108 ): RunConfig = {
90109 new RunConfig (onOutputStream, inheritOutput, inheritError, logger,
91- eternallyUnsupportedOption)
110+ env, eternallyUnsupportedOption)
92111 }
93112
94113 /** Validates constraints on the config itself. */
@@ -119,9 +138,10 @@ final object RunConfig {
119138 */
120139 final class Validator private (
121140 inheritIO : Boolean ,
122- onOutputStream : Boolean
141+ onOutputStream : Boolean ,
142+ env : Boolean
123143 ) {
124- private def this () = this (false , false )
144+ private def this () = this (false , false , false )
125145
126146 /** The caller supports [[RunConfig#inheritOutput ]] and
127147 * [[RunConfig#inheritError ]].
@@ -131,6 +151,9 @@ final object RunConfig {
131151 /** The caller supports [[RunConfig#onOutputStream ]]. */
132152 def supportsOnOutputStream (): Validator = copy(onOutputStream = true )
133153
154+ /** The caller supports [[RunConfig#env ]]. */
155+ def supportsEnv (): Validator = copy(env = true )
156+
134157 /** Validates that `config` is valid and only sets supported options.
135158 *
136159 * @throws java.lang.IllegalArgumentException if there are unsupported options.
@@ -146,13 +169,19 @@ final object RunConfig {
146169 if (! onOutputStream && config.onOutputStream.isDefined)
147170 fail(" onOutputStream is not supported." )
148171
172+ if (! env && config.env.nonEmpty)
173+ fail(" env is not supported." )
174+
149175 if (config.eternallyUnsupportedOption)
150176 fail(" eternallyUnsupportedOption is not supported." )
151177 }
152178
153- private def copy (inheritIO : Boolean = inheritIO,
154- onOutputStream : Boolean = onOutputStream) = {
155- new Validator (inheritIO, onOutputStream)
179+ private def copy (
180+ inheritIO : Boolean = inheritIO,
181+ onOutputStream : Boolean = onOutputStream,
182+ env : Boolean = env
183+ ) = {
184+ new Validator (inheritIO, onOutputStream, env)
156185 }
157186 }
158187
0 commit comments