Skip to content

Commit 2a32818

Browse files
committed
WIP: fix(cli): Make --help easier to browse
This mirrors some of the categories from `cargo help` (the man pages).
1 parent 2d1842c commit 2a32818

File tree

2 files changed

+103
-53
lines changed

2 files changed

+103
-53
lines changed

src/cargo/util/command_prelude.rs

+74-32
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ pub use clap::{value_parser, Arg, ArgAction, ArgMatches};
2323

2424
pub use clap::Command;
2525

26+
pub mod heading {
27+
pub const PACKAGE_SELECTION: &str = "Package Selection";
28+
pub const TARGET_SELECTION: &str = "Target Selection";
29+
pub const FEATURE_SELECTION: &str = "Feature Selection";
30+
pub const COMPILATION_OPTIONS: &str = "Compilation Options";
31+
}
32+
2633
pub trait CommandExt: Sized {
2734
fn _arg(self, arg: Arg) -> Self;
2835

@@ -34,8 +41,10 @@ pub trait CommandExt: Sized {
3441
all: &'static str,
3542
exclude: &'static str,
3643
) -> Self {
37-
self.arg_package_spec_no_all(package, all, exclude)
38-
._arg(flag("all", "Alias for --workspace (deprecated)"))
44+
self.arg_package_spec_no_all(package, all, exclude)._arg(
45+
flag("all", "Alias for --workspace (deprecated)")
46+
.help_heading(heading::PACKAGE_SELECTION),
47+
)
3948
}
4049

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

5564
fn arg_package_spec_simple(self, package: &'static str) -> Self {
56-
self._arg(optional_multi_opt("package", "SPEC", package).short('p'))
65+
self._arg(
66+
optional_multi_opt("package", "SPEC", package)
67+
.short('p')
68+
.help_heading(heading::PACKAGE_SELECTION),
69+
)
5770
}
5871

5972
fn arg_package(self, package: &'static str) -> Self {
6073
self._arg(
6174
optional_opt("package", package)
6275
.short('p')
63-
.value_name("SPEC"),
76+
.value_name("SPEC")
77+
.help_heading(heading::PACKAGE_SELECTION),
6478
)
6579
}
6680

@@ -91,11 +105,13 @@ pub trait CommandExt: Sized {
91105
all: &'static str,
92106
) -> Self {
93107
self.arg_targets_lib_bin_example(lib, bin, bins, example, examples)
94-
._arg(optional_multi_opt("test", "NAME", test))
95-
._arg(flag("tests", tests))
96-
._arg(optional_multi_opt("bench", "NAME", bench))
97-
._arg(flag("benches", benches))
98-
._arg(flag("all-targets", all))
108+
._arg(optional_multi_opt("test", "NAME", test).help_heading(heading::TARGET_SELECTION))
109+
._arg(flag("tests", tests).help_heading(heading::TARGET_SELECTION))
110+
._arg(
111+
optional_multi_opt("bench", "NAME", bench).help_heading(heading::TARGET_SELECTION),
112+
)
113+
._arg(flag("benches", benches).help_heading(heading::TARGET_SELECTION))
114+
._arg(flag("all-targets", all).help_heading(heading::TARGET_SELECTION))
99115
}
100116

101117
fn arg_targets_lib_bin_example(
@@ -106,11 +122,14 @@ pub trait CommandExt: Sized {
106122
example: &'static str,
107123
examples: &'static str,
108124
) -> Self {
109-
self._arg(flag("lib", lib))
110-
._arg(optional_multi_opt("bin", "NAME", bin))
111-
._arg(flag("bins", bins))
112-
._arg(optional_multi_opt("example", "NAME", example))
113-
._arg(flag("examples", examples))
125+
self._arg(flag("lib", lib).help_heading(heading::TARGET_SELECTION))
126+
._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
127+
._arg(flag("bins", bins).help_heading(heading::TARGET_SELECTION))
128+
._arg(
129+
optional_multi_opt("example", "NAME", example)
130+
.help_heading(heading::TARGET_SELECTION),
131+
)
132+
._arg(flag("examples", examples).help_heading(heading::TARGET_SELECTION))
114133
}
115134

116135
fn arg_targets_bins_examples(
@@ -120,15 +139,21 @@ pub trait CommandExt: Sized {
120139
example: &'static str,
121140
examples: &'static str,
122141
) -> Self {
123-
self._arg(optional_multi_opt("bin", "NAME", bin))
124-
._arg(flag("bins", bins))
125-
._arg(optional_multi_opt("example", "NAME", example))
126-
._arg(flag("examples", examples))
142+
self._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
143+
._arg(flag("bins", bins).help_heading(heading::TARGET_SELECTION))
144+
._arg(
145+
optional_multi_opt("example", "NAME", example)
146+
.help_heading(heading::TARGET_SELECTION),
147+
)
148+
._arg(flag("examples", examples).help_heading(heading::TARGET_SELECTION))
127149
}
128150

129151
fn arg_targets_bin_example(self, bin: &'static str, example: &'static str) -> Self {
130-
self._arg(optional_multi_opt("bin", "NAME", bin))
131-
._arg(optional_multi_opt("example", "NAME", example))
152+
self._arg(optional_multi_opt("bin", "NAME", bin).help_heading(heading::TARGET_SELECTION))
153+
._arg(
154+
optional_multi_opt("example", "NAME", example)
155+
.help_heading(heading::TARGET_SELECTION),
156+
)
132157
}
133158

134159
fn arg_features(self) -> Self {
@@ -138,34 +163,51 @@ pub trait CommandExt: Sized {
138163
"FEATURES",
139164
"Space or comma separated list of features to activate",
140165
)
141-
.short('F'),
166+
.short('F')
167+
.help_heading(heading::FEATURE_SELECTION),
168+
)
169+
._arg(
170+
flag("all-features", "Activate all available features")
171+
.help_heading(heading::FEATURE_SELECTION),
172+
)
173+
._arg(
174+
flag(
175+
"no-default-features",
176+
"Do not activate the `default` feature",
177+
)
178+
.help_heading(heading::FEATURE_SELECTION),
142179
)
143-
._arg(flag("all-features", "Activate all available features"))
144-
._arg(flag(
145-
"no-default-features",
146-
"Do not activate the `default` feature",
147-
))
148180
}
149181

150182
fn arg_release(self, release: &'static str) -> Self {
151-
self._arg(flag("release", release).short('r'))
183+
self._arg(
184+
flag("release", release)
185+
.short('r')
186+
.help_heading(heading::COMPILATION_OPTIONS),
187+
)
152188
}
153189

154190
fn arg_profile(self, profile: &'static str) -> Self {
155-
self._arg(opt("profile", profile).value_name("PROFILE-NAME"))
191+
self._arg(
192+
opt("profile", profile)
193+
.value_name("PROFILE-NAME")
194+
.help_heading(heading::COMPILATION_OPTIONS),
195+
)
156196
}
157197

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

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

166206
fn arg_target_dir(self) -> Self {
167207
self._arg(
168-
opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"),
208+
opt("target-dir", "Directory for all generated artifacts")
209+
.value_name("DIRECTORY")
210+
.help_heading(heading::COMPILATION_OPTIONS),
169211
)
170212
}
171213

tests/testsuite/cargo_build/help/stdout.log

+29-21
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,15 @@ Usage: cargo build [OPTIONS]
44

55
Options:
66
-q, --quiet Do not print cargo log messages
7-
-p, --package [<SPEC>] Package to build (see `cargo help pkgid`)
8-
--workspace Build all packages in the workspace
9-
--exclude <SPEC> Exclude packages from the build
107
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
11-
--all Alias for --workspace (deprecated)
128
--color <WHEN> Coloring: auto, always, never
139
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs
1410
--keep-going Do not abort the build as soon as there is an error (unstable)
1511
--frozen Require Cargo.lock and cache are up to date
16-
--lib Build only this package's library
17-
--bin [<NAME>] Build only the specified binary
1812
--locked Require Cargo.lock is up to date
19-
--bins Build all binaries
2013
--offline Run without accessing the network
2114
--config <KEY=VALUE> Override a configuration value
22-
--example [<NAME>] Build only the specified example
23-
--examples Build all examples
2415
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
25-
--test [<NAME>] Build only the specified test target
26-
--tests Build all tests
27-
--bench [<NAME>] Build only the specified bench target
28-
--benches Build all benches
29-
--all-targets Build all targets
30-
-r, --release Build artifacts in release mode, with optimizations
31-
--profile <PROFILE-NAME> Build artifacts with the specified profile
32-
-F, --features <FEATURES> Space or comma separated list of features to activate
33-
--all-features Activate all available features
34-
--no-default-features Do not activate the `default` feature
35-
--target <TRIPLE> Build for the target triple
36-
--target-dir <DIRECTORY> Directory for all generated artifacts
3716
--out-dir <PATH> Copy final artifacts to this directory (unstable)
3817
--manifest-path <PATH> Path to Cargo.toml
3918
--ignore-rust-version Ignore `rust-version` specification in packages
@@ -44,4 +23,33 @@ Options:
4423
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
4524
-h, --help Print help
4625

26+
Package Selection:
27+
-p, --package [<SPEC>] Package to build (see `cargo help pkgid`)
28+
--workspace Build all packages in the workspace
29+
--exclude <SPEC> Exclude packages from the build
30+
--all Alias for --workspace (deprecated)
31+
32+
Target Selection:
33+
--lib Build only this package's library
34+
--bin [<NAME>] Build only the specified binary
35+
--bins Build all binaries
36+
--example [<NAME>] Build only the specified example
37+
--examples Build all examples
38+
--test [<NAME>] Build only the specified test target
39+
--tests Build all tests
40+
--bench [<NAME>] Build only the specified bench target
41+
--benches Build all benches
42+
--all-targets Build all targets
43+
44+
Compilation Options:
45+
-r, --release Build artifacts in release mode, with optimizations
46+
--profile <PROFILE-NAME> Build artifacts with the specified profile
47+
--target <TRIPLE> Build for the target triple
48+
--target-dir <DIRECTORY> Directory for all generated artifacts
49+
50+
Feature Selection:
51+
-F, --features <FEATURES> Space or comma separated list of features to activate
52+
--all-features Activate all available features
53+
--no-default-features Do not activate the `default` feature
54+
4755
Run `cargo help build` for more detailed information.

0 commit comments

Comments
 (0)