From 3d0d6229a3f4c8aabb80ecf717bec0777d0433d6 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 28 Aug 2023 12:05:19 -0500 Subject: [PATCH] feat(help): Add styling to help output Traditionally, cargo has disabled clap's styled output. My assumed reason is that cargo mixes custom help output with auto-generated and you couldn't previously make it all styled. Clap 4.2 allowed users to pass in strings styled using ANSI escape codes, allowing us to pass in styled text that matches clap. In clap 4.4.1, clap gained the ability for the user to override the style. In this PR, I decided to use the new 4.4.1 feature to style clap's output to match the rest of cargo's output. Alternatively, we could use a more subdue style that clap uses by default. --- Cargo.lock | 22 ++++++++++++ Cargo.toml | 2 ++ src/bin/cargo/cli.rs | 63 ++++++++++++++++++++--------------- src/bin/cargo/commands/run.rs | 4 ++- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ecf6576e2e9..d2343f7db496 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,7 @@ dependencies = [ "cargo-test-support", "cargo-util", "clap", + "color-print", "crates-io", "curl", "curl-sys", @@ -540,6 +541,27 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" +[[package]] +name = "color-print" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2a5e6504ed8648554968650feecea00557a3476bc040d0ffc33080e66b646d0" +dependencies = [ + "color-print-proc-macro", +] + +[[package]] +name = "color-print-proc-macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51beaa537d73d2d1ff34ee70bc095f170420ab2ec5d687ecd3ec2b0d092514b" +dependencies = [ + "nom", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "colorchoice" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index d8a6abdf8cbc..e8999d68f81d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ cargo-test-support = { path = "crates/cargo-test-support" } cargo-util = { version = "0.2.6", path = "crates/cargo-util" } cargo_metadata = "0.14.0" clap = "4.4.1" +color-print = "0.3.4" core-foundation = { version = "0.9.3", features = ["mac_os_10_7_support"] } crates-io = { version = "0.39.0", path = "crates/crates-io" } criterion = { version = "0.5.1", features = ["html_reports"] } @@ -130,6 +131,7 @@ cargo-credential-libsecret.workspace = true cargo-credential-macos-keychain.workspace = true cargo-credential-wincred.workspace = true cargo-util.workspace = true +color-print.workspace = true clap = { workspace = true, features = ["wrap_help"] } crates-io.workspace = true curl = { workspace = true, features = ["http2"] } diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index eb337d681ce0..8fa930f93549 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -520,6 +520,19 @@ pub fn cli() -> Command { } else { "cargo [OPTIONS] [COMMAND]\n cargo [OPTIONS] -Zscript [ARGS]..." }; + + let styles = { + use clap::builder::styling::*; + Styles::styled() + .header(AnsiColor::Green.on_default() | Effects::BOLD) + .usage(AnsiColor::Green.on_default() | Effects::BOLD) + .literal(AnsiColor::Blue.on_default() | Effects::BOLD) + .placeholder(AnsiColor::Cyan.on_default()) + .error(AnsiColor::Red.on_default()) + .valid(AnsiColor::Blue.on_default() | Effects::BOLD) + .invalid(AnsiColor::Yellow.on_default()) + }; + Command::new("cargo") // Subcommands all count their args' display order independently (from 0), // which makes their args interspersed with global args. This puts global args last. @@ -527,41 +540,39 @@ pub fn cli() -> Command { // We also want these to come before auto-generated `--help` .next_display_order(800) .allow_external_subcommands(true) - // Doesn't mix well with our list of common cargo commands. See clap-rs/clap#3108 for - // opening clap up to allow us to style our help template - .disable_colored_help(true) + .styles(styles) // Provide a custom help subcommand for calling into man pages .disable_help_subcommand(true) .override_usage(usage) - .help_template( + .help_template(color_print::cstr!( "\ Rust's package manager -Usage: {usage} +Usage: {usage} -Options: +Options: {options} -Some common cargo commands are (see all commands with --list): - build, b Compile the current package - check, c Analyze the current package and report errors, but don't build object files - clean Remove the target directory - doc, d Build this package's and its dependencies' documentation - new Create a new cargo package - init Create a new cargo package in an existing directory - add Add dependencies to a manifest file - remove Remove dependencies from a manifest file - run, r Run a binary or example of the local package - test, t Run the tests - bench Run the benchmarks - update Update dependencies listed in Cargo.lock - search Search registry for crates - publish Package and upload this package to the registry - install Install a Rust binary. Default location is $HOME/.cargo/bin - uninstall Uninstall a Rust binary - -See 'cargo help ' for more information on a specific command.\n", - ) +Some common cargo commands are (see all commands with '--list'): + build, b Compile the current package + check, c Analyze the current package and report errors, but don't build object files + clean Remove the target directory + doc, d Build this package's and its dependencies' documentation + new Create a new cargo package + init Create a new cargo package in an existing directory + add Add dependencies to a manifest file + remove Remove dependencies from a manifest file + run, r Run a binary or example of the local package + test, t Run the tests + bench Run the benchmarks + update Update dependencies listed in Cargo.lock + search Search registry for crates + publish Package and upload this package to the registry + install Install a Rust binary. Default location is $HOME/.cargo/bin + uninstall Uninstall a Rust binary + +See 'cargo help <>' for more information on a specific command.\n", + )) .arg(flag("version", "Print version info and exit").short('V')) .arg(flag("list", "List installed commands")) .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE")) diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index ce2099b0e505..9bde7f345275 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -38,7 +38,9 @@ pub fn cli() -> Command { .arg_manifest_path() .arg_unit_graph() .arg_timings() - .after_help("Run `cargo help run` for more detailed information.\n") + .after_help(color_print::cstr!( + "Run `cargo help run` for more detailed information.\n" + )) } pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {