From b8233af2c44ca41260403b9d2ff934c04e7d359f Mon Sep 17 00:00:00 2001 From: Greizgh Date: Sat, 22 Sep 2018 16:05:07 +0200 Subject: [PATCH] Allow to disable colors through env vars - unless forced, only use colors in tty - support CLICOLOR and NO_COLOR vars - switch to termcolor crate to handle output coloring --- Cargo.lock | 32 ++++++++------- Cargo.toml | 4 +- .../getting-started/cli-usage.md | 15 +++++++ src/console.rs | 41 ++++++++++++++++--- src/main.rs | 5 ++- 5 files changed, 74 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2d6d6bf..40ac0a34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -756,16 +756,18 @@ name = "gutenberg" version = "0.4.2" dependencies = [ "actix-web 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "content 0.1.0", "ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "errors 0.1.0", "front_matter 0.1.0", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rebuild 0.1.0", "site 0.1.0", - "term-painter 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "utils 0.1.0", @@ -2182,20 +2184,11 @@ dependencies = [ ] [[package]] -name = "term" -version = "0.4.6" +name = "termcolor" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "term-painter" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2721,6 +2714,15 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wincolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winreg" version = "0.5.1" @@ -2998,8 +3000,7 @@ dependencies = [ "checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" "checksum tera 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4f79f17fe555fffe4838a082a63636883ee13022888dc7bdc99edad8e0a411cd" -"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" -"checksum term-painter 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dcaa948f0e3e38470cd8dc8dcfe561a75c9e43f28075bb183845be2b9b3c08cf" +"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" @@ -3057,6 +3058,7 @@ dependencies = [ "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a27a759395c1195c4cc5cda607ef6f8f6498f64e78f7900f5de0a127a424704a" "checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" "checksum ws 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d2c221321dca56e6a80aa179d562e1fbe6ae116aeaa9205c76fa64e9e3c49dfc" diff --git a/Cargo.toml b/Cargo.toml index 1a6e6361..40ad6716 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,10 +17,12 @@ clap = "2" name = "gutenberg" [dependencies] +atty = "0.2.11" clap = "2" chrono = "0.4" +lazy_static = "1.1.0" toml = "0.4" -term-painter = "0.2" +termcolor = "1.0.4" # Used in init to ensure the url given as base_url is a valid one url = "1.5" # Below is for the serve cmd diff --git a/docs/content/documentation/getting-started/cli-usage.md b/docs/content/documentation/getting-started/cli-usage.md index c6427521..4b92162e 100644 --- a/docs/content/documentation/getting-started/cli-usage.md +++ b/docs/content/documentation/getting-started/cli-usage.md @@ -77,3 +77,18 @@ You can also point to another config file than `config.toml` like so - the posit ```bash $ gutenberg --config config.staging.toml serve ``` + +## Colored output + +Any of the three commands will emit colored output if your terminal supports it. + +*Note*: coloring is automatically disabled when the output is redirected to a pipe or a file (ie. when the standard output is not a TTY). + +You can disable this behavior by exporting one of the two following environment variables: + +- `NO_COLOR` (the value does not matter) +- `CLICOLOR=0` + +Should you want to force the use of colors, you can set the following environment variable: + +- `CLICOLOR_FORCE=1` diff --git a/src/console.rs b/src/console.rs index e28caa9d..a643eb32 100644 --- a/src/console.rs +++ b/src/console.rs @@ -1,27 +1,48 @@ +use std::env; +use std::io::Write; use std::time::Instant; +use atty; use chrono::Duration; -use term_painter::ToStyle; -use term_painter::Color::*; +use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use errors::Error; use site::Site; +lazy_static! { + /// Termcolor color choice. + /// We do not rely on ColorChoice::Auto behavior + /// as the check is already performed by has_color. + static ref COLOR_CHOICE: ColorChoice = + if has_color() { + ColorChoice::Always + } else { + ColorChoice::Never + }; +} + pub fn info(message: &str) { - println!("{}", NotSet.bold().paint(message)); + colorize(message, ColorSpec::new().set_bold(true)); } pub fn warn(message: &str) { - println!("{}", Yellow.bold().paint(message)); + colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Yellow))); } pub fn success(message: &str) { - println!("{}", Green.bold().paint(message)); + colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Green))); } pub fn error(message: &str) { - println!("{}", Red.bold().paint(message)); + colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Red))); +} + +/// Print a colorized message to stdout +fn colorize(message: &str, color: &ColorSpec) { + let mut stdout = StandardStream::stdout(*COLOR_CHOICE); + stdout.set_color(color).unwrap(); + writeln!(&mut stdout, "{}", message).unwrap(); } /// Display in the console the number of pages/sections in the site @@ -75,3 +96,11 @@ pub fn unravel_errors(message: &str, error: &Error) { self::error(&format!("Reason: {}", e)); } } + +/// Check whether to output colors +fn has_color() -> bool { + let use_colors = env::var("CLICOLOR").unwrap_or("1".to_string()) != "0" && !env::var("NO_COLOR").is_ok(); + let force_colors = env::var("CLICOLOR_FORCE").unwrap_or("0".to_string()) != "0"; + + force_colors || use_colors && atty::is(atty::Stream::Stdout) +} diff --git a/src/main.rs b/src/main.rs index 30f13b1b..d49175cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ +extern crate atty; extern crate actix_web; #[macro_use] extern crate clap; extern crate chrono; +#[macro_use] +extern crate lazy_static; extern crate notify; -extern crate term_painter; +extern crate termcolor; extern crate url; extern crate ws; extern crate ctrlc;