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,35 @@ 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 = MultiProgress :: with_draw_target (
32
+ 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
+ }
40
+ ) ;
24
41
Self {
25
42
display_progress,
26
43
stdout_is_a_tty : process. stdout ( ) . is_a_tty ( process) ,
44
+ use_colors,
45
+ multi_progress_bars,
27
46
progress_bar : ProgressBar :: hidden ( ) ,
28
47
}
29
48
}
@@ -56,7 +75,11 @@ impl DownloadTracker {
56
75
self . progress_bar . set_length ( content_len) ;
57
76
self . progress_bar . set_style (
58
77
ProgressStyle :: with_template (
59
- "[{elapsed_precise}] [{bar:40.blue}] {bytes}/{total_bytes} (ETA: {eta})" ,
78
+ if self . use_colors {
79
+ "[{elapsed_precise}] [{bar:40.blue}] {bytes}/{total_bytes} (ETA: {eta})"
80
+ } else {
81
+ "[{elapsed_precise}] [{bar:40}] {bytes}/{total_bytes} (ETA: {eta})"
82
+ } ,
60
83
)
61
84
. unwrap ( )
62
85
. tick_chars ( "⠁⠂⠄⡀⢀⠠⠐⠈ " ) ,
@@ -70,15 +93,15 @@ impl DownloadTracker {
70
93
&& self . stdout_is_a_tty
71
94
&& self . progress_bar . elapsed ( ) >= Duration :: from_secs ( 1 )
72
95
{
73
- self . progress_bar
74
- . set_draw_target ( ProgressDrawTarget :: stdout ( ) ) ;
96
+ self . multi_progress_bars . add ( self . progress_bar . clone ( ) ) ;
75
97
}
76
98
self . progress_bar . inc ( len as u64 ) ;
77
99
}
78
100
79
101
/// Notifies self that the download has finished.
80
102
pub ( crate ) fn download_finished ( & mut self ) {
81
103
self . progress_bar . finish_and_clear ( ) ;
104
+ self . multi_progress_bars . remove ( & self . progress_bar ) ;
82
105
self . progress_bar = ProgressBar :: hidden ( ) ;
83
106
}
84
107
}
0 commit comments