diff --git a/js/process.ts b/js/process.ts index 495f6a9ce5..c47a5b5dd5 100644 --- a/js/process.ts +++ b/js/process.ts @@ -27,6 +27,7 @@ export type ProcessStdio = "inherit" | "piped" | "null"; export interface RunOptions { args: string[]; cwd?: string; + env?: { [key: string]: string }; stdout?: ProcessStdio; stderr?: ProcessStdio; stdin?: ProcessStdio; @@ -107,11 +108,24 @@ export function run(opt: RunOptions): Process { opt.args.map(a => builder.createString(a)) ); const cwdOffset = opt.cwd == null ? -1 : builder.createString(opt.cwd); + const kvOffset: flatbuffers.Offset[] = []; + if (opt.env) { + for (const [key, val] of Object.entries(opt.env)) { + const keyOffset = builder.createString(key); + const valOffset = builder.createString(String(val)); + msg.KeyValue.startKeyValue(builder); + msg.KeyValue.addKey(builder, keyOffset); + msg.KeyValue.addValue(builder, valOffset); + kvOffset.push(msg.KeyValue.endKeyValue(builder)); + } + } + const envOffset = msg.Run.createEnvVector(builder, kvOffset); msg.Run.startRun(builder); msg.Run.addArgs(builder, argsOffset); if (opt.cwd != null) { msg.Run.addCwd(builder, cwdOffset); } + msg.Run.addEnv(builder, envOffset); if (opt.stdin) { msg.Run.addStdin(builder, stdioMap(opt.stdin!)); } diff --git a/js/process_test.ts b/js/process_test.ts index e629dbe3d3..9603fb1c83 100644 --- a/js/process_test.ts +++ b/js/process_test.ts @@ -186,3 +186,22 @@ testPerm({ run: true }, async function runOutput() { assertEqual(s, "hello"); p.close(); }); + +testPerm({ run: true }, async function runEnv() { + const p = run({ + args: [ + "python", + "-c", + "import os, sys; sys.stdout.write(os.environ.get('FOO', '') + os.environ.get('BAR', ''))" + ], + env: { + FOO: "0123", + BAR: "4567" + }, + stdout: "piped" + }); + const output = await p.output(); + const s = new TextDecoder().decode(output); + assertEqual(s, "01234567"); + p.close(); +}); diff --git a/src/msg.fbs b/src/msg.fbs index 7d8b891754..f3c47faf6a 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -464,6 +464,7 @@ enum ProcessStdio: byte { Inherit, Piped, Null } table Run { args: [string]; cwd: string; + env: [KeyValue]; stdin: ProcessStdio; stdout: ProcessStdio; stderr: ProcessStdio; diff --git a/src/ops.rs b/src/ops.rs index a0646e9231..a968ae6e16 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -1559,6 +1559,7 @@ fn op_run( assert_eq!(data.len(), 0); let inner = base.inner_as_run().unwrap(); let args = inner.args().unwrap(); + let env = inner.env().unwrap(); let cwd = inner.cwd(); let mut c = Command::new(args.get(0)); @@ -1567,6 +1568,10 @@ fn op_run( c.arg(arg); }); cwd.map(|d| c.current_dir(d)); + (0..env.len()).for_each(|i| { + let entry = env.get(i); + c.env(entry.key().unwrap(), entry.value().unwrap()); + }); c.stdin(subprocess_stdio_map(inner.stdin())); c.stdout(subprocess_stdio_map(inner.stdout()));