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 d500051
Show file tree
Hide file tree
Showing 33 changed files with 545 additions and 390 deletions.
12 changes: 6 additions & 6 deletions src/bin/cargo/commands/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ pub fn cli() -> Command {
.num_args(0..)
.last(true),
)
.arg_package_spec(
"Package to run benchmarks for",
"Benchmark all packages in the workspace",
"Exclude packages from the benchmark",
)
.arg_features()
.arg_targets_all(
"Benchmark only this package's library",
"Benchmark only the specified binary",
Expand All @@ -29,14 +35,8 @@ pub fn cli() -> Command {
"Benchmark all targets",
)
.arg(flag("no-run", "Compile, but don't run benchmarks"))
.arg_package_spec(
"Package to run benchmarks for",
"Benchmark all packages in the workspace",
"Exclude packages from the benchmark",
)
.arg_jobs()
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub fn cli() -> Command {
"Build all packages in the workspace",
"Exclude packages from the build",
)
.arg_features()
.arg_jobs()
.arg_targets_all(
"Build only this package's library",
Expand All @@ -28,7 +29,6 @@ pub fn cli() -> Command {
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg(
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub fn cli() -> Command {
"Check all packages in the workspace",
"Exclude packages from the check",
)
.arg_features()
.arg_jobs()
.arg_targets_all(
"Check only this package's library",
Expand All @@ -28,7 +29,6 @@ pub fn cli() -> Command {
)
.arg_release("Check artifacts in release mode, with optimizations")
.arg_profile("Check artifacts with the specified profile")
.arg_features()
.arg_target_triple("Check for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub fn cli() -> Command {
"Document all packages in the workspace",
"Exclude packages from the build",
)
.arg_features()
.arg(flag(
"no-deps",
"Don't build documentation for dependencies",
Expand All @@ -32,7 +33,6 @@ pub fn cli() -> Command {
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn cli() -> Command {
"Fix all packages in the workspace",
"Exclude packages from the fixes",
)
.arg_features()
.arg_jobs()
.arg_targets_all(
"Fix only this package's library",
Expand All @@ -26,7 +27,6 @@ pub fn cli() -> Command {
)
.arg_release("Fix artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Fix for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
6 changes: 3 additions & 3 deletions src/bin/cargo/commands/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ pub fn cli() -> Command {
"allow-dirty",
"Allow dirty working directories to be packaged",
))
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_features()
.arg_package_spec_no_all(
"Package(s) to assemble",
"Assemble all packages in the workspace",
"Don't assemble specified packages",
)
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
.arg_jobs()
.after_help("Run `cargo help package` for more detailed information.\n")
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ pub fn cli() -> Command {
"Name of the example target to run",
)
.arg_package("Package with the target to run")
.arg_features()
.arg_jobs()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub fn cli() -> Command {
.trailing_var_arg(true),
)
.arg_package("Package to build")
.arg_features()
.arg_jobs()
.arg_targets_all(
"Build only this package's library",
Expand All @@ -31,7 +32,6 @@ pub fn cli() -> Command {
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Target triple which compiles will be for")
.arg(
opt(
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub fn cli() -> Command {
"Opens the docs in a browser after the operation",
))
.arg_package("Package to document")
.arg_features()
.arg_jobs()
.arg_targets_all(
"Build only this package's library",
Expand All @@ -32,7 +33,6 @@ pub fn cli() -> Command {
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ pub fn cli() -> Command {
"Test all packages in the workspace",
"Exclude packages from the test",
)
.arg_features()
.arg_jobs()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ pub fn cli() -> Command {
"Display the tree for all packages in the workspace",
"Exclude specific workspace members",
)
.arg_features()
.arg(
flag("all", "Deprecated, use --no-dedupe instead")
.short('a')
.hide(true),
)
.arg(flag("all-targets", "Deprecated, use --target=all instead").hide(true))
.arg_features()
.arg_target_triple(
"Filter dependencies matching the given target-triple (default host platform). \
Pass `all` to include all targets.",
Expand Down
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

0 comments on commit d500051

Please sign in to comment.