From b83d44768d4e1673371ecf9a9b14bd76b91b6b2c Mon Sep 17 00:00:00 2001 From: Didier Date: Mon, 17 Jul 2023 20:40:22 +0200 Subject: [PATCH] feat: Process with multithreaded log pipes --- pkgr/src/process/mod.rs | 44 ++++++++++++++++++++++++++++++++++++++ pkgr/src/process/output.rs | 26 ++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 pkgr/src/process/mod.rs create mode 100644 pkgr/src/process/output.rs diff --git a/pkgr/src/process/mod.rs b/pkgr/src/process/mod.rs new file mode 100644 index 0000000..70ab93b --- /dev/null +++ b/pkgr/src/process/mod.rs @@ -0,0 +1,44 @@ +use std::process::Command; + +pub mod output; + +pub struct Process { + pub command: Vec, + pub cwd: Option, + pub env: Vec, +} + +impl Process { + pub fn new(command: Vec, cwd: Option, env: Vec) -> Process { + Process { + command, + cwd, + env, + } + } + + pub fn command>(cmd: Vec) -> Process { + Process::new(cmd.into_iter().map(|v| v.into()).collect(), None, vec![]) + } + + pub fn spawn(&self) -> std::io::Result { + 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('='); + (split.next().unwrap().to_string(), split.next().unwrap().to_string()) + })) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .spawn()?; + output::spawn_output_handlers(&mut child); + Ok(child) + } +} + +impl Default for Process { + fn default() -> Process { + Process::new(vec![], None, vec![]) + } +} \ No newline at end of file diff --git a/pkgr/src/process/output.rs b/pkgr/src/process/output.rs new file mode 100644 index 0000000..09e788e --- /dev/null +++ b/pkgr/src/process/output.rs @@ -0,0 +1,26 @@ +// create functions that spawn threads for Stdout and Stderr +// that print the output to info!(target: "command:stdout", ...) and info!(target: "command:stderr", ...) respectively + +use std::process::Child; +use std::io::{BufRead, BufReader}; + +use log::{info, error}; + +pub fn spawn_output_handlers(child: &mut Child) { + let stdout = child.stdout.take().unwrap(); + let stderr = child.stderr.take().unwrap(); + + std::thread::spawn(move || { + let reader = BufReader::new(stdout); + for line in reader.lines() { + info!(target: "command:stdout", "{}", line.unwrap()); + } + }); + + std::thread::spawn(move || { + let reader = BufReader::new(stderr); + for line in reader.lines() { + error!(target: "command:stderr", "{}", line.unwrap()); + } + }); +} \ No newline at end of file