1
- use indicatif:: { ProgressBar , ProgressDrawTarget , ProgressStyle } ;
1
+ use indicatif:: { MultiProgress , ProgressBar , ProgressDrawTarget , ProgressStyle } ;
2
2
use std:: time:: Duration ;
3
3
4
4
use crate :: dist:: Notification as In ;
5
5
use crate :: notifications:: Notification ;
6
- use crate :: process:: Process ;
6
+ use crate :: process:: { Process , terminalsource :: ColorChoice } ;
7
7
use crate :: utils:: Notification as Un ;
8
8
9
9
/// Tracks download progress and displays information about it to a terminal.
@@ -14,16 +14,34 @@ pub(crate) struct DownloadTracker {
14
14
/// Whether we display progress or not.
15
15
display_progress : bool ,
16
16
stdout_is_a_tty : bool ,
17
- // Progress bar for the download.
17
+ /// Whether we display colors or not.
18
+ use_colors : bool ,
19
+ /// MultiProgress bar for the downloads.
20
+ multi_progress_bars : MultiProgress ,
21
+ /// ProgressBar for the current download.
18
22
progress_bar : ProgressBar ,
19
23
}
20
24
21
25
impl DownloadTracker {
22
26
/// Creates a new DownloadTracker.
23
27
pub ( crate ) fn new_with_display_progress ( display_progress : bool , process : & Process ) -> Self {
28
+ let t = process. stdout ( ) . terminal ( process) ;
29
+ let is_a_tty = t. is_a_tty ( ) ;
30
+ let use_colors = matches ! ( t. color_choice( ) , ColorChoice :: Auto | ColorChoice :: Always ) ;
31
+ let multi_progress_bars =
32
+ MultiProgress :: with_draw_target ( match process. var ( "RUSTUP_TERM_PROGRESS_WHEN" ) {
33
+ Ok ( s) if s. eq_ignore_ascii_case ( "always" ) => {
34
+ ProgressDrawTarget :: term_like ( Box :: new ( t) )
35
+ }
36
+ Ok ( s) if s. eq_ignore_ascii_case ( "never" ) => ProgressDrawTarget :: hidden ( ) ,
37
+ _ if is_a_tty => ProgressDrawTarget :: term_like ( Box :: new ( t) ) ,
38
+ _ => ProgressDrawTarget :: hidden ( ) ,
39
+ } ) ;
24
40
Self {
25
41
display_progress,
26
42
stdout_is_a_tty : process. stdout ( ) . is_a_tty ( process) ,
43
+ use_colors,
44
+ multi_progress_bars,
27
45
progress_bar : ProgressBar :: hidden ( ) ,
28
46
}
29
47
}
@@ -55,9 +73,11 @@ impl DownloadTracker {
55
73
pub ( crate ) fn content_length_received ( & mut self , content_len : u64 ) {
56
74
self . progress_bar . set_length ( content_len) ;
57
75
self . progress_bar . set_style (
58
- ProgressStyle :: with_template (
59
- "[{elapsed_precise}] [{bar:40.blue}] {bytes}/{total_bytes} (ETA: {eta})" ,
60
- )
76
+ ProgressStyle :: with_template ( if self . use_colors {
77
+ "[{elapsed_precise}] [{bar:40.blue}] {bytes}/{total_bytes} (ETA: {eta})"
78
+ } else {
79
+ "[{elapsed_precise}] [{bar:40}] {bytes}/{total_bytes} (ETA: {eta})"
80
+ } )
61
81
. unwrap ( )
62
82
. tick_chars ( "⠁⠂⠄⡀⢀⠠⠐⠈ " ) ,
63
83
) ;
@@ -70,15 +90,15 @@ impl DownloadTracker {
70
90
&& self . stdout_is_a_tty
71
91
&& self . progress_bar . elapsed ( ) >= Duration :: from_secs ( 1 )
72
92
{
73
- self . progress_bar
74
- . set_draw_target ( ProgressDrawTarget :: stdout ( ) ) ;
93
+ self . multi_progress_bars . add ( self . progress_bar . clone ( ) ) ;
75
94
}
76
95
self . progress_bar . inc ( len as u64 ) ;
77
96
}
78
97
79
98
/// Notifies self that the download has finished.
80
99
pub ( crate ) fn download_finished ( & mut self ) {
81
100
self . progress_bar . finish_and_clear ( ) ;
101
+ self . multi_progress_bars . remove ( & self . progress_bar ) ;
82
102
self . progress_bar = ProgressBar :: hidden ( ) ;
83
103
}
84
104
}
0 commit comments