Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit progress state escape codes #11436

Closed
Closed
Changes from all 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
39 changes: 39 additions & 0 deletions src/cargo/util/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct State<'cfg> {
throttle: Throttle,
last_line: Option<String>,
fixed_width: Option<usize>,
#[cfg(windows)] // Windows is the only currently supported platform
last_pbar: u8,
}

struct Format {
Expand All @@ -39,6 +41,26 @@ struct Format {
max_print: usize,
}

/// Which escape code to use for progress reporting.
///
/// There is more codes, but we only use these two.
#[cfg(windows)] // Windows is the only currently supported platform
enum ProgressCode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is Windows-only feature, right? Is it possible to add #[cfg(windows)] for all relevant code and items?

Also, having doc comments on each new items would be fantastic. Thanks!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think that other terminal emulators may also implement those, but I can't verify now.
It seems like per alacritty/alacritty#5201, it won't get this support, however.

None,
Normal(u8),
}

#[cfg(windows)] // Windows is the only currently supported platform
impl std::fmt::Display for ProgressCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let (state, progress) = match self {
Self::None => (0, 0),
Self::Normal(v) => (1, *v),
};
write!(f, "\x1b]9;4;{state};{progress}\x1b\\")
}
}

impl<'cfg> Progress<'cfg> {
pub fn with_style(name: &str, style: ProgressStyle, cfg: &'cfg Config) -> Progress<'cfg> {
// report no progress when -q (for quiet) or TERM=dumb are set
Expand Down Expand Up @@ -81,6 +103,8 @@ impl<'cfg> Progress<'cfg> {
throttle: Throttle::new(),
last_line: None,
fixed_width: progress_config.width,
#[cfg(windows)] // Windows is the only currently supported platform
last_pbar: u8::MAX,
}),
}
}
Expand Down Expand Up @@ -183,6 +207,8 @@ impl Throttle {
impl<'cfg> State<'cfg> {
fn tick(&mut self, cur: usize, max: usize, msg: &str) -> CargoResult<()> {
if self.done {
#[cfg(windows)] // Windows is the only currently supported platform
write!(self.config.shell().err(), "{}", ProgressCode::None)?;
return Ok(());
}

Expand All @@ -194,6 +220,14 @@ impl<'cfg> State<'cfg> {
// return back to the beginning of the line for the next print.
self.try_update_max_width();
if let Some(pbar) = self.format.progress(cur, max) {
#[cfg(windows)] // Windows is the only currently supported platform
{
let prog = ((cur as f32) / (max as f32) * 100.0) as u8;
if self.last_pbar != prog {
write!(self.config.shell().err(), "{}", ProgressCode::Normal(prog))?;
self.last_pbar = prog;
}
}
self.print(&pbar, msg)?;
}
Ok(())
Expand Down Expand Up @@ -232,6 +266,11 @@ impl<'cfg> State<'cfg> {
if self.last_line.is_some() && !self.config.shell().is_cleared() {
self.config.shell().err_erase_line();
self.last_line = None;
#[cfg(windows)] // Windows is the only currently supported platform
{
let _ = write!(self.config.shell().err(), "{}", ProgressCode::None);
self.last_pbar = u8::MAX;
}
}
}

Expand Down