forked from extern/nushell
Add support to run external command with string evaluation (#3611)
This commit is contained in:
parent
2846e3f5d9
commit
721f704260
@ -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();
|
||||||
|
|
||||||
|
@ -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 "#);
|
||||||
|
Loading…
Reference in New Issue
Block a user