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.
73 lines
2.2 KiB
Rust
73 lines
2.2 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)?;
|
|
let pwd = stack
|
|
.get_env_var(engine_state, "PWD")
|
|
.and_then(|v| v.as_string().ok())
|
|
.unwrap_or_else(|| std::env::var("PWD").unwrap_or_else(|_| "/".into()));
|
|
|
|
tracing::debug!("Running {executable} {}", args.join(" "));
|
|
|
|
let mut cmd = Command::new(&executable)
|
|
.current_dir(pwd)
|
|
.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()?.success() {
|
|
Ok(PipelineData::empty())
|
|
} else {
|
|
Err(ShellError::ExternalCommand(
|
|
executable,
|
|
String::from("Is it written correctly?"),
|
|
call.span(),
|
|
))
|
|
}
|
|
}
|
|
}
|