mirror of
https://github.com/crate-ci/typos.git
synced 2024-11-25 02:20:58 -05:00
feat(cli): Smarter color control
This commit is contained in:
parent
a5d06c5a65
commit
b17b811ec1
5 changed files with 41 additions and 114 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -231,6 +231,33 @@ dependencies = [
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "concolor-clap"
|
||||||
|
version = "0.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4eb23c99e877c098e60ba3e84410153bfc311ac91b6ac7eabc0da0414ffa12e4"
|
||||||
|
dependencies = [
|
||||||
|
"concolor-control",
|
||||||
|
"structopt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "concolor-control"
|
||||||
|
version = "0.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7104119c2f80d887239879d0c50e033cd40eac9a3f3561e0684ba7d5d654f4da"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"concolor-query",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "concolor-query"
|
||||||
|
version = "0.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad159cc964ac8f9d407cbc0aa44b02436c054b541f2b4b5f06972e1efdc54bc7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "content_inspector"
|
name = "content_inspector"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
@ -1454,6 +1481,8 @@ dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"clap",
|
"clap",
|
||||||
"clap-verbosity-flag",
|
"clap-verbosity-flag",
|
||||||
|
"concolor-clap",
|
||||||
|
"concolor-control",
|
||||||
"content_inspector",
|
"content_inspector",
|
||||||
"criterion",
|
"criterion",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
|
|
@ -70,6 +70,8 @@ log = "0.4"
|
||||||
env_logger = { version = "0.9", default-features = false, features = ["termcolor"] }
|
env_logger = { version = "0.9", default-features = false, features = ["termcolor"] }
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
yansi = "0.5.0"
|
yansi = "0.5.0"
|
||||||
|
concolor-control = { version = "0.0.7" }
|
||||||
|
concolor-clap = { version = "0.0.6", features = ["api_unstable"] }
|
||||||
bstr = "0.2"
|
bstr = "0.2"
|
||||||
once_cell = "1.2.0"
|
once_cell = "1.2.0"
|
||||||
ahash = "0.7"
|
ahash = "0.7"
|
||||||
|
|
|
@ -44,7 +44,8 @@ impl Default for Format {
|
||||||
#[structopt(
|
#[structopt(
|
||||||
setting = structopt::clap::AppSettings::UnifiedHelpMessage,
|
setting = structopt::clap::AppSettings::UnifiedHelpMessage,
|
||||||
setting = structopt::clap::AppSettings::DeriveDisplayOrder,
|
setting = structopt::clap::AppSettings::DeriveDisplayOrder,
|
||||||
setting = structopt::clap::AppSettings::DontCollapseArgsInUsage
|
setting = structopt::clap::AppSettings::DontCollapseArgsInUsage,
|
||||||
|
setting = concolor_clap::color_choice(),
|
||||||
)]
|
)]
|
||||||
#[structopt(group = structopt::clap::ArgGroup::with_name("mode").multiple(false))]
|
#[structopt(group = structopt::clap::ArgGroup::with_name("mode").multiple(false))]
|
||||||
pub(crate) struct Args {
|
pub(crate) struct Args {
|
||||||
|
@ -104,7 +105,7 @@ pub(crate) struct Args {
|
||||||
pub(crate) config: ConfigArgs,
|
pub(crate) config: ConfigArgs,
|
||||||
|
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
pub(crate) color: crate::color::ColorArgs,
|
pub(crate) color: concolor_clap::Color,
|
||||||
|
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
pub(crate) verbose: clap_verbosity_flag::Verbosity,
|
pub(crate) verbose: clap_verbosity_flag::Verbosity,
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
|
||||||
#[structopt(rename_all = "kebab-case")]
|
|
||||||
pub struct ColorArgs {
|
|
||||||
/// "Specify when to use colored output. The automatic mode
|
|
||||||
/// only enables colors if an interactive terminal is detected -
|
|
||||||
/// colors are automatically disabled if the output goes to a pipe.
|
|
||||||
///
|
|
||||||
/// Possible values: *auto*, never, always.
|
|
||||||
#[structopt(
|
|
||||||
long,
|
|
||||||
value_name="when",
|
|
||||||
possible_values(&ColorValue::variants()),
|
|
||||||
case_insensitive(true),
|
|
||||||
default_value("auto"),
|
|
||||||
hide_possible_values(true),
|
|
||||||
hide_default_value(true),
|
|
||||||
help="When to use colors (*auto*, never, always).")]
|
|
||||||
color: ColorValue,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorArgs {
|
|
||||||
pub fn colored(&self) -> Option<bool> {
|
|
||||||
self.color.colored()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_enum! {
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
pub enum ColorValue {
|
|
||||||
Always,
|
|
||||||
Never,
|
|
||||||
Auto,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorValue {
|
|
||||||
fn colored(self) -> Option<bool> {
|
|
||||||
match self {
|
|
||||||
ColorValue::Always => Some(true),
|
|
||||||
ColorValue::Never => Some(false),
|
|
||||||
ColorValue::Auto => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ColorValue {
|
|
||||||
fn default() -> Self {
|
|
||||||
ColorValue::Auto
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colored_stdout() -> Option<bool> {
|
|
||||||
if atty::is(atty::Stream::Stdout) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colored_stderr() -> Option<bool> {
|
|
||||||
if atty::is(atty::Stream::Stderr) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colored_env() -> Option<bool> {
|
|
||||||
match std::env::var_os("TERM") {
|
|
||||||
None => noterm_colored(),
|
|
||||||
Some(k) => {
|
|
||||||
if k == "dumb" {
|
|
||||||
Some(false)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.or_else(|| {
|
|
||||||
// See https://no-color.org/
|
|
||||||
std::env::var_os("NO_COLOR").map(|_| true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
fn noterm_colored() -> Option<bool> {
|
|
||||||
// If TERM isn't set, then we are in a weird environment that
|
|
||||||
// probably doesn't support colors.
|
|
||||||
Some(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn noterm_colored() -> Option<bool> {
|
|
||||||
// On Windows, if TERM isn't set, then we shouldn't automatically
|
|
||||||
// assume that colors aren't allowed. This is unlike Unix environments
|
|
||||||
// where TERM is more rigorously set.
|
|
||||||
None
|
|
||||||
}
|
|
|
@ -7,7 +7,6 @@ use std::io::Write;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
mod color;
|
|
||||||
mod report;
|
mod report;
|
||||||
|
|
||||||
use proc_exit::WithCodeResultExt;
|
use proc_exit::WithCodeResultExt;
|
||||||
|
@ -31,22 +30,16 @@ fn run() -> proc_exit::ExitResult {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let colored = args.color.colored().or_else(color::colored_env);
|
args.color.apply();
|
||||||
let mut colored_stdout = colored.or_else(color::colored_stdout).unwrap_or(true);
|
|
||||||
let mut colored_stderr = colored.or_else(color::colored_stderr).unwrap_or(true);
|
|
||||||
if (colored_stdout || colored_stderr) && !yansi::Paint::enable_windows_ascii() {
|
|
||||||
colored_stdout = false;
|
|
||||||
colored_stderr = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_logging(args.verbose.log_level(), colored_stderr);
|
init_logging(args.verbose.log_level());
|
||||||
|
|
||||||
let stdout_palette = if colored_stdout {
|
let stdout_palette = if concolor_control::get(concolor_control::Stream::Stdout).ansi_color() {
|
||||||
report::Palette::colored()
|
report::Palette::colored()
|
||||||
} else {
|
} else {
|
||||||
report::Palette::plain()
|
report::Palette::plain()
|
||||||
};
|
};
|
||||||
let stderr_palette = if colored_stderr {
|
let stderr_palette = if concolor_control::get(concolor_control::Stream::Stderr).ansi_color() {
|
||||||
report::Palette::colored()
|
report::Palette::colored()
|
||||||
} else {
|
} else {
|
||||||
report::Palette::plain()
|
report::Palette::plain()
|
||||||
|
@ -272,9 +265,11 @@ fn run_checks(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_logging(level: Option<log::Level>, colored: bool) {
|
fn init_logging(level: Option<log::Level>) {
|
||||||
if let Some(level) = level {
|
if let Some(level) = level {
|
||||||
let mut builder = env_logger::Builder::new();
|
let mut builder = env_logger::Builder::new();
|
||||||
|
|
||||||
|
let colored = concolor_control::get(concolor_control::Stream::Stderr).ansi_color();
|
||||||
builder.write_style(if colored {
|
builder.write_style(if colored {
|
||||||
env_logger::WriteStyle::Always
|
env_logger::WriteStyle::Always
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue