Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/commands/debug_files/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ fn find_ids(
.filter(|e| e.file_type().is_file());

let mut found_files = vec![];
let pb = ProgressBar::new_spinner();
let mut pb = ProgressBar::new_spinner();
pb.set_style(
ProgressStyle::default_spinner()
.tick_chars("/|\\- ")
Expand All @@ -136,7 +136,7 @@ fn find_ids(
pb.set_message(p);
}
pb.tick();
pb.set_prefix(&format!("{}", found_files.len()));
pb.set_prefix(format!("{}", found_files.len()));

let found: Vec<_> = types
.iter()
Expand Down
2 changes: 1 addition & 1 deletion src/utils/chunks/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ where
);

let api = Api::current();
let pb = ProgressBar::new(chunked_objects.len());
let mut pb = ProgressBar::new(chunked_objects.len());
pb.set_style(progress_style);
pb.set_prefix(">");

Expand Down
12 changes: 6 additions & 6 deletions src/utils/dif_upload/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ fn search_difs(options: &DifUpload) -> Result<Vec<DifMatch<'static>>> {
\n found {prefix:.yellow} {msg:.dim}",
);

let pb = ProgressBar::new_spinner();
let mut pb = ProgressBar::new_spinner();
pb.enable_steady_tick(100);
pb.set_style(progress_style);

Expand Down Expand Up @@ -668,7 +668,7 @@ fn search_difs(options: &DifUpload) -> Result<Vec<DifMatch<'static>>> {
}
};

pb.set_prefix(&collected.len().to_string());
pb.set_prefix(collected.len().to_string());
Ok(())
})?;
}
Expand Down Expand Up @@ -958,7 +958,7 @@ where
\n{wide_bar} {pos}/{len}",
);

let pb = ProgressBar::new(items.len());
let mut pb = ProgressBar::new(items.len());
pb.set_style(progress_style);
pb.set_prefix(">");

Expand Down Expand Up @@ -1019,7 +1019,7 @@ fn process_symbol_maps<'a>(
\n{wide_bar} {pos}/{len}",
);

let pb = ProgressBar::new(len);
let mut pb = ProgressBar::new(len);
pb.set_style(progress_style);
pb.set_prefix(">");

Expand Down Expand Up @@ -1110,7 +1110,7 @@ fn create_source_bundles<'a>(
\n{wide_bar} {pos}/{len}",
);

let pb = ProgressBar::new(difs.len());
let mut pb = ProgressBar::new(difs.len());
pb.set_style(progress_style);
pb.set_prefix(">");

Expand Down Expand Up @@ -1166,7 +1166,7 @@ fn create_il2cpp_mappings<'a>(difs: &[DifMatch<'a>]) -> Result<Vec<DifMatch<'a>>
\n{wide_bar} {pos}/{len}",
);

let pb = ProgressBar::new(difs.len());
let mut pb = ProgressBar::new(difs.len());
pb.set_style(progress_style);
pb.set_prefix(">");

Expand Down
6 changes: 3 additions & 3 deletions src/utils/file_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl ReleaseFileSearch {
\n found {prefix:.yellow} {msg:.dim}",
);

let pb = ProgressBar::new_spinner();
let mut pb = ProgressBar::new_spinner();
pb.enable_steady_tick(100);
pb.set_style(progress_style);

