From 9769ae8ea495c19115d080b8971ba122cdb8eec9 Mon Sep 17 00:00:00 2001
From: theMackabu <theMackabu@gmail.com>
Date: Mon, 25 Nov 2024 22:13:38 -0800
Subject: [PATCH] allow logging from dependency using 'log:name'

---
 maid/client/cli.rs           | 18 +++++++++---------
 maid/client/cli/script.rs    | 31 ++++++++++++++++++++++++-------
 maid/client/task/progress.rs | 25 +++++++++++++++++++------
 3 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/maid/client/cli.rs b/maid/client/cli.rs
index 3006186..44b2d06 100644
--- a/maid/client/cli.rs
+++ b/maid/client/cli.rs
@@ -128,19 +128,19 @@ pub(crate) fn exec(task: &str, args: &Vec<String>, path: &String, silent: bool,
 
                         pb.set_prefix(format!("[{}/{}]", index + 1, deps.len()));
                         pb.set_message(fmtstr!("{} {name}", "running dependency".bright_yellow()));
+
                         exec(&name, args, path, true, true, is_remote, log_level, force, is_verbose_dep);
                     }
 
                     if !is_dep {
-                        pb.suspend(|| {
-                            println!(
-                                "{} {} in {} {}\n",
-                                maid::colors::OK,
-                                format!("finished {} {}", deps.len(), ternary!(deps.len() > 1, "dependencies", "dependency")).bright_green(),
-                                format!("{:.2?}", start.elapsed()).yellow(),
-                                format!("[{}]", deps.join(", ")).white()
-                            )
-                        });
+                        task::progress::finish();
+                        println!(
+                            "{} {} in {} {}\n",
+                            maid::colors::OK,
+                            format!("finished {} {}", deps.len(), ternary!(deps.len() > 1, "dependencies", "dependency")).bright_green(),
+                            format!("{:.2?}", start.elapsed()).yellow(),
+                            format!("[{}]", deps.join(", ")).white()
+                        )
                     }
                 }
                 None => {}
diff --git a/maid/client/cli/script.rs b/maid/client/cli/script.rs
index 946675f..69cf5ae 100644
--- a/maid/client/cli/script.rs
+++ b/maid/client/cli/script.rs
@@ -7,13 +7,13 @@ use maid::{
 
 use std::{
     env,
-    io::Error,
+    io::{BufRead, BufReader, Error},
     path::Path,
     process::{Child, Command, ExitStatus, Stdio},
     time::Instant,
 };
 
-use crate::shell::IntoArgs;
+use crate::{shell::IntoArgs, task};
 use fs_extra::dir::get_size;
 use human_bytes::human_bytes;
 use text_placeholder::Template;
@@ -47,15 +47,32 @@ pub(crate) fn run_wrapped(runner: Runner<toml::Value>) {
 
         if runner.dep.active {
             let is_verbose = runner.dep.verbose;
+            let pb = task::progress::get().unwrap();
 
             cmd = match Command::new(&name)
-                .stdout(if is_verbose { Stdio::inherit() } else { Stdio::null() })
-                .stderr(if is_verbose { Stdio::inherit() } else { Stdio::null() })
-                .stdin(if is_verbose { Stdio::inherit() } else { Stdio::null() })
+                .stdout(if is_verbose { Stdio::piped() } else { Stdio::null() })
+                .stderr(if is_verbose { Stdio::piped() } else { Stdio::null() })
+                .stdin(Stdio::null())
                 .args(args.to_owned())
                 .spawn()
             {
-                Ok(output) => output,
+                Ok(mut child) => {
+                    if let (Some(stdout), Some(stderr)) = (child.stdout.take(), child.stderr.take()) {
+                        let stdout = BufReader::new(stdout);
+                        let stderr = BufReader::new(stderr);
+                        let name = format!("[{}]", runner.name).white();
+
+                        std::thread::spawn(move || {
+                            stdout
+                                .lines()
+                                .chain(stderr.lines())
+                                .filter_map(Result::ok)
+                                .filter(|_| is_verbose)
+                                .for_each(|line| pb.println(format!("{name} {line}")));
+                        });
+                    }
+                    child
+                }
                 Err(err) => error!(%err, "Cannot start command {name}."),
             };
         } else {
@@ -66,7 +83,7 @@ pub(crate) fn run_wrapped(runner: Runner<toml::Value>) {
                 .stdin(Stdio::inherit())
                 .spawn()
             {
-                Ok(output) => output,
+                Ok(child) => child,
                 Err(err) => error!(%err, "Cannot start command {name}."),
             };
         }
diff --git a/maid/client/task/progress.rs b/maid/client/task/progress.rs
index 44ee464..07a505a 100644
--- a/maid/client/task/progress.rs
+++ b/maid/client/task/progress.rs
@@ -1,12 +1,25 @@
 use indicatif::{ProgressBar, ProgressStyle};
 use macros_rs::fmt::fmtstr;
+use std::sync::OnceLock;
 
-pub(crate) fn init(ticks: Vec<&str>, template: &str, tick: u64) -> ProgressBar {
-    let pb = ProgressBar::new_spinner();
-    let tick_str: Vec<&str> = ticks.into_iter().map(|item| fmtstr!("{item} ")).collect();
+static PROGRESS_BAR: OnceLock<ProgressBar> = OnceLock::new();
 
-    pb.enable_steady_tick(std::time::Duration::from_millis(tick));
-    pb.set_style(ProgressStyle::with_template(template).unwrap().tick_strings(&*tick_str));
+pub(crate) fn get<'p>() -> Option<&'p ProgressBar> { PROGRESS_BAR.get() }
 
-    return pb;
+pub(crate) fn init<'p>(ticks: Vec<&str>, template: &str, tick: u64) -> &'p ProgressBar {
+    PROGRESS_BAR.get_or_init(|| {
+        let pb = ProgressBar::new_spinner();
+        let tick_str: Vec<&str> = ticks.into_iter().map(|item| fmtstr!("{item} ")).collect();
+
+        pb.enable_steady_tick(std::time::Duration::from_millis(tick));
+        pb.set_style(ProgressStyle::with_template(template).unwrap().tick_strings(&*tick_str));
+
+        return pb;
+    })
+}
+
+pub(crate) fn finish() {
+    if let Some(pb) = PROGRESS_BAR.get() {
+        pb.finish_and_clear();
+    }
 }
-- 
GitLab