Skip to content

Commit 00bf8b0

Browse files
committed
Auto merge of #12655 - epage:style, r=weihanglo
refactor: Consolidate clap/shell styles ### What does this PR try to resolve? This is a follow up to #12578 to reduce duplication of terminal styling. This still leaves styling in `color_print::cstr!`. This is also prep for copy/pasting into `clap-cargo` for others to use. Another step might be to extract `cargo::util::style` into its own crate. ### How should we test and review this PR? We have no styling tests so this can only be verified by inspection or running the commands ### Additional information I chose `anstyle` for expressing these as its an API designed specifically for stable style definitions to put in public APIs.
2 parents 7541cc7 + 51e1058 commit 00bf8b0

File tree

11 files changed

+88
-69
lines changed

11 files changed

+88
-69
lines changed

Cargo.lock

+14-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ edition = "2021"
1616
license = "MIT OR Apache-2.0"
1717

1818
[workspace.dependencies]
19+
anstyle = "1.0.3"
20+
anstyle-termcolor = "1.1.0"
1921
anyhow = "1.0.75"
2022
base64 = "0.21.3"
2123
bytesize = "1.3"
@@ -121,6 +123,8 @@ name = "cargo"
121123
path = "src/cargo/lib.rs"
122124

123125
[dependencies]
126+
anstyle.workspace = true
127+
anstyle-termcolor.workspace = true
124128
anyhow.workspace = true
125129
base64.workspace = true
126130
bytesize.workspace = true

src/bin/cargo/cli.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use super::list_commands;
1414
use crate::command_prelude::*;
1515
use crate::util::is_rustup;
1616
use cargo::core::features::HIDDEN;
17+
use cargo::util::style;
1718

