Add support to run external command with string evaluation (#3611)

This commit is contained in:
Võ Anh Duy 2021-06-14 08:20:07 +08:00 committed by GitHub
parent 2846e3f5d9
commit 721f704260
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 14 deletions

View File

@ -4,10 +4,13 @@ use crate::prelude::*;
use derive_new::new; use derive_new::new;
use std::path::PathBuf; use std::path::PathBuf;
use nu_engine::shell::CdArgs;
use nu_engine::WholeStreamCommand; use nu_engine::WholeStreamCommand;
use nu_engine::{evaluate_baseline_expr, shell::CdArgs};
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_protocol::hir::{Expression, ExternalArgs, ExternalCommand, Literal, SpannedExpression}; use nu_protocol::{
hir::{ExternalArgs, ExternalCommand, SpannedExpression},
Primitive, UntaggedValue,
};
use nu_protocol::{Signature, SyntaxShape}; use nu_protocol::{Signature, SyntaxShape};
use nu_source::Tagged; use nu_source::Tagged;
@ -17,12 +20,13 @@ pub struct RunExternalCommand {
pub(crate) interactive: bool, pub(crate) interactive: bool,
} }
fn spanned_expression_to_string(expr: SpannedExpression) -> Result<String, ShellError> { fn spanned_expression_to_string(
if let SpannedExpression { expr: SpannedExpression,
expr: Expression::Literal(Literal::String(s)), ctx: &EvaluationContext,
.. ) -> Result<String, ShellError> {
} = expr let value = evaluate_baseline_expr(&expr, ctx)?;
{
if let UntaggedValue::Primitive(Primitive::String(s)) = value.value {
Ok(s) Ok(s)
} else { } else {
Err(ShellError::labeled_error( Err(ShellError::labeled_error(
@ -67,12 +71,11 @@ impl WholeStreamCommand for RunExternalCommand {
let external_redirection = args.call_info.args.external_redirection; let external_redirection = args.call_info.args.external_redirection;
let name = positionals let expr = positionals.next().ok_or_else(|| {
.next()
.ok_or_else(|| {
ShellError::untagged_runtime_error("run_external called with no arguments") ShellError::untagged_runtime_error("run_external called with no arguments")
}) })?;
.and_then(spanned_expression_to_string)?;
let name = spanned_expression_to_string(expr, &args.context)?;
let mut external_context = args.context.clone(); let mut external_context = args.context.clone();

View File

@ -68,6 +68,18 @@ fn correctly_escape_external_arguments() {
assert_eq!(actual.out, "$0"); assert_eq!(actual.out, "$0");
} }
#[test]
fn execute_binary_in_string() {
let actual = nu!(
cwd: ".",
r#"
let cmd = echo
^$"($cmd)" '$0'
"#);
assert_eq!(actual.out, "$0");
}
#[test] #[test]
fn redirects_custom_command_external() { fn redirects_custom_command_external() {
let actual = nu!(cwd: ".", r#"def foo [] { nu --testbin cococo foo bar }; foo | str length "#); let actual = nu!(cwd: ".", r#"def foo [] { nu --testbin cococo foo bar }; foo | str length "#);