live-cli/src/command.rs

84 lines
2.1 KiB
Rust
Raw Normal View History

use anyhow::bail;
use anyhow::Context;
use anyhow::Result;
2022-12-15 23:19:17 -05:00
use std::{
io::Write,
process::{Command, Stdio},
};
use crate::App;
2022-12-16 21:28:40 -05:00
pub struct CommandResult {
2022-12-15 23:19:17 -05:00
pub status_success: bool,
2022-12-16 21:28:40 -05:00
pub stdout: Vec<u8>,
pub stderr: Vec<u8>,
2022-12-15 23:19:17 -05:00
}
2022-12-16 21:28:40 -05:00
impl Default for CommandResult {
2022-12-15 23:19:17 -05:00
fn default() -> Self {
Self {
status_success: true,
2022-12-16 21:28:40 -05:00
stdout: vec![],
stderr: vec![],
2022-12-15 23:19:17 -05:00
}
}
}
pub fn run(app: &mut App) {
2022-12-17 11:25:15 -05:00
match run_inner(app) {
Ok(c) => {
// If there was no stdout and the command failed, don't touch stdout
if !c.status_success && c.stdout.is_empty() {
app.command_result.stderr = c.stderr;
app.command_result.status_success = c.status_success;
} else {
app.command_result = c;
}
}
2022-12-16 20:41:16 -05:00
Err(e) => {
2022-12-17 11:25:15 -05:00
println!("asdf");
app.command_result.status_success = false;
app.command_result.stderr = e.to_string().as_bytes().to_vec();
2022-12-16 20:41:16 -05:00
}
2022-12-17 11:25:15 -05:00
}
}
2022-12-16 20:41:16 -05:00
2022-12-17 11:25:15 -05:00
fn run_inner(app: &mut App) -> Result<CommandResult> {
let mut command = Command::new(&app.command);
command
2022-12-15 23:19:17 -05:00
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
2022-12-17 11:25:15 -05:00
.args(&app.hidden_options);
if app.wordsplit {
match shellwords::split(&app.cmdline) {
Ok(a) => {
command.args(a);
}
Err(e) => {
bail!("Argument error: {e:?}");
}
}
} else {
// TODO: Avoid cloning here
command.arg(&app.cmdline);
}
let mut child = command.spawn().context("Could not spawn child process")?;
2022-12-15 23:19:17 -05:00
let mut stdin = child.stdin.take().context("Could not take stdin")?;
2022-12-15 23:19:17 -05:00
let text_orig_clone = app.text_orig.clone();
std::thread::spawn(move || {
2022-12-17 00:10:17 -05:00
let _result = stdin.write_all(text_orig_clone.as_bytes());
2022-12-15 23:19:17 -05:00
});
// Collect the output
let output = child.wait_with_output().context("Failed to read stdout")?;
2022-12-15 23:19:17 -05:00
Ok(CommandResult {
2022-12-15 23:19:17 -05:00
status_success: output.status.success(),
2022-12-16 21:28:40 -05:00
stdout: output.stdout,
stderr: output.stderr,
})
2022-12-15 23:19:17 -05:00
}