Properly evaluate dynamic blocks (#3339)

This commit is contained in:
JT 2021-04-21 14:31:54 +12:00 committed by GitHub
parent ce35689d2e
commit 02d5729941
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 37 deletions

View file

@ -137,21 +137,17 @@ fn run_pipeline(
} }
} }
match &call.head.expr { let block = run_expression_block(&call.head, ctx)?.into_vec();
Expression::Block(block) => {
ctx.scope.enter_scope();
for (param, value) in block.params.positional.iter().zip(args.iter()) {
ctx.scope.add_var(param.0.name(), value[0].clone());
}
let result = run_block(&block, ctx, input);
ctx.scope.exit_scope();
let result = result?; if block.len() != 1 {
return Ok(result); return Err(ShellError::labeled_error(
"Dynamic commands must start with a block",
"needs to be a block",
call.head.span,
));
} }
Expression::Variable(v, span) => {
if let Some(value) = ctx.scope.get_var(v) { match &block[0].value {
match &value.value {
UntaggedValue::Block(captured_block) => { UntaggedValue::Block(captured_block) => {
ctx.scope.enter_scope(); ctx.scope.enter_scope();
ctx.scope.add_vars(&captured_block.captured.entries); ctx.scope.add_vars(&captured_block.captured.entries);
@ -174,18 +170,6 @@ fn run_pipeline(
return Err(ShellError::labeled_error("Dynamic commands must start with a block (or variable pointing to a block)", "needs to be a block", call.head.span)); return Err(ShellError::labeled_error("Dynamic commands must start with a block (or variable pointing to a block)", "needs to be a block", call.head.span));
} }
} }
} else {
return Err(ShellError::labeled_error(
"Variable not found",
"variable not found",
span,
));
}
}
_ => {
return Err(ShellError::labeled_error("Dynamic commands must start with a block (or variable pointing to a block)", "needs to be a block", call.head.span));
}
}
} }
ClassifiedCommand::Expr(expr) => run_expression_block(&*expr, ctx)?, ClassifiedCommand::Expr(expr) => run_expression_block(&*expr, ctx)?,

View file

@ -391,6 +391,17 @@ fn proper_shadow_set_aliases() {
assert_eq!(actual.out, "falsetruefalse"); assert_eq!(actual.out, "falsetruefalse");
} }
#[test]
fn run_dynamic_blocks() {
let actual = nu!(
cwd: ".",
r#"
let block = { echo "holaaaa" }; $block
"#
);
assert_eq!(actual.out, "holaaaa");
}
#[cfg(feature = "which")] #[cfg(feature = "which")]
#[test] #[test]
fn argument_invocation_reports_errors() { fn argument_invocation_reports_errors() {