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 Mar 28, 2023
1 parent 2d1842c commit 2a32818
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 53 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 @@ -23,6 +23,13 @@ pub use clap::{value_parser, Arg, ArgAction, ArgMatches};

pub use clap::Command;

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 @@ -34,8 +41,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 @@ -48,19 +57,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 @@ -91,11 +105,13 @@ pub trait CommandExt: Sized {
all: &'static str,
) -> Self {
self.arg_targets_lib_bin_example(lib, bin, bins, example, examples)
._arg(optional_multi_opt("test", "NAME", test))
._arg(flag("tests", tests))
._arg(optional_multi_opt("bench", "NAME", bench))
._arg(flag("benches", benches))
._arg(flag("all-targets", all))
._arg(optional_multi_opt("test", "NAME", test).help_heading(heading::TARGET_SELECTION))
._arg(flag("tests", tests).help_heading(heading::TARGET_SELECTION))
._arg(
optional_multi_opt("bench", "NAME", bench).help_heading(heading::TARGET_SELECTION),
)
._arg(flag("benches", benches).help_heading(heading::TARGET_SELECTION))
._arg(flag("all-targets", all).help_heading(heading::TARGET_SELECTION))
}

fn arg_targets_lib_bin_example(
Expand All @@ -106,11 +122,14 @@ pub trait CommandExt: Sized {
example: &'static str,
examples: &'static str,
) -> Self {
self._arg(flag("lib", lib))
._arg(optional_multi_opt("bin", "NAME", bin))
._arg(flag("bins", bins))
._arg(optional_multi_opt("example", "NAME", example))
._arg(flag("examples", examples))
self._arg(flag("lib", lib).help_heading(heading::TARGET_SELECTION))
._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_bins_examples(
Expand All @@ -120,15 +139,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 @@ -138,34 +163,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
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,36 +4,15 @@ Usage: cargo 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
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--all Alias for --workspace (deprecated)
--color <WHEN> Coloring: auto, always, never
-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)
--frozen Require Cargo.lock and cache are up to date
--lib Build only this package's library
--bin [<NAME>] Build only the specified binary
--locked Require Cargo.lock is up to date
--bins Build all binaries
--offline Run without accessing the network
--config <KEY=VALUE> Override a configuration value
--example [<NAME>] Build only the specified example
--examples Build all examples
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
--test [<NAME>] Build only the specified test target
--tests Build all tests
--bench [<NAME>] Build only the specified bench target
--benches Build all benches
--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 @@ -44,4 +23,33 @@ Options:
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
-h, --help Print help

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
--bin [<NAME>] Build only the specified binary
--bins Build all binaries
--example [<NAME>] Build only the specified example
--examples Build all examples
--test [<NAME>] Build only the specified test target
--tests Build all tests
--bench [<NAME>] Build only the specified bench target
--benches Build all benches
--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.

0 comments on commit 2a32818

Please sign in to comment.