Skip to content

Conversation

@fischeti
Copy link
Contributor

@fischeti fischeti commented Jan 1, 2026

CLI Progress bars

Adds progress bars to bender actions that require longer network access. A taste is shown below*

bender

*some style changes have been done since this recording.

Implementation

The progress bars are rendered with the crate indicatif, that allows rendering of multiple progress bars at once. The state of the progress bars is extracted from the stderr output of the spawned git commands i.e. a separate task is spawned alongside git tasks to parse git output lines and update the progress bar state. I initially thought about adopting the git2 crate, which would have built in progress callbacks. However, this would have been a larger change and also poses some challenges since those git tasks are not asynchronous and also credential handling would be more complicated, which is why I opted for stderr parsing in the end.

Related Changes

Apart from the implementation of the progress bars, some additional changes were necessary:

error macros

Previously, all messages were simply printed to stdout/stderr with println!/eprintln! without any specific order. Rendering the progress bars together with warning/error messaged caused unwanted artifacts. The reason is that the progress bar requires exclusive access over stdout/stderr, since it needs to clear lines again. If warning/error messages are sent in between, it might clear the warning/error message instead of the actual progress bar which is left behind as an artifact. For that matter, the MultiProgress instance can be suspended, which essentially means clearing all progress bars, writing the desired custom message to stdout/stderr and then redraw all the progress bars. This means the previous warnln!, errorln! etc., macros are now passed through the MultiProgress.suspend() function.

git spawns

  • Where appropriate the git spawn functions now accept a Option<ProgressHandler> argument. If None is passed, the behaviour is as before, whereas Some(pb) will add a new progress bar.
  • The git submodule update commands are only performed if a dependency contains a .gitmodules. Otherwise, too many no-op progress messages are spawned.

TODOs

  • Check more bender commands. I focused mostly on checkout, but others use the same underlying functions so there should not be an issue in theory.
  • Check output in log files (e.g. CI). In theory, this should work outside of the box.
  • Revert git throttling changes

@fischeti fischeti force-pushed the fischeti/progress-bar branch from 16b915a to 8b6b44e Compare January 2, 2026 19:22
@fischeti fischeti marked this pull request as ready for review January 3, 2026 09:47
@fischeti fischeti force-pushed the fischeti/progress-bar branch from e8fa8c5 to 35a73db Compare January 6, 2026 18:36
@fischeti fischeti marked this pull request as draft January 12, 2026 12:48
@fischeti fischeti force-pushed the fischeti/progress-bar branch 5 times, most recently from 0dfe99a to b02ae96 Compare January 19, 2026 15:26
First compiling version

sess: Fix compiler warnings

progress: Get rid of the `Sub` prefix for submodules

progress: Clean up a bit
git: Don't report progress when fetching tags

progress: Don't set length multiple times

progress: Refactor

progress: Don't allow clones of Progresshandlers

Clones of progress bars don't really work well after they were finished

git: Don't clone progress handler

Format sources
progress: Print duration of git operation

progress: Stylistic changes

progress: Add `Submodule` operations

progress: Improve time formatting

progress: Mention submodules in completed message

progress: Improve display for submodules

progress: Stylistic changes for submodules
error: Add formatting macros

error: Align `stageln` to other macros

error: Rename `Note` to `Info`
progress: Don't check for ASCII characters

progress: Change the order of functions, enums and impl blocks

progress: Clean up and document
@fischeti fischeti force-pushed the fischeti/progress-bar branch from fd145e3 to 995ee75 Compare January 19, 2026 16:05
@fischeti fischeti marked this pull request as ready for review January 19, 2026 16:08
Copy link
Member

@micprog micprog left a comment

Choose a reason for hiding this comment

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

Very nice feature, providing some insight into what bender is doing at the moment! Some comments below.

@fischeti fischeti force-pushed the fischeti/progress-bar branch 2 times, most recently from 62c0c8f to 0949dda Compare January 22, 2026 09:40
@fischeti
Copy link
Contributor Author

I should have addressed all the comments now. Additionally, I added the following:

  • 0949dda: All colored messages (e.g. stages, warnings etc.,) will now only be collored in environments that allow colors i.e. if NO_COLOR is not set in the environment. For instance bender command 2> command.log will not contain any ANSI codes anymore.
  • 2f884e5: I aligned the formatting of update command during manual version resolving to the ones introduced with progress bars and the diagnostics (This is also why the CLI regression test fails at the moment, since I removed the backticks when rendering paths.)
  • bd380f4: I changed to style of versions (cyan now) to differentiate it from the style of packages (white bold). I am not fully satisfied with the look tbh, so we can also revert this. Or if you have a better idea let me know.
  • bb71e62: Fixes an issue where stageln messages interfered with the progress bars. This was very rare but I noticed it a few times when symlinks were created for dependencies, while cloning was in progress. Now stageln always suspends the progress bars to fix this issue.

progress: Color in progress operations in cyan

progress: Reword in progress messages
Whenever we are not in a TTY/terminal (e.g. a CI), we don't actually
want to render the progress bar, but just print out the completion
messages in the end for the log.
Is now in the standard library
In newer versions of git, tags are automatically fetched if the belong
to the history of the reference that is fetched (i.e. a branch).
Fetching `--tags` is therefore in most cases a no-op, since tags have
been fetched in the first git operation. Only in the case where a
specific branch is fetched e.g. `git fetch origin my_branch`, fetching
additional tags from other branches could make sense. This is not the
case here, since we fetch the entire remote
@fischeti fischeti force-pushed the fischeti/progress-bar branch from 38ae3ac to dcf1660 Compare January 22, 2026 14:22
Copy link
Member

@micprog micprog left a comment

Choose a reason for hiding this comment

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

LGTM, thanks! 👍

@micprog
Copy link
Member

micprog commented Jan 22, 2026

CI failures look to be slight formatting adjustments in the parents command, which are OK to merge IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants