From eeeb7ed23409d6935b209d9a3e82fc37d7eec730 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Fri, 5 May 2023 17:12:48 -0700 Subject: [PATCH] cli: report snapshot progress after first 250ms --- src/cli_util.rs | 4 +++- src/progress.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/cli_util.rs b/src/cli_util.rs index ac1941a53..61c30df99 100644 --- a/src/cli_util.rs +++ b/src/cli_util.rs @@ -1000,7 +1000,9 @@ impl WorkspaceCommandHelper { ))); } }; - let new_tree_id = locked_wc.snapshot(base_ignores, None)?; + let progress = crate::progress::snapshot_progress(ui); + let new_tree_id = locked_wc.snapshot(base_ignores, progress.as_ref().map(|x| x as _))?; + drop(progress); if new_tree_id != *wc_commit.tree_id() { let mut tx = start_repo_transaction( &self.repo, diff --git a/src/progress.rs b/src/progress.rs index 8ae6da421..8566d06f0 100644 --- a/src/progress.rs +++ b/src/progress.rs @@ -1,11 +1,14 @@ use std::io; +use std::path::Path; +use std::sync::Mutex; use std::time::{Duration, Instant}; use crossterm::terminal::{Clear, ClearType}; use jujutsu_lib::git; +use jujutsu_lib::repo_path::RepoPath; use crate::cleanup_guard::CleanupGuard; -use crate::ui::Ui; +use crate::ui::{OutputGuard, Ui}; pub struct Progress { next_print: Instant, @@ -166,6 +169,43 @@ impl RateEstimateState { } } +pub fn snapshot_progress(ui: &mut Ui) -> Option { + struct State<'a> { + guard: Option, + ui: &'a mut Ui, + } + + if !ui.use_progress_indicator() { + return None; + } + + let start = Instant::now(); + let state = Mutex::new(State { guard: None, ui }); + + Some(move |path: &RepoPath| { + if start.elapsed() < Duration::from_millis(250) { + // Don't clutter the output during fast operations. Future work: Display current + // path after exactly 250ms has elapsed, to better handle large single files + return; + } + let mut state = state.lock().unwrap(); + if state.guard.is_none() { + state.guard = Some( + state + .ui + .output_guard(format!("\r{}", Clear(ClearType::CurrentLine))), + ); + } + _ = write!( + state.ui, + "\r{}Snapshotting {}", + Clear(ClearType::CurrentLine), + path.to_fs_path(Path::new("")).display() + ); + _ = state.ui.flush(); + }) +} + #[cfg(test)] mod tests { use super::*;