1 // Used to simulate a fairly large number of subcommands
2 //
3 // CLI used is from rustup 408ed84f0e50511ed44a405dd91365e5da588790
4 
5 use clap::{Arg, ArgAction, ArgGroup, Command};
6 use criterion::{criterion_group, criterion_main, Criterion};
7 
build_rustupnull8 pub fn build_rustup(c: &mut Criterion) {
9     c.bench_function("build_rustup", |b| b.iter(build_cli));
10 }
11 
parse_rustupnull12 pub fn parse_rustup(c: &mut Criterion) {
13     c.bench_function("parse_rustup", |b| {
14         b.iter(|| build_cli().get_matches_from(vec![""]))
15     });
16 }
17 
parse_rustup_with_scnull18 pub fn parse_rustup_with_sc(c: &mut Criterion) {
19     c.bench_function("parse_rustup_with_sc", |b| {
20         b.iter(|| build_cli().get_matches_from(vec!["rustup override add stable"]))
21     });
22 }
23 
build_clinull24 fn build_cli() -> Command {
25     Command::new("rustup")
26         .version("0.9.0") // Simulating
27         .about("The Rust toolchain installer")
28         .after_help(RUSTUP_HELP)
29         .arg(
30             Arg::new("verbose")
31                 .help("Enable verbose output")
32                 .short('v')
33                 .long("verbose")
34                 .action(ArgAction::SetTrue),
35         )
36         .subcommand(
37             Command::new("show")
38                 .about("Show the active and installed toolchains")
39                 .after_help(SHOW_HELP),
40         )
41         .subcommand(
42             Command::new("install")
43                 .about("Update Rust toolchains")
44                 .after_help(TOOLCHAIN_INSTALL_HELP)
45                 .hide(true) // synonym for 'toolchain install'
46                 .arg(Arg::new("toolchain").required(true)),
47         )
48         .subcommand(
49             Command::new("update")
50                 .about("Update Rust toolchains")
51                 .after_help(UPDATE_HELP)
52                 .arg(Arg::new("toolchain").required(true))
53                 .arg(
54                     Arg::new("no-self-update")
55                         .help("Don't perform self update when running the `rustup` command")
56                         .long("no-self-update")
57                         .action(ArgAction::SetTrue)
58                         .hide(true),
59                 ),
60         )
61         .subcommand(
62             Command::new("default")
63                 .about("Set the default toolchain")
64                 .after_help(DEFAULT_HELP)
65                 .arg(Arg::new("toolchain").required(true)),
66         )
67         .subcommand(
68             Command::new("toolchain")
69                 .about("Modify or query the installed toolchains")
70                 .after_help(TOOLCHAIN_HELP)
71                 .subcommand(Command::new("list").about("List installed toolchains"))
72                 .subcommand(
73                     Command::new("install")
74                         .about("Install or update a given toolchain")
75                         .arg(Arg::new("toolchain").required(true)),
76                 )
77                 .subcommand(
78                     Command::new("uninstall")
79                         .about("Uninstall a toolchain")
80                         .arg(Arg::new("toolchain").required(true)),
81                 )
82                 .subcommand(
83                     Command::new("link")
84                         .about("Create a custom toolchain by symlinking to a directory")
85                         .arg(Arg::new("toolchain").required(true))
86                         .arg(Arg::new("path").required(true)),
87                 )
88                 .subcommand(
89                     Command::new("update")
90                         .hide(true) // synonym for 'install'
91                         .arg(Arg::new("toolchain").required(true)),
92                 )
93                 .subcommand(
94                     Command::new("add")
95                         .hide(true) // synonym for 'install'
96                         .arg(Arg::new("toolchain").required(true)),
97                 )
98                 .subcommand(
99                     Command::new("remove")
100                         .hide(true) // synonym for 'uninstall'
101                         .arg(Arg::new("toolchain").required(true)),
102                 ),
103         )
104         .subcommand(
105             Command::new("target")
106                 .about("Modify a toolchain's supported targets")
107                 .subcommand(
108                     Command::new("list")
109                         .about("List installed and available targets")
110                         .arg(
111                             Arg::new("toolchain")
112                                 .long("toolchain")
113                                 .action(ArgAction::Set),
114                         ),
115                 )
116                 .subcommand(
117                     Command::new("add")
118                         .about("Add a target to a Rust toolchain")
119                         .arg(Arg::new("target").required(true))
120                         .arg(
121                             Arg::new("toolchain")
122                                 .long("toolchain")
123                                 .action(ArgAction::Set),
124                         ),
125                 )
126                 .subcommand(
127                     Command::new("remove")
128                         .about("Remove a target  from a Rust toolchain")
129                         .arg(Arg::new("target").required(true))
130                         .arg(
131                             Arg::new("toolchain")
132                                 .long("toolchain")
133                                 .action(ArgAction::Set),
134                         ),
135                 )
136                 .subcommand(
137                     Command::new("install")
138                         .hide(true) // synonym for 'add'
139                         .arg(Arg::new("target").required(true))
140                         .arg(
141                             Arg::new("toolchain")
142                                 .long("toolchain")
143                                 .action(ArgAction::Set),
144                         ),
145                 )
146                 .subcommand(
147                     Command::new("uninstall")
148                         .hide(true) // synonym for 'remove'
149                         .arg(Arg::new("target").required(true))
150                         .arg(
151                             Arg::new("toolchain")
152                                 .long("toolchain")
153                                 .action(ArgAction::Set),
154                         ),
155                 ),
156         )
157         .subcommand(
158             Command::new("component")
159                 .about("Modify a toolchain's installed components")
160                 .subcommand(
161                     Command::new("list")
162                         .about("List installed and available components")
163                         .arg(
164                             Arg::new("toolchain")
165                                 .long("toolchain")
166                                 .action(ArgAction::Set),
167                         ),
168                 )
169                 .subcommand(
170                     Command::new("add")
171                         .about("Add a component to a Rust toolchain")
172                         .arg(Arg::new("component").required(true))
173                         .arg(
174                             Arg::new("toolchain")
175                                 .long("toolchain")
176                                 .action(ArgAction::Set),
177                         )
178                         .arg(Arg::new("target").long("target").action(ArgAction::Set)),
179                 )
180                 .subcommand(
181                     Command::new("remove")
182                         .about("Remove a component from a Rust toolchain")
183                         .arg(Arg::new("component").required(true))
184                         .arg(
185                             Arg::new("toolchain")
186                                 .long("toolchain")
187                                 .action(ArgAction::Set),
188                         )
189                         .arg(Arg::new("target").long("target").action(ArgAction::Set)),
190                 ),
191         )
192         .subcommand(
193             Command::new("override")
194                 .about("Modify directory toolchain overrides")
195                 .after_help(OVERRIDE_HELP)
196                 .subcommand(Command::new("list").about("List directory toolchain overrides"))
197                 .subcommand(
198                     Command::new("set")
199                         .about("Set the override toolchain for a directory")
200                         .arg(Arg::new("toolchain").required(true)),
201                 )
202                 .subcommand(
203                     Command::new("unset")
204                         .about("Remove the override toolchain for a directory")
205                         .after_help(OVERRIDE_UNSET_HELP)
206                         .arg(
207                             Arg::new("path")
208                                 .long("path")
209                                 .action(ArgAction::Set)
210                                 .help("Path to the directory"),
211                         )
212                         .arg(
213                             Arg::new("nonexistent")
214                                 .long("nonexistent")
215                                 .action(ArgAction::SetTrue)
216                                 .help("Remove override toolchain for all nonexistent directories"),
217                         ),
218                 )
219                 .subcommand(
220                     Command::new("add")
221                         .hide(true) // synonym for 'set'
222                         .arg(Arg::new("toolchain").required(true)),
223                 )
224                 .subcommand(
225                     Command::new("remove")
226                         .hide(true) // synonym for 'unset'
227                         .about("Remove the override toolchain for a directory")
228                         .arg(Arg::new("path").long("path").action(ArgAction::Set))
229                         .arg(
230                             Arg::new("nonexistent")
231                                 .long("nonexistent")
232                                 .action(ArgAction::SetTrue)
233                                 .help("Remove override toolchain for all nonexistent directories"),
234                         ),
235                 ),
236         )
237         .subcommand(
238             Command::new("run")
239                 .about("Run a command with an environment configured for a given toolchain")
240                 .after_help(RUN_HELP)
241                 .arg(Arg::new("toolchain").required(true))
242                 .arg(
243                     Arg::new("command")
244                         .required(true)
245                         .num_args(1..)
246                         .trailing_var_arg(true),
247                 ),
248         )
249         .subcommand(
250             Command::new("which")
251                 .about("Display which binary will be run for a given command")
252                 .arg(Arg::new("command").required(true)),
253         )
254         .subcommand(
255             Command::new("doc")
256                 .about("Open the documentation for the current toolchain")
257                 .after_help(DOC_HELP)
258                 .arg(
259                     Arg::new("book")
260                         .long("book")
261                         .action(ArgAction::SetTrue)
262                         .help("The Rust Programming Language book"),
263                 )
264                 .arg(
265                     Arg::new("std")
266                         .long("std")
267                         .action(ArgAction::SetTrue)
268                         .help("Standard library API documentation"),
269                 )
270                 .group(ArgGroup::new("page").args(["book", "std"])),
271         )
272         .subcommand(
273             Command::new("man")
274                 .about("View the man page for a given command")
275                 .arg(Arg::new("command").required(true))
276                 .arg(
277                     Arg::new("toolchain")
278                         .long("toolchain")
279                         .action(ArgAction::Set),
280                 ),
281         )
282         .subcommand(
283             Command::new("self")
284                 .about("Modify the rustup installation")
285                 .subcommand(Command::new("update").about("Download and install updates to rustup"))
286                 .subcommand(
287                     Command::new("uninstall")
288                         .about("Uninstall rustup.")
289                         .arg(Arg::new("no-prompt").short('y').action(ArgAction::SetTrue)),
290                 )
291                 .subcommand(
292                     Command::new("upgrade-data").about("Upgrade the internal data format."),
293                 ),
294         )
295         .subcommand(
296             Command::new("telemetry")
297                 .about("rustup telemetry commands")
298                 .hide(true)
299                 .subcommand(Command::new("enable").about("Enable rustup telemetry"))
300                 .subcommand(Command::new("disable").about("Disable rustup telemetry"))
301                 .subcommand(Command::new("analyze").about("Analyze stored telemetry")),
302         )
303         .subcommand(
304             Command::new("set")
305                 .about("Alter rustup settings")
306                 .subcommand(
307                     Command::new("default-host")
308                         .about("The triple used to identify toolchains when not specified")
309                         .arg(Arg::new("host_triple").required(true)),
310                 ),
311         )
312 }
313 
314 static RUSTUP_HELP: &str = r"
315 rustup installs The Rust Programming Language from the official
316 release channels, enabling you to easily switch between stable, beta,
317 and nightly compilers and keep them updated. It makes cross-compiling
318 simpler with binary builds of the standard library for common platforms.
319 
320 If you are new to Rust consider running `rustup doc --book`
321 to learn Rust.";
322 
323 static SHOW_HELP: &str = r"
324 Shows the name of the active toolchain and the version of `rustc`.
325 
326 If the active toolchain has installed support for additional
327 compilation targets, then they are listed as well.
328 
329 If there are multiple toolchains installed then all installed
330 toolchains are listed as well.";
331 
332 static UPDATE_HELP: &str = r"
333 With no toolchain specified, the `update` command updates each of the
334 installed toolchains from the official release channels, then updates
335 rustup itself.
336 
337 If given a toolchain argument then `update` updates that toolchain,
338 the same as `rustup toolchain install`.
339 
340 'toolchain' specifies a toolchain name, such as 'stable', 'nightly',
341 or '1.8.0'. For more information see `rustup help toolchain`.";
342 
343 static TOOLCHAIN_INSTALL_HELP: &str = r"
344 Installs a specific rust toolchain.
345 
346 The 'install' command is an alias for 'rustup update <toolchain>'.
347 
348 'toolchain' specifies a toolchain name, such as 'stable', 'nightly',
349 or '1.8.0'. For more information see `rustup help toolchain`.";
350 
351 static DEFAULT_HELP: &str = r"
352 Sets the default toolchain to the one specified. If the toolchain is
353 not already installed then it is installed first.";
354 
355 static TOOLCHAIN_HELP: &str = r"
356 Many `rustup` commands deal with *toolchains*, a single installation
357 of the Rust compiler. `rustup` supports multiple types of
358 toolchains. The most basic track the official release channels:
359 'stable', 'beta' and 'nightly'; but `rustup` can also install
360 toolchains from the official archives, for alternate host platforms,
361 and from local builds.
362 
363 Standard release channel toolchain names have the following form:
364 
365     <channel>[-<date>][-<host>]
366 
367     <channel>       = stable|beta|nightly|<version>
368     <date>          = YYYY-MM-DD
369     <host>          = <target-triple>
370 
371 'channel' is either a named release channel or an explicit version
372 number, such as '1.8.0'. Channel names can be optionally appended with
373 an archive date, as in 'nightly-2014-12-18', in which case the
374 toolchain is downloaded from the archive for that date.
375 
376 Finally, the host may be specified as a target triple. This is most
377 useful for installing a 32-bit compiler on a 64-bit platform, or for
378 installing the [MSVC-based toolchain] on Windows. For example:
379 
380     rustup toolchain install stable-x86_64-pc-windows-msvc
381 
382 For convenience, elements of the target triple that are omitted will be
383 inferred, so the above could be written:
384 
385     $ rustup default stable-msvc
386 
387 Toolchain names that don't name a channel instead can be used to name
388 custom toolchains with the `rustup toolchain link` command.";
389 
390 static OVERRIDE_HELP: &str = r"
391 Overrides configure rustup to use a specific toolchain when
392 running in a specific directory.
393 
394 Directories can be assigned their own Rust toolchain with
395 `rustup override`. When a directory has an override then
396 any time `rustc` or `cargo` is run inside that directory,
397 or one of its child directories, the override toolchain
398 will be invoked.
399 
400 To pin to a specific nightly:
401 
402     rustup override set nightly-2014-12-18
403 
404 Or a specific stable release:
405 
406     rustup override set 1.0.0
407 
408 To see the active toolchain use `rustup show`. To remove the override
409 and use the default toolchain again, `rustup override unset`.";
410 
411 static OVERRIDE_UNSET_HELP: &str = r"
412 If `--path` argument is present, removes the override toolchain for
413 the specified directory. If `--nonexistent` argument is present, removes
414 the override toolchain for all nonexistent directories. Otherwise,
415 removes the override toolchain for the current directory.";
416 
417 static RUN_HELP: &str = r"
418 Configures an environment to use the given toolchain and then runs
419 the specified program. The command may be any program, not just
420 rustc or cargo. This can be used for testing arbitrary toolchains
421 without setting an override.
422 
423 Commands explicitly proxied by `rustup` (such as `rustc` and `cargo`)
424 also have a shorthand for this available. The toolchain can be set by
425 using `+toolchain` as the first argument. These are equivalent:
426 
427     cargo +nightly build
428 
429     rustup run nightly cargo build";
430 
431 static DOC_HELP: &str = r"
432 Opens the documentation for the currently active toolchain with the
433 default browser.
434 
435 By default, it opens the documentation index. Use the various flags to
436 open specific pieces of documentation.";
437 
438 criterion_group!(benches, build_rustup, parse_rustup, parse_rustup_with_sc);
439 
440 criterion_main!(benches);
441