1819
pub fn main(config: &mut LazyConfig) -> CliResult {
1920
let args = cli().try_get_matches()?;
@@ -519,15 +520,14 @@ pub fn cli() -> Command {
519520
};
520521

521522
let styles = {
522-
use clap::builder::styling::*;
523-
Styles::styled()
524-
.header(AnsiColor::Green.on_default() | Effects::BOLD)
525-
.usage(AnsiColor::Green.on_default() | Effects::BOLD)
526-
.literal(AnsiColor::Cyan.on_default() | Effects::BOLD)
527-
.placeholder(AnsiColor::Cyan.on_default())
528-
.error(AnsiColor::Red.on_default() | Effects::BOLD)
529-
.valid(AnsiColor::Cyan.on_default() | Effects::BOLD)
530-
.invalid(AnsiColor::Yellow.on_default() | Effects::BOLD)
523+
clap::builder::styling::Styles::styled()
524+
.header(style::HEADER)
525+
.usage(style::USAGE)
526+
.literal(style::LITERAL)
527+
.placeholder(style::PLACEHOLDER)
528+
.error(style::ERROR)
529+
.valid(style::VALID)
530+
.invalid(style::INVALID)
531531
};
532532

533533
Command::new("cargo")

src/cargo/core/compiler/timings.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::core::compiler::{BuildContext, Context, TimingOutput};
88
use crate::core::PackageId;
99
use crate::util::cpu::State;
1010
use crate::util::machine_message::{self, Message};
11+
use crate::util::style;
1112
use crate::util::{CargoResult, Config};
1213
use anyhow::Context as _;
1314
use cargo_util::paths;
@@ -352,7 +353,7 @@ impl<'cfg> Timings<'cfg> {
352353
paths::link_or_copy(&filename, &unstamped_filename)?;
353354
self.config
354355
.shell()
355-
.status_with_color("Timing", msg, termcolor::Color::Cyan)?;
356+
.status_with_color("Timing", msg, &style::NOTE)?;
356357
Ok(())
357358
}
358359

src/cargo/core/shell.rs

+20-26
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ use std::fmt;
22
use std::io::prelude::*;
33
use std::io::IsTerminal;
44

5-
use termcolor::Color::{Cyan, Green, Red, Yellow};
6-
use termcolor::{self, Color, ColorSpec, StandardStream, WriteColor};
5+
use anstyle::Style;
6+
use anstyle_termcolor::to_termcolor_spec;
7+
use termcolor::{self, StandardStream, WriteColor};
78

89
use crate::util::errors::CargoResult;
10+
use crate::util::style::*;
911

1012
pub enum TtyWidth {
1113
NoTty,
@@ -130,7 +132,7 @@ impl Shell {
130132
&mut self,
131133
status: &dyn fmt::Display,
132134
message: Option<&dyn fmt::Display>,
133-
color: Color,
135+
color: &Style,
134136
justified: bool,
135137
) -> CargoResult<()> {
136138
match self.verbosity {
@@ -203,22 +205,22 @@ impl Shell {
203205
T: fmt::Display,
204206
U: fmt::Display,
205207
{
206-
self.print(&status, Some(&message), Green, true)
208+
self.print(&status, Some(&message), &HEADER, true)
207209
}
208210

209211
pub fn status_header<T>(&mut self, status: T) -> CargoResult<()>
210212
where
211213
T: fmt::Display,
212214
{
213-
self.print(&status, None, Cyan, true)
215+
self.print(&status, None, &NOTE, true)
214216
}
215217

216218
/// Shortcut to right-align a status message.
217219
pub fn status_with_color<T, U>(
218220
&mut self,
219221
status: T,
220222
message: U,
221-
color: Color,
223+
color: &Style,
222224
) -> CargoResult<()>
223225
where
224226
T: fmt::Display,
@@ -255,20 +257,20 @@ impl Shell {
255257
self.err_erase_line();
256258
}
257259
self.output
258-
.message_stderr(&"error", Some(&message), Red, false)
260+
.message_stderr(&"error", Some(&message), &ERROR, false)
259261
}
260262

261263
/// Prints an amber 'warning' message.
262264
pub fn warn<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
263265
match self.verbosity {
264266
Verbosity::Quiet => Ok(()),
265-
_ => self.print(&"warning", Some(&message), Yellow, false),
267+
_ => self.print(&"warning", Some(&message), &WARN, false),
266268
}
267269
}
268270

269271
/// Prints a cyan 'note' message.
270272
pub fn note<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
271-
self.print(&"note", Some(&message), Cyan, false)
273+
self.print(&"note", Some(&message), &NOTE, false)
272274
}
273275

274276
/// Updates the verbosity of the shell.
@@ -338,22 +340,14 @@ impl Shell {
338340
/// Write a styled fragment
339341
///
340342
/// Caller is responsible for deciding whether [`Shell::verbosity`] is affects output.
341-
pub fn write_stdout(
342-
&mut self,
343-
fragment: impl fmt::Display,
344-
color: &ColorSpec,
345-
) -> CargoResult<()> {
343+
pub fn write_stdout(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
346344
self.output.write_stdout(fragment, color)
347345
}
348346

349347
/// Write a styled fragment
350348
///
351349
/// Caller is responsible for deciding whether [`Shell::verbosity`] is affects output.
352-
pub fn write_stderr(
353-
&mut self,
354-
fragment: impl fmt::Display,
355-
color: &ColorSpec,
356-
) -> CargoResult<()> {
350+
pub fn write_stderr(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
357351
self.output.write_stderr(fragment, color)
358352
}
359353

@@ -412,18 +406,18 @@ impl ShellOut {
412406
&mut self,
413407
status: &dyn fmt::Display,
414408
message: Option<&dyn fmt::Display>,
415-
color: Color,
409+
style: &Style,
416410
justified: bool,
417411
) -> CargoResult<()> {
418412
match *self {
419413
ShellOut::Stream { ref mut stderr, .. } => {
420414
stderr.reset()?;
421-
stderr.set_color(ColorSpec::new().set_bold(true).set_fg(Some(color)))?;
415+
stderr.set_color(&to_termcolor_spec(*style))?;
422416
if justified {
423417
write!(stderr, "{:>12}", status)?;
424418
} else {
425419
write!(stderr, "{}", status)?;
426-
stderr.set_color(ColorSpec::new().set_bold(true))?;
420+
stderr.set_color(termcolor::ColorSpec::new().set_bold(true))?;
427421
write!(stderr, ":")?;
428422
}
429423
stderr.reset()?;
@@ -448,11 +442,11 @@ impl ShellOut {
448442
}
449443

450444
/// Write a styled fragment
451-
fn write_stdout(&mut self, fragment: impl fmt::Display, color: &ColorSpec) -> CargoResult<()> {
445+
fn write_stdout(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
452446
match *self {
453447
ShellOut::Stream { ref mut stdout, .. } => {
454448
stdout.reset()?;
455-
stdout.set_color(&color)?;
449+
stdout.set_color(&to_termcolor_spec(*color))?;
456450
write!(stdout, "{}", fragment)?;
457451
stdout.reset()?;
458452
}
@@ -464,11 +458,11 @@ impl ShellOut {
464458
}
465459

466460
/// Write a styled fragment
467-
fn write_stderr(&mut self, fragment: impl fmt::Display, color: &ColorSpec) -> CargoResult<()> {
461+
fn write_stderr(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
468462
match *self {
469463
ShellOut::Stream { ref mut stderr, .. } => {
470464
stderr.reset()?;
471-
stderr.set_color(&color)?;
465+
stderr.set_color(&to_termcolor_spec(*color))?;
472466
write!(stderr, "{}", fragment)?;
473467
stderr.reset()?;
474468
}

src/cargo/ops/cargo_add/mod.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ use anyhow::Context as _;
1212
use cargo_util::paths;
1313
use indexmap::IndexSet;
1414
use itertools::Itertools;
15-
use termcolor::Color::Green;
16-
use termcolor::Color::Red;
17-
use termcolor::ColorSpec;
1815
use toml_edit::Item as TomlItem;
1916

2017
use crate::core::dependency::DepKind;
@@ -26,6 +23,7 @@ use crate::core::Shell;
2623
use crate::core::Summary;
2724
use crate::core::Workspace;
2825
use crate::sources::source::QueryKind;
26+
use crate::util::style;
2927
use crate::util::toml_mut::dependency::Dependency;
3028
use crate::util::toml_mut::dependency::GitSource;
3129
use crate::util::toml_mut::dependency::MaybeWorkspace;
@@ -968,19 +966,16 @@ fn print_dep_table_msg(shell: &mut Shell, dep: &DependencyUI) -> CargoResult<()>
968966
} else {
969967
"".to_owned()
970968
};
971-
shell.write_stderr(
972-
format_args!("{}Features{}:\n", prefix, suffix),
973-
&ColorSpec::new(),
974-
)?;
969+
shell.write_stderr(format_args!("{}Features{}:\n", prefix, suffix), &style::NOP)?;
975970
for feat in activated {
976-
shell.write_stderr(&prefix, &ColorSpec::new())?;
977-
shell.write_stderr('+', &ColorSpec::new().set_bold(true).set_fg(Some(Green)))?;
978-
shell.write_stderr(format_args!(" {}\n", feat), &ColorSpec::new())?;
971+
shell.write_stderr(&prefix, &style::NOP)?;
972+
shell.write_stderr('+', &style::GOOD)?;
973+
shell.write_stderr(format_args!(" {}\n", feat), &style::NOP)?;
979974
}
980975
for feat in deactivated {
981-
shell.write_stderr(&prefix, &ColorSpec::new())?;
982-
shell.write_stderr('-', &ColorSpec::new().set_bold(true).set_fg(Some(Red)))?;
983-
shell.write_stderr(format_args!(" {}\n", feat), &ColorSpec::new())?;
976+
shell.write_stderr(&prefix, &style::NOP)?;
977+
shell.write_stderr('-', &style::ERROR)?;
978+
shell.write_stderr(format_args!(" {}\n", feat), &style::NOP)?;
984979
}
985980
}
986981

src/cargo/ops/cargo_generate_lockfile.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use crate::core::{PackageId, PackageIdSpec};
44
use crate::core::{Resolve, SourceId, Workspace};
55
use crate::ops;
66
use crate::util::config::Config;
7+
use crate::util::style;
78
use crate::util::CargoResult;
9+
use anstyle::Style;
810
use std::collections::{BTreeMap, HashSet};
9-
use termcolor::Color::{self, Cyan, Green, Red, Yellow};
1011
use tracing::debug;
1112

1213
pub struct UpdateOptions<'a> {
@@ -133,7 +134,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
133134
)?;
134135

135136
// Summarize what is changing for the user.
136-
let print_change = |status: &str, msg: String, color: Color| {
137+
let print_change = |status: &str, msg: String, color: &Style| {
137138
opts.config.shell().status_with_color(status, msg, color)
138139
};
139140
for (removed, added) in compare_dependency_graphs(&previous_resolve, &resolve) {
@@ -149,16 +150,16 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
149150
};
150151

151152
if removed[0].version() > added[0].version() {
152-
print_change("Downgrading", msg, Yellow)?;
153+
print_change("Downgrading", msg, &style::WARN)?;
153154
} else {
154-
print_change("Updating", msg, Green)?;
155+
print_change("Updating", msg, &style::GOOD)?;
155156
}
156157
} else {
157158
for package in removed.iter() {
158-
print_change("Removing", format!("{}", package), Red)?;
159+
print_change("Removing", format!("{}", package), &style::ERROR)?;
159160
}
160161
for package in added.iter() {
161-
print_change("Adding", format!("{}", package), Cyan)?;
162+
print_change("Adding", format!("{}", package), &style::NOTE)?;
162163
}
163164
}
164165
}

src/cargo/ops/registry/search.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ use std::cmp;
66
use std::iter::repeat;
77

88
use anyhow::Context as _;
9-
use termcolor::Color;
10-
use termcolor::ColorSpec;
119
use url::Url;
1210

11+
use crate::util::style;
1312
use crate::util::truncate_with_ellipsis;
1413
use crate::CargoResult;
1514
use crate::Config;
@@ -58,15 +57,12 @@ pub fn search(
5857
};
5958
let mut fragments = line.split(query).peekable();
6059
while let Some(fragment) = fragments.next() {
61-
let _ = config.shell().write_stdout(fragment, &ColorSpec::new());
60+
let _ = config.shell().write_stdout(fragment, &style::NOP);
6261
if fragments.peek().is_some() {
63-
let _ = config.shell().write_stdout(
64-
query,
65-
&ColorSpec::new().set_bold(true).set_fg(Some(Color::Green)),
66-
);
62+
let _ = config.shell().write_stdout(query, &style::GOOD);
6763
}
6864
}
69-
let _ = config.shell().write_stdout("\n", &ColorSpec::new());
65+
let _ = config.shell().write_stdout("\n", &style::NOP);
7066
}
7167

7268
let search_max_limit = 100;
@@ -76,7 +72,7 @@ pub fn search(
7672
"... and {} crates more (use --limit N to see more)\n",
7773
total_crates - limit
7874
),
79-
&ColorSpec::new(),
75+
&style::NOP,
8076
);
8177
} else if total_crates > limit && limit >= search_max_limit {
8278
let extra = if source_ids.original.is_crates_io() {
@@ -87,7 +83,7 @@ pub fn search(
8783
};
8884
let _ = config.shell().write_stdout(
8985
format_args!("... and {} crates more{}\n", total_crates - limit, extra),
90-
&ColorSpec::new(),
86+
&style::NOP,
9187
);
9288
}
9389

0 commit comments

Comments
 (0)