Skip to content

Commit 3ad6cb1

Browse files
committed
refactor(shell): Switch termcolor to anstream
1 parent 87ad274 commit 3ad6cb1

File tree

3 files changed

+54
-137
lines changed

3 files changed

+54
-137
lines changed

Cargo.lock

Lines changed: 2 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ edition = "2021"
1616
license = "MIT OR Apache-2.0"
1717

1818
[workspace.dependencies]
19-
anstream = "0.6.0"
19+
anstream = "0.6.1"
2020
anstyle = "1.0.4"
21-
anstyle-termcolor = "1.1.0"
2221
anyhow = "1.0.75"
2322
base64 = "0.21.3"
2423
bytesize = "1.3"
@@ -41,7 +40,6 @@ curl = "0.4.44"
4140
curl-sys = "0.4.66"
4241
filetime = "0.2.22"
4342
flate2 = { version = "1.0.27", default-features = false, features = ["zlib"] }
44-
fwdansi = "1.1.0"
4543
git2 = "0.18.0"
4644
git2-curl = "0.19.0"
4745
gix = { version = "0.54.1", default-features = false, features = ["blocking-http-transport-curl", "progress-tree", "revision"] }
@@ -91,7 +89,6 @@ snapbox = { version = "0.4.13", features = ["diff", "path"] }
9189
syn = { version = "2.0.29", features = ["extra-traits", "full"] }
9290
tar = { version = "0.4.40", default-features = false }
9391
tempfile = "3.8.0"
94-
termcolor = "1.2.0"
9592
thiserror = "1.0.47"
9693
time = { version = "0.3", features = ["parsing", "formatting", "serde"] }
9794
toml = "0.7.6"
@@ -124,7 +121,6 @@ path = "src/cargo/lib.rs"
124121

125122
[dependencies]
126123
anstream.workspace = true
127-
anstyle-termcolor.workspace = true
128124
anstyle.workspace = true
129125
anyhow.workspace = true
130126
base64.workspace = true
@@ -179,7 +175,6 @@ shell-escape.workspace = true
179175
syn.workspace = true
180176
tar.workspace = true
181177
tempfile.workspace = true
182-
termcolor.workspace = true
183178
time.workspace = true
184179
toml.workspace = true
185180
toml_edit.workspace = true
@@ -194,9 +189,6 @@ walkdir.workspace = true
194189
[target.'cfg(not(windows))'.dependencies]
195190
openssl = { workspace = true, optional = true }
196191

197-
[target.'cfg(windows)'.dependencies]
198-
fwdansi.workspace = true
199-
200192
[target.'cfg(windows)'.dependencies.windows-sys]
201193
workspace = true
202194
features = [

src/cargo/core/shell.rs

Lines changed: 51 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use std::fmt;
22
use std::io::prelude::*;
33
use std::io::IsTerminal;
44

5+
use anstream::AutoStream;
6+
use anstream::Buffer;
57
use anstyle::Style;
6-
use anstyle_termcolor::to_termcolor_spec;
7-
use termcolor::{self, BufferWriter, StandardStream, WriteColor};
88

99
use crate::util::errors::CargoResult;
1010
use crate::util::style::*;
@@ -86,10 +86,8 @@ enum ShellOut {
8686
/// corresponding stream. The non-buffered fields should be used when you
8787
/// do not want content to be buffered.
8888
Stream {
89-
stdout: StandardStream,
90-
buffered_stdout: BufferWriter,
91-
stderr: StandardStream,
92-
buffered_stderr: BufferWriter,
89+
stdout: AutoStream<std::io::Stdout>,
90+
stderr: AutoStream<std::io::Stderr>,
9391
stderr_tty: bool,
9492
color_choice: ColorChoice,
9593
},
@@ -111,15 +109,13 @@ impl Shell {
111109
/// output.
112110
pub fn new() -> Shell {
113111
let auto_clr = ColorChoice::CargoAuto;
114-
let stdout_choice = auto_clr.to_termcolor_color_choice(Stream::Stdout);
115-
let stderr_choice = auto_clr.to_termcolor_color_choice(Stream::Stderr);
112+
let stdout_choice = auto_clr.to_anstream_color_choice();
113+
let stderr_choice = auto_clr.to_anstream_color_choice();
116114
Shell {
117115
output: ShellOut::Stream {
118-
stdout: StandardStream::stdout(stdout_choice),
119-
buffered_stdout: BufferWriter::stdout(stdout_choice),
120-
stderr: StandardStream::stderr(stderr_choice),
121-
buffered_stderr: BufferWriter::stderr(stderr_choice),
122-
color_choice: ColorChoice::CargoAuto,
116+
stdout: AutoStream::new(std::io::stdout(), stdout_choice),
117+
stderr: AutoStream::new(std::io::stderr(), stderr_choice),
118+
color_choice: auto_clr,
123119
stderr_tty: std::io::stderr().is_terminal(),
124120
},
125121
verbosity: Verbosity::Verbose,
@@ -297,9 +293,7 @@ impl Shell {
297293
pub fn set_color_choice(&mut self, color: Option<&str>) -> CargoResult<()> {
298294
if let ShellOut::Stream {
299295
ref mut stdout,
300-
ref mut buffered_stdout,
301296
ref mut stderr,
302-
ref mut buffered_stderr,
303297
ref mut color_choice,
304298
..
305299
} = self.output
@@ -317,12 +311,10 @@ impl Shell {
317311
),
318312
};
319313
*color_choice = cfg;
320-
let stdout_choice = cfg.to_termcolor_color_choice(Stream::Stdout);
321-
let stderr_choice = cfg.to_termcolor_color_choice(Stream::Stderr);
322-
*stdout = StandardStream::stdout(stdout_choice);
323-
*buffered_stdout = BufferWriter::stdout(stdout_choice);
324-
*stderr = StandardStream::stderr(stderr_choice);
325-
*buffered_stderr = BufferWriter::stderr(stderr_choice);
314+
let stdout_choice = cfg.to_anstream_color_choice();
315+
let stderr_choice = cfg.to_anstream_color_choice();
316+
*stdout = AutoStream::new(std::io::stdout(), stdout_choice);
317+
*stderr = AutoStream::new(std::io::stderr(), stderr_choice);
326318
}
327319
Ok(())
328320
}
@@ -342,14 +334,14 @@ impl Shell {
342334
pub fn err_supports_color(&self) -> bool {
343335
match &self.output {
344336
ShellOut::Write(_) => false,
345-
ShellOut::Stream { stderr, .. } => stderr.supports_color(),
337+
ShellOut::Stream { stderr, .. } => supports_color(stderr.current_choice()),
346338
}
347339
}
348340

349341
pub fn out_supports_color(&self) -> bool {
350342
match &self.output {
351343
ShellOut::Write(_) => false,
352-
ShellOut::Stream { stdout, .. } => stdout.supports_color(),
344+
ShellOut::Stream { stdout, .. } => supports_color(stdout.current_choice()),
353345
}
354346
}
355347

@@ -372,13 +364,6 @@ impl Shell {
372364
if self.needs_clear {
373365
self.err_erase_line();
374366
}
375-
#[cfg(windows)]
376-
{
377-
if let ShellOut::Stream { stderr, .. } = &mut self.output {
378-
::fwdansi::write_ansi(stderr, message)?;
379-
return Ok(());
380-
}
381-
}
382367
self.err().write_all(message)?;
383368
Ok(())
384369
}
@@ -388,13 +373,6 @@ impl Shell {
388373
if self.needs_clear {
389374
self.err_erase_line();
390375
}
391-
#[cfg(windows)]
392-
{
393-
if let ShellOut::Stream { stdout, .. } = &mut self.output {
394-
::fwdansi::write_ansi(stdout, message)?;
395-
return Ok(());
396-
}
397-
}
398376
self.out().write_all(message)?;
399377
Ok(())
400378
}
@@ -426,26 +404,22 @@ impl ShellOut {
426404
justified: bool,
427405
) -> CargoResult<()> {
428406
match *self {
429-
ShellOut::Stream {
430-
ref mut buffered_stderr,
431-
..
432-
} => {
433-
let mut buffer = buffered_stderr.buffer();
434-
buffer.reset()?;
435-
buffer.set_color(&to_termcolor_spec(*style))?;
407+
ShellOut::Stream { ref mut stderr, .. } => {
408+
let style = style.render();
409+
let bold = (anstyle::Style::new() | anstyle::Effects::BOLD).render();
410+
let reset = anstyle::Reset.render();
411+
412+
let mut buffer = Buffer::new();
436413
if justified {
437-
write!(buffer, "{:>12}", status)?;
414+
write!(&mut buffer, "{style}{status:>12}{reset}")?;
438415
} else {
439-
write!(buffer, "{}", status)?;
440-
buffer.set_color(termcolor::ColorSpec::new().set_bold(true))?;
441-
write!(buffer, ":")?;
416+
write!(&mut buffer, "{style}{status}{reset}{bold}:{reset}")?;
442417
}
443-
buffer.reset()?;
444418
match message {
445-
Some(message) => writeln!(buffer, " {}", message)?,
419+
Some(message) => writeln!(buffer, " {message}")?,
446420
None => write!(buffer, " ")?,
447421
}
448-
buffered_stderr.print(&buffer)?;
422+
stderr.write_all(buffer.as_bytes())?;
449423
}
450424
ShellOut::Write(ref mut w) => {
451425
if justified {
@@ -463,18 +437,15 @@ impl ShellOut {
463437
}
464438

465439
/// Write a styled fragment
466-
fn write_stdout(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
440+
fn write_stdout(&mut self, fragment: impl fmt::Display, style: &Style) -> CargoResult<()> {
467441
match *self {
468-
ShellOut::Stream {
469-
ref mut buffered_stdout,
470-
..
471-
} => {
472-
let mut buffer = buffered_stdout.buffer();
473-
buffer.reset()?;
474-
buffer.set_color(&to_termcolor_spec(*color))?;
475-
write!(buffer, "{}", fragment)?;
476-
buffer.reset()?;
477-
buffered_stdout.print(&buffer)?;
442+
ShellOut::Stream { ref mut stdout, .. } => {
443+
let style = style.render();
444+
let reset = anstyle::Reset.render();
445+
446+
let mut buffer = Buffer::new();
447+
write!(buffer, "{style}{}{reset}", fragment)?;
448+
stdout.write_all(buffer.as_bytes())?;
478449
}
479450
ShellOut::Write(ref mut w) => {
480451
write!(w, "{}", fragment)?;
@@ -484,18 +455,15 @@ impl ShellOut {
484455
}
485456

486457
/// Write a styled fragment
487-
fn write_stderr(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
458+
fn write_stderr(&mut self, fragment: impl fmt::Display, style: &Style) -> CargoResult<()> {
488459
match *self {
489-
ShellOut::Stream {
490-
ref mut buffered_stderr,
491-
..
492-
} => {
493-
let mut buffer = buffered_stderr.buffer();
494-
buffer.reset()?;
495-
buffer.set_color(&to_termcolor_spec(*color))?;
496-
write!(buffer, "{}", fragment)?;
497-
buffer.reset()?;
498-
buffered_stderr.print(&buffer)?;
460+
ShellOut::Stream { ref mut stderr, .. } => {
461+
let style = style.render();
462+
let reset = anstyle::Reset.render();
463+
464+
let mut buffer = Buffer::new();
465+
write!(buffer, "{style}{}{reset}", fragment)?;
466+
stderr.write_all(buffer.as_bytes())?;
499467
}
500468
ShellOut::Write(ref mut w) => {
501469
write!(w, "{}", fragment)?;
@@ -523,32 +491,21 @@ impl ShellOut {
523491

524492
impl ColorChoice {
525493
/// Converts our color choice to termcolor's version.
526-
fn to_termcolor_color_choice(self, stream: Stream) -> termcolor::ColorChoice {
494+
fn to_anstream_color_choice(self) -> anstream::ColorChoice {
527495
match self {
528-
ColorChoice::Always => termcolor::ColorChoice::Always,
529-
ColorChoice::Never => termcolor::ColorChoice::Never,
530-
ColorChoice::CargoAuto => {
531-
if stream.is_terminal() {
532-
termcolor::ColorChoice::Auto
533-
} else {
534-
termcolor::ColorChoice::Never
535-
}
536-
}
496+
ColorChoice::Always => anstream::ColorChoice::Always,
497+
ColorChoice::Never => anstream::ColorChoice::Never,
498+
ColorChoice::CargoAuto => anstream::ColorChoice::Auto,
537499
}
538500
}
539501
}
540502

541-
enum Stream {
542-
Stdout,
543-
Stderr,
544-
}
545-
546-
impl Stream {
547-
fn is_terminal(self) -> bool {
548-
match self {
549-
Self::Stdout => std::io::stdout().is_terminal(),
550-
Self::Stderr => std::io::stderr().is_terminal(),
551-
}
503+
fn supports_color(choice: anstream::ColorChoice) -> bool {
504+
match choice {
505+
anstream::ColorChoice::Always
506+
| anstream::ColorChoice::AlwaysAnsi
507+
| anstream::ColorChoice::Auto => true,
508+
anstream::ColorChoice::Never => false,
552509
}
553510
}
554511

0 commit comments

Comments
 (0)