Skip to content

Commit

Permalink
WIP: fix(cli): Make --help easier to browse
Browse files Browse the repository at this point in the history
This mirrors some of the categories from `cargo help` (the man pages).
  • Loading branch information
epage committed Jul 25, 2023
1 parent e2fbcd9 commit 830931e
Show file tree
Hide file tree
Showing 22 changed files with 527 additions and 372 deletions.
106 changes: 74 additions & 32 deletions src/cargo/util/command_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ pub use clap::Command;

use super::config::JobsConfig;

pub mod heading {
pub const PACKAGE_SELECTION: &str = "Package Selection";
pub const TARGET_SELECTION: &str = "Target Selection";
pub const FEATURE_SELECTION: &str = "Feature Selection";
pub const COMPILATION_OPTIONS: &str = "Compilation Options";
}

pub trait CommandExt: Sized {
fn _arg(self, arg: Arg) -> Self;

Expand All @@ -37,8 +44,10 @@ pub trait CommandExt: Sized {
all: &'static str,
exclude: &'static str,
) -> Self {
self.arg_package_spec_no_all(package, all, exclude)
._arg(flag("all", "Alias for --workspace (deprecated)"))
self.arg_package_spec_no_all(package, all, exclude)._arg(
flag("all", "Alias for --workspace (deprecated)")
.help_heading(heading::PACKAGE_SELECTION),
)
}

/// Variant of arg_package_spec that does not include the `--all` flag
Expand All @@ -51,19 +60,24 @@ pub trait CommandExt: Sized {
exclude: &'static str,
) -> Self {
self.arg_package_spec_simple(package)
._arg(flag("workspace", all))
._arg(multi_opt("exclude", "SPEC", exclude))
._arg(flag("workspace", all).help_heading(heading::PACKAGE_SELECTION))
._arg(multi_opt("exclude", "SPEC", exclude).help_heading(heading::PACKAGE_SELECTION))
}

fn arg_package_spec_simple(self, package: &'static str) -> Self {
self._arg(optional_multi_opt("package", "SPEC", package).short('p'))
self._arg(
optional_multi_opt("package", "SPEC", package)
.short('p')
.help_heading(heading::PACKAGE_SELECTION),
)
}

fn arg_package(self, package: &'static str) -> Self {
self._arg(
optional_opt("package", package)
.short('p')
.value_name("SPEC"),
.value_name("SPEC")
.help_heading(heading::PACKAGE_SELECTION),
)
}

Expand Down Expand Up @@ -94,11 +108,13 @@ pub trait CommandExt: Sized {
all: &'static str,
) -> Self {
self.arg_targets_lib_bin_example(lib, bin, bins, example, examples)
._arg(flag("tests", tests))
._arg(optional_multi_opt("test", "NAME", test))
._arg(flag("benches", benches))
._arg(optional_multi_opt("bench", "NAME", bench))
._arg(flag("all-targets", all))
._arg(flag("tests", tests).help_heading(heading::TARGET_SELECTION))
._arg(optional_multi_opt("test", "NAME", test).help_heading(heading::TARGET_SELECTION))
._arg(flag("benches", benches).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("bench", "NAME", bench).help_heading(heading::TARGET_SELECTION),
)
._arg(flag("all-targets", all).help_heading(heading::TARGET_SELECTION))
}

fn arg_targets_lib_bin_example(
Expand All @@ -109,11 +125,14 @@ pub trait CommandExt: Sized {
example: &'static str,
examples: &'static str,
) -> Self {
self._arg(flag("lib", lib))
._arg(flag("bins", bins))
._arg(optional_multi_opt("bin", "NAME", bin))
._arg(flag("examples", examples))
._arg(optional_multi_opt("example", "NAME", example))
self._arg(flag("lib", lib).help_heading(heading::TARGET_SELECTION))
._arg(flag("bins", bins).help_heading(heading::TARGET_SELECTION))
._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
._arg(flag("examples", examples).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("example", "NAME", example)
.help_heading(heading::TARGET_SELECTION),
)
}

fn arg_targets_bins_examples(
Expand All @@ -123,15 +142,21 @@ pub trait CommandExt: Sized {
example: &'static str,
examples: &'static str,
) -> Self {
self._arg(optional_multi_opt("bin", "NAME", bin))
._arg(flag("bins", bins))
._arg(optional_multi_opt("example", "NAME", example))
._arg(flag("examples", examples))
self._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
._arg(flag("bins", bins).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("example", "NAME", example)
.help_heading(heading::TARGET_SELECTION),
)
._arg(flag("examples", examples).help_heading(heading::TARGET_SELECTION))
}

fn arg_targets_bin_example(self, bin: &'static str, example: &'static str) -> Self {
self._arg(optional_multi_opt("bin", "NAME", bin))
._arg(optional_multi_opt("example", "NAME", example))
self._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("example", "NAME", example)
.help_heading(heading::TARGET_SELECTION),
)
}

fn arg_features(self) -> Self {
Expand All @@ -141,34 +166,51 @@ pub trait CommandExt: Sized {
"FEATURES",
"Space or comma separated list of features to activate",
)
.short('F'),
.short('F')
.help_heading(heading::FEATURE_SELECTION),
)
._arg(
flag("all-features", "Activate all available features")
.help_heading(heading::FEATURE_SELECTION),
)
._arg(
flag(
"no-default-features",
"Do not activate the `default` feature",
)
.help_heading(heading::FEATURE_SELECTION),
)
._arg(flag("all-features", "Activate all available features"))
._arg(flag(
"no-default-features",
"Do not activate the `default` feature",
))
}

fn arg_release(self, release: &'static str) -> Self {
self._arg(flag("release", release).short('r'))
self._arg(
flag("release", release)
.short('r')
.help_heading(heading::COMPILATION_OPTIONS),
)
}

fn arg_profile(self, profile: &'static str) -> Self {
self._arg(opt("profile", profile).value_name("PROFILE-NAME"))
self._arg(
opt("profile", profile)
.value_name("PROFILE-NAME")
.help_heading(heading::COMPILATION_OPTIONS),
)
}

fn arg_doc(self, doc: &'static str) -> Self {
self._arg(flag("doc", doc))
}

fn arg_target_triple(self, target: &'static str) -> Self {
self._arg(multi_opt("target", "TRIPLE", target))
self._arg(multi_opt("target", "TRIPLE", target).help_heading(heading::COMPILATION_OPTIONS))
}

fn arg_target_dir(self) -> Self {
self._arg(
opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"),
opt("target-dir", "Directory for all generated artifacts")
.value_name("DIRECTORY")
.help_heading(heading::COMPILATION_OPTIONS),
)
}

Expand Down
7 changes: 4 additions & 3 deletions tests/testsuite/cargo_add/help/stdout.log
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ Options:
--manifest-path <PATH>
Path to Cargo.toml

-p, --package [<SPEC>]
Package to modify

-q, --quiet
Do not print cargo log messages

Expand Down Expand Up @@ -78,6 +75,10 @@ Options:
-Z <FLAG>
Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details

Package Selection:
-p, --package [<SPEC>]
Package to modify

Source:
--path <PATH>
Filesystem path to local crate to add
Expand Down
80 changes: 44 additions & 36 deletions tests/testsuite/cargo_bench/help/stdout.log
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,52 @@ Arguments:
[args]... Arguments for the bench binary

Options:
-q, --quiet Do not print cargo log messages
--lib Benchmark only this package's library
--bins Benchmark all binaries
--bin [<NAME>] Benchmark only the specified binary
--examples Benchmark all examples
--example [<NAME>] Benchmark only the specified example
--tests Benchmark all tests
--test [<NAME>] Benchmark only the specified test target
--benches Benchmark all benches
--bench [<NAME>] Benchmark only the specified bench target
--all-targets Benchmark all targets
--no-run Compile, but don't run benchmarks
-p, --package [<SPEC>] Package to run benchmarks for
--workspace Benchmark all packages in the workspace
--exclude <SPEC> Exclude packages from the benchmark
--all Alias for --workspace (deprecated)
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
--keep-going Do not abort the build as soon as there is an error (unstable)
-q, --quiet Do not print cargo log messages
--no-run Compile, but don't run benchmarks
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
--keep-going Do not abort the build as soon as there is an error (unstable)
--manifest-path <PATH> Path to Cargo.toml
--ignore-rust-version Ignore `rust-version` specification in packages
--message-format <FMT> Error format
--no-fail-fast Run all benchmarks regardless of failure
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
-h, --help Print help
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
--offline Run without accessing the network
--config <KEY=VALUE> Override a configuration value
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for
details

Target Selection:
--lib Benchmark only this package's library
--bins Benchmark all binaries
--bin [<NAME>] Benchmark only the specified binary
--examples Benchmark all examples
--example [<NAME>] Benchmark only the specified example
--tests Benchmark all tests
--test [<NAME>] Benchmark only the specified test target
--benches Benchmark all benches
--bench [<NAME>] Benchmark only the specified bench target
--all-targets Benchmark all targets

Package Selection:
-p, --package [<SPEC>] Package to run benchmarks for
--workspace Benchmark all packages in the workspace
--exclude <SPEC> Exclude packages from the benchmark
--all Alias for --workspace (deprecated)

Compilation Options:
--profile <PROFILE-NAME> Build artifacts with the specified profile
-F, --features <FEATURES> Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature
--target <TRIPLE> Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--manifest-path <PATH> Path to Cargo.toml
--ignore-rust-version Ignore `rust-version` specification in packages
--message-format <FMT> Error format
--no-fail-fast Run all benchmarks regardless of failure
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
-h, --help Print help
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
--offline Run without accessing the network
--config <KEY=VALUE> Override a configuration value
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for
details

Feature Selection:
-F, --features <FEATURES> Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature

Run `cargo help bench` for more detailed information.
50 changes: 29 additions & 21 deletions tests/testsuite/cargo_build/help/stdout.log
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,8 @@ Usage: cargo[EXE] build [OPTIONS]

Options:
-q, --quiet Do not print cargo log messages
-p, --package [<SPEC>] Package to build (see `cargo help pkgid`)
--workspace Build all packages in the workspace
--exclude <SPEC> Exclude packages from the build
--all Alias for --workspace (deprecated)
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
--keep-going Do not abort the build as soon as there is an error (unstable)
--lib Build only this package's library
--bins Build all binaries
--bin [<NAME>] Build only the specified binary
--examples Build all examples
--example [<NAME>] Build only the specified example
--tests Build all tests
--test [<NAME>] Build only the specified test target
--benches Build all benches
--bench [<NAME>] Build only the specified bench target
--all-targets Build all targets
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
-F, --features <FEATURES> Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature
--target <TRIPLE> Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--out-dir <PATH> Copy final artifacts to this directory (unstable)
--manifest-path <PATH> Path to Cargo.toml
--ignore-rust-version Ignore `rust-version` specification in packages
Expand All @@ -45,4 +24,33 @@ Options:
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for
details

Package Selection:
-p, --package [<SPEC>] Package to build (see `cargo help pkgid`)
--workspace Build all packages in the workspace
--exclude <SPEC> Exclude packages from the build
--all Alias for --workspace (deprecated)

Target Selection:
--lib Build only this package's library
--bins Build all binaries
--bin [<NAME>] Build only the specified binary
--examples Build all examples
--example [<NAME>] Build only the specified example
--tests Build all tests
--test [<NAME>] Build only the specified test target
--benches Build all benches
--bench [<NAME>] Build only the specified bench target
--all-targets Build all targets

Compilation Options:
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
--target <TRIPLE> Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts

Feature Selection:
-F, --features <FEATURES> Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature

Run `cargo help build` for more detailed information.
Loading

0 comments on commit 830931e

Please sign in to comment.