Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(help): Add styling to help output #12578

Merged
merged 2 commits into from Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Expand Up @@ -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.17.0"
clap = "4.4.2"
color-print = "0.3.4"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not a blocker)

The other issue is that this patch introduces one more dependency (and transitive proc-macro). This doesn't really affect Cargo development too much. However still some cargo plugins depend on cargo directly, so we still need to keep an eye on that.

syn, quote, and proc-macro2 will already be pulled in. I can see if I can work with the maintainer to switch to syn 2 (a gix dep also pulls in syn v1) and winnow (gix pulls in nom for now). That leaves just the macro itself which shouldn't be all that much. While is only used in the bin for now, I'd like to work towards styled text in more places once we are using anstream. The main issue with color-print itself is theming. This is also balanced out with not needing to pull in the String feature into clap which affects binary size, compile times, and runtime performance.

So for me, I'm not too worried about it and I can easy see the situation evolving. To what? I don't yet know.

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"] }
Expand Down Expand Up @@ -129,6 +130,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"] }
Expand Down
69 changes: 40 additions & 29 deletions src/bin/cargo/cli.rs
Expand Up @@ -513,53 +513,64 @@ impl GlobalArgs {

pub fn cli() -> Command {
let usage = if is_rustup() {
"cargo [+toolchain] [OPTIONS] [COMMAND]\n cargo [+toolchain] [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]..."
color_print::cstr!("<cyan,bold>cargo</> <cyan>[+toolchain] [OPTIONS] [COMMAND]</>\n <cyan,bold>cargo</> <cyan>[+toolchain] [OPTIONS]</> <cyan,bold>-Zscript</> <cyan><<MANIFEST_RS>> [ARGS]...</>")
} else {
"cargo [OPTIONS] [COMMAND]\n cargo [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]..."
color_print::cstr!("<cyan,bold>cargo</> <cyan>[OPTIONS] [COMMAND]</>\n <cyan,bold>cargo</> <cyan>[OPTIONS]</> <cyan,bold>-Zscript</> <cyan><<MANIFEST_RS>> [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::Cyan.on_default() | Effects::BOLD)
.placeholder(AnsiColor::Cyan.on_default())
.error(AnsiColor::Red.on_default() | Effects::BOLD)
.valid(AnsiColor::Cyan.on_default() | Effects::BOLD)
.invalid(AnsiColor::Yellow.on_default() | Effects::BOLD)
};

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.
//
// 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}
<green,bold>Usage:</> {usage}

Options:
<green,bold>Options:</>
{options}

Commands:
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 all commands with --list

See 'cargo help <command>' for more information on a specific command.\n",
)
<green,bold>Commands:</>
<cyan,bold>build</>, <cyan,bold>b</> Compile the current package
<cyan,bold>check</>, <cyan,bold>c</> Analyze the current package and report errors, but don't build object files
<cyan,bold>clean</> Remove the target directory
<cyan,bold>doc</>, <cyan,bold>d</> Build this package's and its dependencies' documentation
<cyan,bold>new</> Create a new cargo package
<cyan,bold>init</> Create a new cargo package in an existing directory
<cyan,bold>add</> Add dependencies to a manifest file
<cyan,bold>remove</> Remove dependencies from a manifest file
<cyan,bold>run</>, <cyan,bold>r</> Run a binary or example of the local package
<cyan,bold>test</>, <cyan,bold>t</> Run the tests
<cyan,bold>bench</> Run the benchmarks
<cyan,bold>update</> Update dependencies listed in Cargo.lock
<cyan,bold>search</> Search registry for crates
<cyan,bold>publish</> Package and upload this package to the registry
<cyan,bold>install</> Install a Rust binary. Default location is $HOME/.cargo/bin
<cyan,bold>uninstall</> Uninstall a Rust binary
<cyan>...</> See all commands with <cyan,bold>--list</>

See '<cyan,bold>cargo help</> <cyan><<command>></>' 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(
Expand Down
12 changes: 6 additions & 6 deletions src/bin/cargo/commands/add.rs
Expand Up @@ -18,12 +18,12 @@ pub fn cli() -> Command {
clap::Command::new("add")
.about("Add dependencies to a Cargo.toml manifest file")
.override_usage(
"\
cargo add [OPTIONS] <DEP>[@<VERSION>] ...
cargo add [OPTIONS] --path <PATH> ...
cargo add [OPTIONS] --git <URL> ..."
)
.after_help("Run `cargo help add` for more detailed information.\n")
color_print::cstr!("\
<cyan,bold>cargo add</> <cyan>[OPTIONS] <<DEP>>[@<<VERSION>>] ...</>
<cyan,bold>cargo add</> <cyan>[OPTIONS]</> <cyan,bold>--path</> <cyan><<PATH>> ...</>
<cyan,bold>cargo add</> <cyan>[OPTIONS]</> <cyan,bold>--git</> <cyan><<URL>> ...</>"
))
.after_help(color_print::cstr!("Run `<cyan,bold>cargo help add</>` for more detailed information.\n"))
.group(clap::ArgGroup::new("selected").multiple(true).required(true))
.args([
clap::Arg::new("crates")
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/bench.rs
Expand Up @@ -50,7 +50,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
.after_help("Run `cargo help bench` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help bench</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/build.rs
Expand Up @@ -46,7 +46,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
.after_help("Run `cargo help build` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help build</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/check.rs
Expand Up @@ -37,7 +37,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
.after_help("Run `cargo help check` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help check</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/clean.rs
Expand Up @@ -14,7 +14,9 @@ pub fn cli() -> Command {
.arg_target_triple("Target triple to clean output for")
.arg_target_dir()
.arg_manifest_path()
.after_help("Run `cargo help clean` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help clean</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/doc.rs
Expand Up @@ -40,7 +40,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
.after_help("Run `cargo help doc` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help doc</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/fetch.rs
Expand Up @@ -9,7 +9,9 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_target_triple("Fetch dependencies for the target triple")
.arg_manifest_path()
.after_help("Run `cargo help fetch` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help fetch</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/fix.rs
Expand Up @@ -54,7 +54,9 @@ pub fn cli() -> Command {
.arg_target_dir()
.arg_timings()
.arg_manifest_path()
.after_help("Run `cargo help fix` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help fix</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/generate_lockfile.rs
Expand Up @@ -7,7 +7,9 @@ pub fn cli() -> Command {
.about("Generate the lockfile for a package")
.arg_quiet()
.arg_manifest_path()
.after_help("Run `cargo help generate-lockfile` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help generate-lockfile</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/init.rs
Expand Up @@ -9,7 +9,9 @@ pub fn cli() -> Command {
.arg_new_opts()
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.arg_quiet()
.after_help("Run `cargo help init` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help init</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/install.rs
Expand Up @@ -87,7 +87,9 @@ pub fn cli() -> Command {
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_timings()
.after_help("Run `cargo help install` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help install</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/locate_project.rs
Expand Up @@ -16,7 +16,9 @@ pub fn cli() -> Command {
)
.arg_quiet()
.arg_manifest_path()
.after_help("Run `cargo help locate-project` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help locate-project</>` for more detailed information.\n"
))
}

#[derive(Serialize)]
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/login.rs
Expand Up @@ -14,7 +14,9 @@ pub fn cli() -> Command {
.last(true),
)
.arg_quiet()
.after_help("Run `cargo help login` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help login</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/logout.rs
Expand Up @@ -6,7 +6,9 @@ pub fn cli() -> Command {
.about("Remove an API token from the registry locally")
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.arg_quiet()
.after_help("Run `cargo help logout` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help logout</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/metadata.rs
Expand Up @@ -26,7 +26,9 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_features()
.arg_manifest_path()
.after_help("Run `cargo help metadata` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help metadata</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/new.rs
Expand Up @@ -9,7 +9,9 @@ pub fn cli() -> Command {
.arg_new_opts()
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.arg_quiet()
.after_help("Run `cargo help new` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help new</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/owner.rs
Expand Up @@ -28,7 +28,9 @@ pub fn cli() -> Command {
.arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.arg_quiet()
.after_help("Run `cargo help owner` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help owner</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/package.rs
Expand Up @@ -35,7 +35,9 @@ pub fn cli() -> Command {
.arg_target_dir()
.arg_parallel()
.arg_manifest_path()
.after_help("Run `cargo help package` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help package</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/pkgid.rs
Expand Up @@ -10,7 +10,9 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_package("Argument to get the package ID specifier for")
.arg_manifest_path()
.after_help("Run `cargo help pkgid` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help pkgid</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/publish.rs
Expand Up @@ -24,7 +24,9 @@ pub fn cli() -> Command {
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
.after_help("Run `cargo help publish` for more detailed information.\n")
.after_help(color_print::cstr!(
"Run `<cyan,bold>cargo help publish</>` for more detailed information.\n"
))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Expand Down
8 changes: 4 additions & 4 deletions src/bin/cargo/commands/read_manifest.rs
Expand Up @@ -2,13 +2,13 @@ use crate::command_prelude::*;

pub fn cli() -> Command {
subcommand("read-manifest")
.about(
.about(color_print::cstr!(
"\
Print a JSON representation of a Cargo.toml manifest.

Deprecated, use `cargo metadata --no-deps` instead.\
",
)
Deprecated, use `<cyan,bold>cargo metadata --no-deps</>` instead.\
"
))
.arg_quiet()
.arg_manifest_path()
}
Expand Down