diff --git a/maid/client/cli.rs b/maid/client/cli.rs index 3006186fd6b197325efbbce453b4a43b3013005b..44b2d06ec2d3d2971e55da257fa5f0cc707db2e3 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 946675f149c885647fc1855146706a97297c2b00..69cf5aea87e06a3fcfdbbd6aa52d682f55e5303b 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 44ee464d31e9cf982700e6f65a78b55f33b311d1..07a505a9b4c3dc8b0944399483247989f09ec390 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(); + } }