94 lines
2.1 KiB
Rust
94 lines
2.1 KiB
Rust
use anyhow::{anyhow, Context, Result};
|
|
use std::{
|
|
collections::VecDeque,
|
|
ffi::OsStr,
|
|
fmt::Display,
|
|
fs::{File, OpenOptions},
|
|
os::unix::process::CommandExt,
|
|
path::PathBuf,
|
|
process::{Child, Command, Stdio},
|
|
};
|
|
|
|
use crate::debug_eprintln;
|
|
|
|
pub struct Args(Vec<String>);
|
|
|
|
impl From<&str> for Args {
|
|
fn from(value: &str) -> Self {
|
|
Self(Vec::from_iter(value.split_whitespace().map(String::from)))
|
|
}
|
|
}
|
|
|
|
impl From<&String> for Args {
|
|
fn from(value: &String) -> Self {
|
|
Self(Vec::from_iter(value.split_whitespace().map(String::from)))
|
|
}
|
|
}
|
|
|
|
impl From<&[String]> for Args {
|
|
fn from(value: &[String]) -> Self {
|
|
Self(Vec::from_iter(value.iter().map(|x| x.to_string())))
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct CommandBuilder {
|
|
args: Vec<String>,
|
|
}
|
|
|
|
impl Display for CommandBuilder {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.write_str(&self.args.join(" "))
|
|
}
|
|
}
|
|
|
|
impl CommandBuilder {
|
|
pub fn new(args: &str) -> Self {
|
|
Self::default().args("docker")
|
|
}
|
|
|
|
pub fn docker() -> Self {
|
|
Self::default().args("docker")
|
|
}
|
|
|
|
pub fn docker_compose() -> Self {
|
|
Self::default().args("docker compose -f docker/local/docker-compose.yaml")
|
|
}
|
|
|
|
pub fn args<T>(mut self, args: T) -> Self
|
|
where
|
|
Args: From<T>,
|
|
{
|
|
self.args.extend(Args::from(args).0);
|
|
self
|
|
}
|
|
|
|
pub fn build(self) -> Result<Command> {
|
|
debug_eprintln!("-----\n{self}\n-----");
|
|
|
|
let (first, rest) = self.args.split_first().context("empty args")?;
|
|
let mut command = Command::new(first);
|
|
command.args(rest);
|
|
|
|
Ok(command)
|
|
}
|
|
|
|
pub fn exec_get_stdout(mut self) -> Result<String> {
|
|
Ok(String::from_utf8(self.build()?.output()?.stdout)?)
|
|
}
|
|
|
|
pub fn exec(mut self) -> Result<()> {
|
|
self.build()?.spawn()?.wait()?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn spawn(mut self) -> Result<(Child)> {
|
|
Ok(self.build()?.spawn()?)
|
|
}
|
|
|
|
pub fn exec_redirect_stdout(mut self, stdio: Stdio) -> Result<()> {
|
|
self.build()?.stdout(stdio).spawn()?.wait()?;
|
|
Ok(())
|
|
}
|
|
}
|