2023-10-14 22:39:44 +02:00
|
|
|
use std::io::{BufRead, BufReader};
|
2023-10-14 22:39:43 +02:00
|
|
|
use std::process::Command;
|
2023-10-14 22:39:44 +02:00
|
|
|
use log::info;
|
2023-10-14 22:39:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
pub struct Process {
|
|
|
|
pub command: Vec<String>,
|
|
|
|
pub cwd: Option<String>,
|
|
|
|
pub env: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Process {
|
|
|
|
pub fn new(command: Vec<String>, cwd: Option<String>, env: Vec<String>) -> Process {
|
2023-10-14 22:39:44 +02:00
|
|
|
Process { command, cwd, env }
|
2023-10-14 22:39:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn command<S: Into<String>>(cmd: Vec<S>) -> Process {
|
|
|
|
Process::new(cmd.into_iter().map(|v| v.into()).collect(), None, vec![])
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn spawn(&self) -> std::io::Result<std::process::Child> {
|
|
|
|
let mut child = Command::new(&self.command[0])
|
|
|
|
.args(&self.command[1..])
|
|
|
|
.current_dir(self.cwd.clone().unwrap_or(".".to_string()))
|
|
|
|
.envs(self.env.iter().map(|v| {
|
|
|
|
let mut split = v.split('=');
|
2023-10-14 22:39:44 +02:00
|
|
|
(
|
|
|
|
split.next().unwrap().to_string(),
|
|
|
|
split.next().unwrap().to_string(),
|
|
|
|
)
|
2023-10-14 22:39:43 +02:00
|
|
|
}))
|
|
|
|
.stdout(std::process::Stdio::piped())
|
|
|
|
.stderr(std::process::Stdio::piped())
|
|
|
|
.spawn()?;
|
2023-10-14 22:39:44 +02:00
|
|
|
|
|
|
|
let stdout = child.stdout.take().unwrap();
|
|
|
|
let stderr = child.stderr.take().unwrap();
|
|
|
|
|
|
|
|
for line in BufReader::new(stdout).lines() {
|
|
|
|
info!(target: "command:stdout", "{}", line.unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
for line in BufReader::new(stderr).lines() {
|
|
|
|
info!(target: "command:stderr", "{}", line.unwrap());
|
|
|
|
}
|
|
|
|
|
2023-10-14 22:39:43 +02:00
|
|
|
Ok(child)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Process {
|
|
|
|
fn default() -> Process {
|
|
|
|
Process::new(vec![], None, vec![])
|
|
|
|
}
|
2023-10-14 22:39:44 +02:00
|
|
|
}
|