You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tourmaline/src/task/commands/run.rs

67 lines
1.9 KiB
Rust

use std::{
io::Write,
process::{Command, Stdio},
};
use embed_nu::{
nu_protocol::{ShellError, Signature, SyntaxShape},
CallExt, PipelineData,
};
#[derive(Clone)]
pub struct RunCommand;
impl embed_nu::nu_protocol::engine::Command for RunCommand {
fn name(&self) -> &str {
"run"
}
fn signature(&self) -> embed_nu::nu_protocol::Signature {
Signature::new("run")
.required("executable", SyntaxShape::String, "The executable to run")
.rest(
"rest",
SyntaxShape::String,
"the args for the given command",
)
.allows_unknown_args()
.category(embed_nu::nu_protocol::Category::Custom("Tourmalin".into()))
}
fn usage(&self) -> &str {
"run <executable> [...<args>]"
}
fn run(
&self,
engine_state: &embed_nu::nu_protocol::engine::EngineState,
stack: &mut embed_nu::nu_protocol::engine::Stack,
call: &embed_nu::nu_protocol::ast::Call,
input: embed_nu::PipelineData,
) -> Result<embed_nu::PipelineData, embed_nu::nu_protocol::ShellError> {
let executable: String = call.req(engine_state, stack, 0)?;
let args: Vec<String> = call.rest(engine_state, stack, 1)?;
tracing::debug!("Running {executable} {}", args.join(" "));
let mut cmd = Command::new(&executable)
.args(args)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.stdin(Stdio::piped())
.spawn()?;
let mut stdin = cmd.stdin.take().unwrap();
stdin.write_all(input.collect_string_strict(call.span())?.0.as_bytes())?;
if cmd.wait().is_err() {
Err(ShellError::ExternalCommand(
executable,
String::from("Is it written correctly?"),
call.span(),
))
} else {
Ok(PipelineData::empty())
}
}
}