Skip to content

Commit

Permalink
[2/n] [update-engine] add ( to the beginning of step indexes in the…
Browse files Browse the repository at this point in the history
… line displayer (#6447)

This was reported by @wfchandler -- not sure why I missed these
originally.

Also move the step index display logic out into its own displayer -- I need
this (including the padded logic) in a couple of spots.

This can be landed separately from #6444.

Some example output from `cargo run --example update-engine-basic -- -s line`:

```
[00:00:00]   Running (1/7) Downloading component: https://www.example.org
[00:00:00]  Progress (1/7) Downloading component: https://www.example.org: 12.50% ( 131072/1048576 bytes) after 101.22ms
[00:00:00]  Progress (1/7) Downloading component: https://www.example.org: 25.00% ( 262144/1048576 bytes) after 201.49ms
[00:00:00]     Retry (1/7) Downloading component: https://www.example.org: after 302.77ms (at attempt 1) with message: Simulated failure at 25%
[00:00:00]  Progress (1/7) Downloading component: https://www.example.org:  0.00% (      0/1048576 bytes) after 101.37ms
[00:00:00]  Progress (1/7) Downloading component: https://www.example.org: 10.00% ( 104857/1048576 bytes) after 201.61ms
[00:00:00]  Progress (1/7) Downloading component: https://www.example.org: 20.00% ( 209715/1048576 bytes) after 302.86ms
[00:00:00]  Progress (1/7) Downloading component: https://www.example.org: 30.00% ( 314572/1048576 bytes) after 404.14ms
```
  • Loading branch information
sunshowers authored and hawkw committed Aug 31, 2024
1 parent acae8ef commit 862414a
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 26 deletions.
13 changes: 8 additions & 5 deletions update-engine/src/display/group_display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use swrite::{swrite, SWrite};
use unicode_width::UnicodeWidthStr;

use crate::{
errors::UnknownReportKey, events::EventReport, EventBuffer,
ExecutionStatus, ExecutionTerminalInfo, StepSpec, TerminalKind,
display::ProgressRatioDisplay, errors::UnknownReportKey,
events::EventReport, EventBuffer, ExecutionStatus, ExecutionTerminalInfo,
StepSpec, TerminalKind,
};

use super::{
Expand Down Expand Up @@ -309,11 +310,13 @@ impl GroupDisplayStats {
};

swrite!(line, "{:>HEADER_WIDTH$} ", header.style(header_style));
let terminal_count = self.terminal_count();
swrite!(
line,
"{terminal_count}/{}: {} running, {} {}",
self.total,
"{}: {} running, {} {}",
ProgressRatioDisplay::current_and_total(
self.terminal_count(),
self.total
),
self.running.style(formatter.styles().meta_style),
self.completed.style(formatter.styles().meta_style),
"completed".style(formatter.styles().progress_style),
Expand Down
26 changes: 14 additions & 12 deletions update-engine/src/display/line_display_shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use owo_colors::OwoColorize;
use swrite::{swrite, SWrite as _};

use crate::{
display::ProgressRatioDisplay,
events::{
ProgressCounter, ProgressEvent, ProgressEventKind, StepEvent,
StepEventKind, StepInfo, StepOutcome,
Expand Down Expand Up @@ -633,10 +634,12 @@ fn format_progress_counter(counter: &ProgressCounter) -> String {
let percent = (counter.current as f64 / total as f64) * 100.0;
// <12.34> is 5 characters wide.
let percent_width = 5;
let counter_width = total.to_string().len();
format!(
"{:>percent_width$.2}% ({:>counter_width$}/{} {})",
percent, counter.current, total, counter.units,
"{:>percent_width$.2}% ({} {})",
percent,
ProgressRatioDisplay::current_and_total(counter.current, total)
.padded(true),
counter.units,
)
}
None => format!("{} {}", counter.current, counter.units),
Expand Down Expand Up @@ -716,17 +719,16 @@ impl LineDisplayFormatter {
) {
ld_step_info.nest_data.add_prefix(line);

// Print out "<step index>/<total steps>)". Leave space such that we
// print out e.g. "1/8)" and " 3/14)".
// Add 1 to the index to make it 1-based.
let step_index = ld_step_info.step_info.index + 1;
let step_index_width = ld_step_info.total_steps.to_string().len();
// Print out "(<current>/<total>)" in a padded way, so that successive
// steps are vertically aligned.
swrite!(
line,
"{:width$}/{:width$}) ",
step_index,
ld_step_info.total_steps,
width = step_index_width
"({}) ",
ProgressRatioDisplay::index_and_total(
ld_step_info.step_info.index,
ld_step_info.total_steps
)
.padded(true),
);

swrite!(
Expand Down
3 changes: 3 additions & 0 deletions update-engine/src/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
//! * [`LineDisplay`]: a line-oriented display suitable for the command line.
//! * [`GroupDisplay`]: manages state and shows the results of several
//! [`LineDisplay`]s at once.
//! * Some utility displayers which can be used to build custom displayers.
mod group_display;
mod line_display;
mod line_display_shared;
mod utils;

pub use group_display::GroupDisplay;
pub use line_display::{LineDisplay, LineDisplayStyles};
use line_display_shared::*;
pub use utils::*;
108 changes: 108 additions & 0 deletions update-engine/src/display/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Utility displayers.
use std::fmt;

/// Given current and total, displays `{current}/{total}`.
///
/// * If the `index_and_total` constructor is called, then `current` is `index
/// + 1`.
/// * If `padded` is `true`, `current` is right-aligned and padded with spaces
/// to the width of `total`.
///
/// # Examples
///
/// ```
/// use update_engine::display::ProgressRatioDisplay;
///
/// // 0-based index and total.
/// let display = ProgressRatioDisplay::index_and_total(0 as u64, 8 as u64);
/// assert_eq!(display.to_string(), "1/8");
///
/// // 1-based current and total.
/// let display = ProgressRatioDisplay::current_and_total(82 as u64, 230 as u64);
/// assert_eq!(display.to_string(), "82/230");
///
/// // With padding.
/// let display = display.padded(true);
/// assert_eq!(display.to_string(), " 82/230");
/// ```
#[derive(Debug)]
pub struct ProgressRatioDisplay {
current: u64,
total: u64,
padded: bool,
}

impl ProgressRatioDisplay {
/// Create a new `ProgressRatioDisplay` with current and total values.
///
/// `current` is considered to be 1-based. For example, "20/80 jobs done".
pub fn current_and_total<T: ToU64>(current: T, total: T) -> Self {
Self { current: current.to_u64(), total: total.to_u64(), padded: false }
}

/// Create a new `ProgressRatioDisplay` with index and total values.
///
/// The index is 0-based (i.e. 1 is added to it). For example, step index 0
/// out of 8 total steps is shown as "1/8".
pub fn index_and_total<T: ToU64>(index: T, total: T) -> Self {
Self {
current: index
.to_u64()
.checked_add(1)
.expect("index can't be u64::MAX"),
total: total.to_u64(),
padded: false,
}
}

/// If set to true, the current value is padded to the same width as the
/// total.
pub fn padded(self, padded: bool) -> Self {
Self { padded, ..self }
}
}

impl fmt::Display for ProgressRatioDisplay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.padded {
let width = self.total.to_string().len();
write!(f, "{:>width$}/{}", self.current, self.total)
} else {
write!(f, "{}/{}", self.current, self.total)
}
}
}

/// Trait that abstracts over `usize` and `u64`.
///
/// There are no `From` implementations between `usize` and `u64`, but we
/// assert below that all the architectures we support are 64-bit.
pub trait ToU64 {
fn to_u64(self) -> u64;
}

const _: () = {
assert!(
std::mem::size_of::<usize>() == std::mem::size_of::<u64>(),
"usize and u64 are the same size"
);
};

impl ToU64 for usize {
#[inline]
fn to_u64(self) -> u64 {
self as u64
}
}

impl ToU64 for u64 {
#[inline]
fn to_u64(self) -> u64 {
self
}
}
25 changes: 16 additions & 9 deletions wicket/src/ui/panes/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use ratatui::widgets::{
use ratatui::Frame;
use slog::{info, o, Logger};
use tui_tree_widget::{Tree, TreeItem, TreeState};
use update_engine::display::ProgressRatioDisplay;
use update_engine::{
AbortReason, CompletionReason, ExecutionStatus, FailureReason, StepKey,
TerminalKind, WillNotBeRunReason,
Expand Down Expand Up @@ -1984,9 +1985,11 @@ impl ComponentUpdateListState {
));
status_text.push(Span::styled(
format!(
" (step {}/{})",
step_key.index + 1,
summary.total_steps,
" (step {})",
ProgressRatioDisplay::index_and_total(
step_key.index,
summary.total_steps,
)
),
style::plain_text(),
));
Expand Down Expand Up @@ -2015,9 +2018,11 @@ impl ComponentUpdateListState {
));
status_text.push(Span::styled(
format!(
" at step {}/{}",
info.step_key.index + 1,
summary.total_steps,
" at step {}",
ProgressRatioDisplay::index_and_total(
info.step_key.index,
summary.total_steps,
)
),
style::plain_text(),
));
Expand All @@ -2033,9 +2038,11 @@ impl ComponentUpdateListState {
));
status_text.push(Span::styled(
format!(
" at step {}/{}",
info.step_key.index + 1,
summary.total_steps,
" at step {}",
ProgressRatioDisplay::index_and_total(
info.step_key.index,
summary.total_steps,
)
),
style::plain_text(),
));
Expand Down

0 comments on commit 862414a

Please sign in to comment.