Skip to content

Commit 2932713

Browse files
committed
Use flag in Shell to track progress clearing.
1 parent 78ba948 commit 2932713

File tree

3 files changed

+38
-24
lines changed

3 files changed

+38
-24
lines changed

src/cargo/core/compiler/job_queue.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use jobserver::{Acquired, HelperThread};
1212
use log::{debug, info, trace};
1313

1414
use crate::core::profiles::Profile;
15-
use crate::core::{PackageId, Target, TargetKind, Verbosity};
15+
use crate::core::{PackageId, Target, TargetKind};
1616
use crate::handle_error;
1717
use crate::util;
1818
use crate::util::diagnostic_server::{self, DiagnosticPrinter};
@@ -289,14 +289,8 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
289289
};
290290

291291
for event in events {
292-
// CAUTION: Care must be taken to clear the progress bar if a
293-
// message is to be actually displayed. Try to avoid
294-
// unnecessarily clearing it to avoid flickering.
295292
match event {
296293
Message::Run(cmd) => {
297-
if cx.bcx.config.shell().verbosity() == Verbosity::Verbose {
298-
self.progress.clear();
299-
}
300294
cx.bcx
301295
.config
302296
.shell()
@@ -306,17 +300,14 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
306300
plan.update(&module_name, &cmd, &filenames)?;
307301
}
308302
Message::Stdout(out) => {
309-
self.progress.clear();
310303
println!("{}", out);
311304
}
312305
Message::Stderr(err) => {
313-
self.progress.clear();
314306
let mut shell = cx.bcx.config.shell();
315307
shell.print_ansi(err.as_bytes())?;
316308
shell.err().write_all(b"\n")?;
317309
}
318310
Message::FixDiagnostic(msg) => {
319-
self.progress.clear();
320311
print.print(&msg)?;
321312
}
322313
Message::Finish(key, result) => {
@@ -336,7 +327,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
336327
match result {
337328
Ok(()) => self.finish(key, cx)?,
338329
Err(e) => {
339-
self.progress.clear();
340330
let msg = "The following warnings were emitted during compilation:";
341331
self.emit_warnings(Some(msg), &key, cx)?;
342332

@@ -460,7 +450,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
460450
let bcx = &mut cx.bcx;
461451
if let Some(output) = output.get(&(key.pkg, key.kind)) {
462452
if !output.warnings.is_empty() {
463-
self.progress.clear();
464453
if let Some(msg) = msg {
465454
writeln!(bcx.config.shell().err(), "{}\n", msg)?;
466455
}
@@ -521,12 +510,10 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
521510
// Skip Doctest
522511
if !key.mode.is_any_test() {
523512
self.documented.insert(key.pkg);
524-
self.progress.clear();
525513
config.shell().status("Documenting", key.pkg)?;
526514
}
527515
} else {
528516
self.compiled.insert(key.pkg);
529-
self.progress.clear();
530517
if key.mode.is_check() {
531518
config.shell().status("Checking", key.pkg)?;
532519
} else {
@@ -540,9 +527,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
540527
&& !(key.mode == CompileMode::Doctest && self.compiled.contains(&key.pkg))
541528
{
542529
self.compiled.insert(key.pkg);
543-
if config.shell().verbosity() == Verbosity::Verbose {
544-
self.progress.clear();
545-
}
546530
config.shell().verbose(|c| c.status("Fresh", key.pkg))?;
547531
}
548532
}

src/cargo/core/shell.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ pub struct Shell {
2323
err: ShellOut,
2424
/// How verbose messages should be
2525
verbosity: Verbosity,
26+
/// Flag that indicates the current line needs to be cleared before
27+
/// printing. Used when a progress bar is currently displayed.
28+
needs_clear: bool,
2629
}
2730

2831
impl fmt::Debug for Shell {
@@ -75,6 +78,7 @@ impl Shell {
7578
tty: atty::is(atty::Stream::Stderr),
7679
},
7780
verbosity: Verbosity::Verbose,
81+
needs_clear: false,
7882
}
7983
}
8084

@@ -83,6 +87,7 @@ impl Shell {
8387
Shell {
8488
err: ShellOut::Write(out),
8589
verbosity: Verbosity::Verbose,
90+
needs_clear: false,
8691
}
8792
}
8893

@@ -97,10 +102,25 @@ impl Shell {
97102
) -> CargoResult<()> {
98103
match self.verbosity {
99104
Verbosity::Quiet => Ok(()),
100-
_ => self.err.print(status, message, color, justified),
105+
_ => {
106+
if self.needs_clear {
107+
self.err_erase_line();
108+
}
109+
self.err.print(status, message, color, justified)
110+
}
101111
}
102112
}
103113

114+
/// Set whether or not the next print should clear the current line.
115+
pub fn set_needs_clear(&mut self, needs_clear: bool) {
116+
self.needs_clear = needs_clear;
117+
}
118+
119+
/// True if the `needs_clear` flag is not set.
120+
pub fn is_cleared(&self) -> bool {
121+
!self.needs_clear
122+
}
123+
104124
/// Returns the width of the terminal in spaces, if any
105125
pub fn err_width(&self) -> Option<usize> {
106126
match self.err {
@@ -119,13 +139,17 @@ impl Shell {
119139

120140
/// Get a reference to the underlying writer
121141
pub fn err(&mut self) -> &mut dyn Write {
142+
if self.needs_clear {
143+
self.err_erase_line();
144+
}
122145
self.err.as_write()
123146
}
124147

125148
/// Erase from cursor to end of line.
126149
pub fn err_erase_line(&mut self) {
127150
if let ShellOut::Stream { tty: true, .. } = self.err {
128151
imp::err_erase_line(self);
152+
self.needs_clear = false;
129153
}
130154
}
131155

@@ -251,6 +275,9 @@ impl Shell {
251275

252276
/// Prints a message and translates ANSI escape code into console colors.
253277
pub fn print_ansi(&mut self, message: &[u8]) -> CargoResult<()> {
278+
if self.needs_clear {
279+
self.err_erase_line();
280+
}
254281
#[cfg(windows)]
255282
{
256283
if let ShellOut::Stream { stream, .. } = &mut self.err {
@@ -361,7 +388,7 @@ mod imp {
361388
// This is the "EL - Erase in Line" sequence. It clears from the cursor
362389
// to the end of line.
363390
// https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
364-
let _ = shell.err().write_all(b"\x1B[K");
391+
let _ = shell.err.as_write().write_all(b"\x1B[K");
365392
}
366393
}
367394

@@ -434,6 +461,6 @@ mod imp {
434461
fn default_err_erase_line(shell: &mut Shell) {
435462
if let Some(max_width) = imp::stderr_width() {
436463
let blank = " ".repeat(max_width);
437-
drop(write!(shell.err(), "{}\r", blank));
464+
drop(write!(shell.err.as_write(), "{}\r", blank));
438465
}
439466
}

src/cargo/util/progress.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,21 @@ impl<'cfg> State<'cfg> {
195195
}
196196

197197
// Only update if the line has changed.
198-
if self.last_line.as_ref() != Some(&line) {
199-
self.config.shell().status_header(&self.name)?;
200-
write!(self.config.shell().err(), "{}\r", line)?;
198+
if self.config.shell().is_cleared() || self.last_line.as_ref() != Some(&line) {
199+
let mut shell = self.config.shell();
200+
shell.set_needs_clear(false);
201+
shell.status_header(&self.name)?;
202+
write!(shell.err(), "{}\r", line)?;
201203
self.last_line = Some(line);
204+
shell.set_needs_clear(true);
202205
}
203206

204207
Ok(())
205208
}
206209

207210
fn clear(&mut self) {
208211
// No need to clear if the progress is not currently being displayed.
209-
if self.last_line.is_some() {
212+
if self.last_line.is_some() && !self.config.shell().is_cleared() {
210213
self.config.shell().err_erase_line();
211214
self.last_line = None;
212215
}

0 commit comments

Comments
 (0)