Expand Down Expand Up @@ -139,7 +139,7 @@ impl ReleaseFileSearch {
if file.file_type().is_some_and(|t| t.is_dir()) {
continue;
}
pb.set_message(&format!("{}", file.path().display()));
pb.set_message(format!("{}", file.path().display()));

info!("found: {} ({} bytes)", file.path().display(), {
#[expect(clippy::unwrap_used, reason = "legacy code")]
Expand All @@ -164,7 +164,7 @@ impl ReleaseFileSearch {
};
collected.push(file_match);

pb.set_prefix(&collected.len().to_string());
pb.set_prefix(collected.len().to_string());
}

pb.finish_and_clear();
Expand Down
2 changes: 1 addition & 1 deletion src/utils/file_upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ fn build_artifact_bundle(
\n{wide_bar} {pos}/{len}",
);

let pb = ProgressBar::new(files.len());
let mut pb = ProgressBar::new(files.len());
pb.set_style(progress_style);
pb.set_prefix(">");

Expand Down
129 changes: 97 additions & 32 deletions src/utils/progress.rs
Original file line number Diff line number Diff line change
@@ -1,76 +1,141 @@
use parking_lot::RwLock;
use std::env;
use std::ops::Deref;
use std::io::IsTerminal as _;
use std::sync::Arc;
use std::time::Instant;

use crate::utils::logging;

pub use indicatif::ProgressStyle;

pub fn is_progress_bar_visible() -> bool {
env::var("SENTRY_NO_PROGRESS_BAR") != Ok("1".into())
/// By default, use the progress bar when we can detect we're running in a terminal.
/// `SENTRY_NO_PROGRESS_BAR` takes precedence and can be used to disable the progress bar
/// regardless of whether or not we're in a terminal.
pub fn use_progress_bar() -> bool {
if env::var("SENTRY_NO_PROGRESS_BAR") == Ok("1".into()) {
return false;
}
std::io::stdout().is_terminal() && std::io::stderr().is_terminal()
}

/// Wrapper that optionally holds a progress bar.
/// If there's a progress bar, forward calls to it.
/// Otherwise, forward messages to `log` calls.
pub struct ProgressBar {
inner: Arc<indicatif::ProgressBar>,
inner: Option<Arc<indicatif::ProgressBar>>,
start: Instant,
prefix: Option<String>,
}

impl ProgressBar {
pub fn new(len: usize) -> Self {
if is_progress_bar_visible() {
indicatif::ProgressBar::new(len as u64).into()
if use_progress_bar() {
Self::from_indicatif(indicatif::ProgressBar::new(len as u64))
} else {
Self::hidden()
Self::no_progress_bar()
}
}

pub fn new_spinner() -> Self {
if is_progress_bar_visible() {
indicatif::ProgressBar::new_spinner().into()
if use_progress_bar() {
Self::from_indicatif(indicatif::ProgressBar::new_spinner())
} else {
Self::hidden()
Self::no_progress_bar()
}
}

pub fn hidden() -> Self {
indicatif::ProgressBar::hidden().into()
fn from_indicatif(pb: indicatif::ProgressBar) -> Self {
let inner = Arc::new(pb);
logging::set_progress_bar(Some(Arc::downgrade(&inner)));
ProgressBar {
inner: Some(inner),
start: Instant::now(),
prefix: None,
}
}

fn no_progress_bar() -> Self {
ProgressBar {
inner: None,
start: Instant::now(),
prefix: None,
}
}

pub fn finish_with_duration(&self, op: &str) {
let dur = self.start.elapsed();
// We could use `dur.as_secs_f64()`, but its unnecessarily precise (micros). Millis are enough for our purpose.
let msg = format!("{op} completed in {}s", dur.as_millis() as f64 / 1000.0);
let progress_style = ProgressStyle::default_bar().template("{prefix:.dim} {msg}");
self.inner.set_style(progress_style);
self.inner.set_prefix(">");
self.inner.finish_with_message(&msg);
logging::set_progress_bar(None);

if let Some(inner) = &self.inner {
let progress_style = ProgressStyle::default_bar().template("{prefix:.dim} {msg}");
inner.set_style(progress_style);
inner.set_prefix(">");
inner.finish_with_message(&msg);
logging::set_progress_bar(None);
} else {
log::info!("> {msg}");
}
}

pub fn finish_and_clear(&self) {
self.inner.finish_and_clear();
logging::set_progress_bar(None);
if let Some(inner) = &self.inner {
inner.finish_and_clear();
logging::set_progress_bar(None);
}
}
}

impl From<indicatif::ProgressBar> for ProgressBar {
fn from(pb: indicatif::ProgressBar) -> Self {
let inner = Arc::new(pb);
logging::set_progress_bar(Some(Arc::downgrade(&inner)));
ProgressBar {
inner,
start: Instant::now(),
pub fn set_style(&self, style: ProgressStyle) {
if let Some(inner) = &self.inner {
inner.set_style(style);
}
}

pub fn set_message<S: AsRef<str>>(&self, msg: S) {
if let Some(inner) = &self.inner {
inner.set_message(msg.as_ref());
} else {
log::debug!(
"{}{}",
self.prefix
.as_deref()
.map(|s| format!("{s} "))
.unwrap_or_else(|| String::new()),
msg.as_ref()
);
}
}
}

impl Deref for ProgressBar {
type Target = indicatif::ProgressBar;
pub fn tick(&self) {
if let Some(inner) = &self.inner {
inner.tick();
}
}

fn deref(&self) -> &Self::Target {
&self.inner
pub fn set_prefix<S: AsRef<str>>(&mut self, prefix: S) {
if let Some(inner) = &self.inner {
inner.set_prefix(prefix.as_ref());
} else {
self.prefix = Some(prefix.as_ref().to_owned());
}
}

pub fn set_position(&self, pos: u64) {
if let Some(inner) = &self.inner {
inner.set_position(pos);
}
}

pub fn inc(&self, delta: u64) {
if let Some(inner) = &self.inner {
inner.inc(delta);
}
}

pub fn enable_steady_tick(&self, interval: u64) {
if let Some(inner) = &self.inner {
inner.enable_steady_tick(interval);
}
}
}

Expand Down
Loading