@@ -16,11 +16,14 @@ use super::{
16
16
unit_output:: TestOutputDisplay ,
17
17
} ;
18
18
use crate :: {
19
+ cargo_config:: CargoConfigs ,
19
20
config:: { CompiledDefaultFilter , LeakTimeoutResult , ScriptId } ,
20
21
errors:: WriteEventError ,
21
22
helpers:: { DisplayScriptInstance , DisplayTestInstance , plural} ,
22
23
list:: { TestInstance , TestInstanceId } ,
23
- reporter:: { events:: * , helpers:: Styles , imp:: ReporterStderr } ,
24
+ reporter:: {
25
+ displayer:: progress:: TerminalProgress , events:: * , helpers:: Styles , imp:: ReporterStderr ,
26
+ } ,
24
27
} ;
25
28
use debug_ignore:: DebugIgnore ;
26
29
use indent_write:: io:: IndentWriter ;
@@ -46,7 +49,11 @@ pub(crate) struct DisplayReporterBuilder {
46
49
}
47
50
48
51
impl DisplayReporterBuilder {
49
- pub ( crate ) fn build ( self , output : ReporterStderr < ' _ > ) -> DisplayReporter < ' _ > {
52
+ pub ( crate ) fn build < ' a > (
53
+ self ,
54
+ configs : & CargoConfigs ,
55
+ output : ReporterStderr < ' a > ,
56
+ ) -> DisplayReporter < ' a > {
50
57
let mut styles: Box < Styles > = Box :: default ( ) ;
51
58
if self . should_colorize {
52
59
styles. colorize ( ) ;
@@ -72,31 +79,37 @@ impl DisplayReporterBuilder {
72
79
}
73
80
74
81
let stderr = match output {
75
- ReporterStderr :: Terminal if self . no_capture => {
76
- // Do not use a progress bar if --no-capture is passed in. This is required since we
77
- // pass down stderr to the child process.
78
- //
79
- // In the future, we could potentially switch to using a pty, in which case we could
80
- // still potentially use the progress bar as a status bar. However, that brings
81
- // about its own complications: what if a test's output doesn't include a newline?
82
- // We might have to use a curses-like UI which would be a lot of work for not much
83
- // gain.
84
- ReporterStderrImpl :: TerminalWithoutBar
85
- }
86
- ReporterStderr :: Terminal if is_ci:: uncached ( ) => {
87
- // Some CI environments appear to pretend to be a terminal. Disable the progress bar
88
- // in these environments.
89
- ReporterStderrImpl :: TerminalWithoutBar
90
- }
91
- ReporterStderr :: Terminal if self . hide_progress_bar => {
92
- ReporterStderrImpl :: TerminalWithoutBar
93
- }
94
-
95
82
ReporterStderr :: Terminal => {
96
- let state = ProgressBarState :: new ( self . test_count , theme_characters. progress_chars ) ;
97
- // Note: even if we create a progress bar here, if stderr is
98
- // piped, indicatif will not show it.
99
- ReporterStderrImpl :: TerminalWithBar { state }
83
+ let progress_bar = if self . no_capture {
84
+ // Do not use a progress bar if --no-capture is passed in.
85
+ // This is required since we pass down stderr to the child
86
+ // process.
87
+ //
88
+ // In the future, we could potentially switch to using a
89
+ // pty, in which case we could still potentially use the
90
+ // progress bar as a status bar. However, that brings about
91
+ // its own complications: what if a test's output doesn't
92
+ // include a newline? We might have to use a curses-like UI
93
+ // which would be a lot of work for not much gain.
94
+ None
95
+ } else if is_ci:: uncached ( ) {
96
+ // Some CI environments appear to pretend to be a terminal.
97
+ // Disable the progress bar in these environments.
98
+ None
99
+ } else if self . hide_progress_bar {
100
+ None
101
+ } else {
102
+ let state =
103
+ ProgressBarState :: new ( self . test_count , theme_characters. progress_chars ) ;
104
+ // Note: even if we create a progress bar here, if stderr is
105
+ // piped, indicatif will not show it.
106
+ Some ( state)
107
+ } ;
108
+ let term_progress = TerminalProgress :: new ( configs, & io:: stderr ( ) ) ;
109
+ ReporterStderrImpl :: Terminal {
110
+ progress_bar,
111
+ term_progress,
112
+ }
100
113
}
101
114
ReporterStderr :: Buffer ( buf) => ReporterStderrImpl :: Buffer ( buf) ,
102
115
} ;
@@ -142,23 +155,37 @@ pub(crate) struct DisplayReporter<'a> {
142
155
impl < ' a > DisplayReporter < ' a > {
143
156
pub ( crate ) fn write_event ( & mut self , event : & TestEvent < ' a > ) -> Result < ( ) , WriteEventError > {
144
157
match & mut self . stderr {
145
- ReporterStderrImpl :: TerminalWithBar { state } => {
146
- // Write to a string that will be printed as a log line.
147
- let mut buf: Vec < u8 > = Vec :: new ( ) ;
148
- self . inner
149
- . write_event_impl ( event, & mut buf)
150
- . map_err ( WriteEventError :: Io ) ?;
151
-
152
- state. update_progress_bar ( event, & self . inner . styles ) ;
153
- state. write_buf ( & buf) . map_err ( WriteEventError :: Io )
154
- }
155
- ReporterStderrImpl :: TerminalWithoutBar => {
156
- // Write to a buffered stderr.
157
- let mut writer = BufWriter :: new ( std:: io:: stderr ( ) ) ;
158
- self . inner
159
- . write_event_impl ( event, & mut writer)
160
- . map_err ( WriteEventError :: Io ) ?;
161
- writer. flush ( ) . map_err ( WriteEventError :: Io )
158
+ ReporterStderrImpl :: Terminal {
159
+ progress_bar,
160
+ term_progress,
161
+ } => {
162
+ if let Some ( state) = progress_bar {
163
+ // Write to a string that will be printed as a log line.
164
+ let mut buf: Vec < u8 > = Vec :: new ( ) ;
165
+ self . inner
166
+ . write_event_impl ( event, & mut buf)
167
+ . map_err ( WriteEventError :: Io ) ?;
168
+
169
+ state. update_progress_bar ( event, & self . inner . styles ) ;
170
+ if let Some ( term_progress) = term_progress {
171
+ term_progress
172
+ . update_progress ( event, & mut buf)
173
+ . map_err ( WriteEventError :: Io ) ?;
174
+ }
175
+ state. write_buf ( & buf) . map_err ( WriteEventError :: Io )
176
+ } else {
177
+ // Write to a buffered stderr.
178
+ let mut writer = BufWriter :: new ( std:: io:: stderr ( ) ) ;
179
+ self . inner
180
+ . write_event_impl ( event, & mut writer)
181
+ . map_err ( WriteEventError :: Io ) ?;
182
+ if let Some ( state) = term_progress {
183
+ state
184
+ . update_progress ( event, & mut writer)
185
+ . map_err ( WriteEventError :: Io ) ?;
186
+ }
187
+ writer. flush ( ) . map_err ( WriteEventError :: Io )
188
+ }
162
189
}
163
190
ReporterStderrImpl :: Buffer ( buf) => self
164
191
. inner
@@ -173,21 +200,26 @@ impl<'a> DisplayReporter<'a> {
173
200
}
174
201
175
202
enum ReporterStderrImpl < ' a > {
176
- TerminalWithBar {
177
- // Reporter-specific progress bar state.
178
- state : ProgressBarState ,
203
+ Terminal {
204
+ // Reporter-specific progress bar state. None if the progress bar is not
205
+ // enabled.
206
+ progress_bar : Option < ProgressBarState > ,
207
+ // OSC 9 code progress reporting.
208
+ term_progress : Option < TerminalProgress > ,
179
209
} ,
180
- TerminalWithoutBar ,
181
210
Buffer ( & ' a mut Vec < u8 > ) ,
182
211
}
183
212
184
213
impl ReporterStderrImpl < ' _ > {
185
214
fn finish_and_clear_bar ( & self ) {
186
215
match self {
187
- ReporterStderrImpl :: TerminalWithBar { state } => {
216
+ ReporterStderrImpl :: Terminal {
217
+ progress_bar : Some ( state) ,
218
+ ..
219
+ } => {
188
220
state. finish_and_clear ( ) ;
189
221
}
190
- ReporterStderrImpl :: TerminalWithoutBar | ReporterStderrImpl :: Buffer ( _) => { }
222
+ ReporterStderrImpl :: Terminal { .. } | ReporterStderrImpl :: Buffer ( _) => { }
191
223
}
192
224
}
193
225
@@ -512,6 +544,7 @@ impl<'a> DisplayReporterImpl<'a> {
512
544
}
513
545
TestEventKind :: RunBeginCancel {
514
546
setup_scripts_running,
547
+ current_stats : _,
515
548
running,
516
549
reason,
517
550
} => {
@@ -544,6 +577,7 @@ impl<'a> DisplayReporterImpl<'a> {
544
577
}
545
578
TestEventKind :: RunBeginKill {
546
579
setup_scripts_running,
580
+ current_stats : _,
547
581
running,
548
582
reason,
549
583
} => {
@@ -1794,6 +1828,7 @@ mod tests {
1794
1828
test_output:: { ChildExecutionOutput , ChildOutput , ChildSplitOutput } ,
1795
1829
} ;
1796
1830
use bytes:: Bytes ;
1831
+ use camino:: Utf8PathBuf ;
1797
1832
use chrono:: Local ;
1798
1833
use nextest_metadata:: RustBinaryId ;
1799
1834
use smol_str:: SmolStr ;
@@ -1806,6 +1841,18 @@ mod tests {
1806
1841
where
1807
1842
F : FnOnce ( DisplayReporter < ' a > ) ,
1808
1843
{
1844
+ // Start and end the search at the cwd -- we expect this to not match
1845
+ // any results since it'll be the nextest-runner directory.
1846
+ let current_dir = Utf8PathBuf :: try_from ( std:: env:: current_dir ( ) . expect ( "obtained cwd" ) )
1847
+ . expect ( "cwd is valid UTF_8" ) ;
1848
+ let configs = CargoConfigs :: new_with_isolation (
1849
+ Vec :: < String > :: new ( ) ,
1850
+ & current_dir,
1851
+ & current_dir,
1852
+ Vec :: new ( ) ,
1853
+ )
1854
+ . unwrap ( ) ;
1855
+
1809
1856
let builder = DisplayReporterBuilder {
1810
1857
default_filter : CompiledDefaultFilter :: for_default_config ( ) ,
1811
1858
status_levels : StatusLevels {
@@ -1821,7 +1868,7 @@ mod tests {
1821
1868
no_output_indent : false ,
1822
1869
} ;
1823
1870
let output = ReporterStderr :: Buffer ( out) ;
1824
- let reporter = builder. build ( output) ;
1871
+ let reporter = builder. build ( & configs , output) ;
1825
1872
f ( reporter) ;
1826
1873
}
1827
1874
0 commit comments