Skip to content

Add progress bar to artifact downloads#182836

Open
Mr-Pepe wants to merge 4 commits intoflutter:masterfrom
Mr-Pepe:02-24-add_progress_bar_to_artifact_download
Open

Add progress bar to artifact downloads#182836
Mr-Pepe wants to merge 4 commits intoflutter:masterfrom
Mr-Pepe:02-24-add_progress_bar_to_artifact_download

Conversation

@Mr-Pepe
Copy link
Contributor

@Mr-Pepe Mr-Pepe commented Feb 24, 2026

Follow-up to #181808
Resolves #14268

Adds a new DownloadProgress class that contains the logic for tracking and formatting download progress, i.e., a progress bar, % display, download speed, and ETA.

The rest is mostly ANSI control logic.

Bumped the width of the lines to 80 characters.

Before:
image

After:
image

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added the tool Affects the "flutter" command-line tool. See also t: labels. label Feb 24, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a progress bar for artifact downloads, enhancing the user experience by providing more detailed feedback on download status, including percentage, speed, and ETA. A new DownloadProgress class encapsulates the logic for tracking and formatting this information. The changes are well-tested, with new unit tests for the DownloadProgress class and integration tests for the ArtifactUpdater. The implementation correctly falls back to the previous spinner-based progress display on terminals that do not support the new progress bar.

The changes look good overall. I have a few minor suggestions to improve documentation and code readability.

@Mr-Pepe Mr-Pepe force-pushed the 02-24-add_progress_bar_to_artifact_download branch 3 times, most recently from 91a3241 to 3af15e1 Compare February 25, 2026 21:44
@Mr-Pepe
Copy link
Contributor Author

Mr-Pepe commented Feb 28, 2026

Had another look at this and think this is ready for review.

To test this, check out the branch and rm -rf bin/cache/flutter_tools.stamp && bin/flutter precache -f -a

@bkonyi and @jtmcdole because you reviewed my last PR improving the progress display.

@bkonyi bkonyi self-requested a review March 2, 2026 16:40
Copy link
Contributor

@bkonyi bkonyi left a comment

Choose a reason for hiding this comment

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

This looks great! I've been wanting this for years 😁

Just a few minor comments from me.

var downloadCompleted = false;
Status? status;

if (_canShowProgress) {
Copy link
Member

Choose a reason for hiding this comment

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

Any chance we could extract the "canShowProgress" and not-show-progress to its own classes? That way this logic is just about downloading the archive and anything you need for progress line can be ignored in the non-progress line abstraction?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. This adds an extra abstraction layer but keeps the ArtifactUpdater nice and clean 👍

while (retries > 0) {
status = _logger.startProgress(formattedMessage);
final progress = DownloadProgress();
final downloadStopwatch = Stopwatch()..start();
Copy link
Member

Choose a reason for hiding this comment

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

You never stop this if !_canShowProgress

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

return Duration(milliseconds: (timeRemainingBytes * 1000 / speed).round());
}

static const _subBlocks = ['▏', '▎', '▍', '▌', '▋', '▊', '▉'];
Copy link
Member

Choose a reason for hiding this comment

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

nit: surprised you didn't use ' ' at the start and just use -1 rather than remainder > 0 ? 1 : 0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, if I understood you correctly.

Copy link
Member

Choose a reason for hiding this comment

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

Close, I was thinking:

 ['', '▏', '▎', '▍', '▌', '▋', '▊', '▉']

 // then below you just use remainder:

 _subBlocks[remainder]

I guess you could use ' ' since emptyBlocks assumes a partial takes up some space. This is how I've done it in the past for progress bars.

@Mr-Pepe Mr-Pepe force-pushed the 02-24-add_progress_bar_to_artifact_download branch from 3af15e1 to 6f05141 Compare March 12, 2026 13:51
@Mr-Pepe
Copy link
Contributor Author

Mr-Pepe commented Mar 12, 2026

Thanks for your reviews! I hope I have addressed all the points.

I think the fallback display without progress bar could still be improved but it's probably not worth it.

bkonyi
bkonyi previously approved these changes Mar 12, 2026
Copy link
Contributor

@bkonyi bkonyi left a comment

Choose a reason for hiding this comment

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

LGTM!

/// - [_ProgressBarDisplay]: ANSI progress bar for terminals with color support.
/// - [_SpinnerDisplay]: Spinner-based display via [Logger.startProgress].
abstract class _DownloadDisplay {
void start();
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: these function declarations could use some basic documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

@bkonyi bkonyi added the CICD Run CI/CD label Mar 16, 2026
@bkonyi bkonyi added CICD Run CI/CD and removed CICD Run CI/CD labels Mar 16, 2026
@jtmcdole jtmcdole self-requested a review March 16, 2026 16:17
Copy link
Member

@jtmcdole jtmcdole left a comment

Choose a reason for hiding this comment

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

LGTM with clarity on the nit.

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

Labels

CICD Run CI/CD tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Downloading lines for flutter doctor should display information

3 participants