nu_command/env/
with_env.rs1use nu_engine::{command_prelude::*, eval_block};
2use nu_protocol::{debugger::WithoutDebug, engine::Closure};
3
4#[derive(Clone)]
5pub struct WithEnv;
6
7impl Command for WithEnv {
8 fn name(&self) -> &str {
9 "with-env"
10 }
11
12 fn signature(&self) -> Signature {
13 Signature::build("with-env")
14 .input_output_types(vec![(Type::Any, Type::Any)])
15 .required(
16 "variable",
17 SyntaxShape::Any,
18 "The environment variable to temporarily set.",
19 )
20 .required(
21 "block",
22 SyntaxShape::Closure(None),
23 "The block to run once the variable is set.",
24 )
25 .category(Category::Env)
26 }
27
28 fn description(&self) -> &str {
29 "Runs a block with an environment variable set."
30 }
31
32 fn run(
33 &self,
34 engine_state: &EngineState,
35 stack: &mut Stack,
36 call: &Call,
37 input: PipelineData,
38 ) -> Result<PipelineData, ShellError> {
39 with_env(engine_state, stack, call, input)
40 }
41
42 fn examples(&self) -> Vec<Example> {
43 vec![Example {
44 description: "Set by key-value record",
45 example: r#"with-env {X: "Y", W: "Z"} { [$env.X $env.W] }"#,
46 result: Some(Value::list(
47 vec![Value::test_string("Y"), Value::test_string("Z")],
48 Span::test_data(),
49 )),
50 }]
51 }
52}
53
54fn with_env(
55 engine_state: &EngineState,
56 stack: &mut Stack,
57 call: &Call,
58 input: PipelineData,
59) -> Result<PipelineData, ShellError> {
60 let env: Record = call.req(engine_state, stack, 0)?;
61 let capture_block: Closure = call.req(engine_state, stack, 1)?;
62 let block = engine_state.get_block(capture_block.block_id);
63 let mut stack = stack.captures_to_stack_preserve_out_dest(capture_block.captures);
64
65 for prohibited in ["PWD", "FILE_PWD", "CURRENT_FILE"] {
67 if env.contains(prohibited) {
68 return Err(ShellError::AutomaticEnvVarSetManually {
69 envvar_name: prohibited.into(),
70 span: call.head,
71 });
72 }
73 }
74
75 for (k, v) in env {
76 stack.add_env_var(k, v);
77 }
78
79 eval_block::<WithoutDebug>(engine_state, &mut stack, block, input)
80}
81
82#[cfg(test)]
83mod test {
84 use super::*;
85
86 #[test]
87 fn test_examples() {
88 use crate::test_examples;
89
90 test_examples(WithEnv {})
91 }
92}