102 lines
2.3 KiB
Rust
102 lines
2.3 KiB
Rust
use anyhow::{anyhow, Context, Result};
|
|
use std::{
|
|
collections::VecDeque,
|
|
env,
|
|
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(value.to_vec())
|
|
}
|
|
}
|
|
|
|
fn get_compose_file() -> Result<String> {
|
|
let cf = env::var("COMPOSE_FILE")?;
|
|
Ok(cf)
|
|
}
|
|
|
|
#[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 {
|
|
let cf =
|
|
get_compose_file().unwrap_or_else(|_| "docker/local/docker-compose.yaml".to_string());
|
|
Self::default().args("docker compose -f").args(&cf)
|
|
}
|
|
|
|
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!("running `{self}`");
|
|
|
|
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(())
|
|
}
|
|
}
|