1// Used to simulate a fairly large number of subcommands 2// 3// CLI used is from rustup 408ed84f0e50511ed44a405dd91365e5da588790 4 5use clap::{Arg, ArgAction, ArgGroup, Command}; 6use criterion::{criterion_group, criterion_main, Criterion}; 7 8pub fn build_rustup(c: &mut Criterion) { 9 c.bench_function("build_rustup", |b| b.iter(build_cli)); 10} 11 12pub 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 18pub 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 24fn 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 314static RUSTUP_HELP: &str = r" 315rustup installs The Rust Programming Language from the official 316release channels, enabling you to easily switch between stable, beta, 317and nightly compilers and keep them updated. It makes cross-compiling 318simpler with binary builds of the standard library for common platforms. 319 320If you are new to Rust consider running `rustup doc --book` 321to learn Rust."; 322 323static SHOW_HELP: &str = r" 324Shows the name of the active toolchain and the version of `rustc`. 325 326If the active toolchain has installed support for additional 327compilation targets, then they are listed as well. 328 329If there are multiple toolchains installed then all installed 330toolchains are listed as well."; 331 332static UPDATE_HELP: &str = r" 333With no toolchain specified, the `update` command updates each of the 334installed toolchains from the official release channels, then updates 335rustup itself. 336 337If given a toolchain argument then `update` updates that toolchain, 338the same as `rustup toolchain install`. 339 340'toolchain' specifies a toolchain name, such as 'stable', 'nightly', 341or '1.8.0'. For more information see `rustup help toolchain`."; 342 343static TOOLCHAIN_INSTALL_HELP: &str = r" 344Installs a specific rust toolchain. 345 346The 'install' command is an alias for 'rustup update <toolchain>'. 347 348'toolchain' specifies a toolchain name, such as 'stable', 'nightly', 349or '1.8.0'. For more information see `rustup help toolchain`."; 350 351static DEFAULT_HELP: &str = r" 352Sets the default toolchain to the one specified. If the toolchain is 353not already installed then it is installed first."; 354 355static TOOLCHAIN_HELP: &str = r" 356Many `rustup` commands deal with *toolchains*, a single installation 357of the Rust compiler. `rustup` supports multiple types of 358toolchains. The most basic track the official release channels: 359'stable', 'beta' and 'nightly'; but `rustup` can also install 360toolchains from the official archives, for alternate host platforms, 361and from local builds. 362 363Standard 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 372number, such as '1.8.0'. Channel names can be optionally appended with 373an archive date, as in 'nightly-2014-12-18', in which case the 374toolchain is downloaded from the archive for that date. 375 376Finally, the host may be specified as a target triple. This is most 377useful for installing a 32-bit compiler on a 64-bit platform, or for 378installing the [MSVC-based toolchain] on Windows. For example: 379 380 rustup toolchain install stable-x86_64-pc-windows-msvc 381 382For convenience, elements of the target triple that are omitted will be 383inferred, so the above could be written: 384 385 $ rustup default stable-msvc 386 387Toolchain names that don't name a channel instead can be used to name 388custom toolchains with the `rustup toolchain link` command."; 389 390static OVERRIDE_HELP: &str = r" 391Overrides configure rustup to use a specific toolchain when 392running in a specific directory. 393 394Directories can be assigned their own Rust toolchain with 395`rustup override`. When a directory has an override then 396any time `rustc` or `cargo` is run inside that directory, 397or one of its child directories, the override toolchain 398will be invoked. 399 400To pin to a specific nightly: 401 402 rustup override set nightly-2014-12-18 403 404Or a specific stable release: 405 406 rustup override set 1.0.0 407 408To see the active toolchain use `rustup show`. To remove the override 409and use the default toolchain again, `rustup override unset`."; 410 411static OVERRIDE_UNSET_HELP: &str = r" 412If `--path` argument is present, removes the override toolchain for 413the specified directory. If `--nonexistent` argument is present, removes 414the override toolchain for all nonexistent directories. Otherwise, 415removes the override toolchain for the current directory."; 416 417static RUN_HELP: &str = r" 418Configures an environment to use the given toolchain and then runs 419the specified program. The command may be any program, not just 420rustc or cargo. This can be used for testing arbitrary toolchains 421without setting an override. 422 423Commands explicitly proxied by `rustup` (such as `rustc` and `cargo`) 424also have a shorthand for this available. The toolchain can be set by 425using `+toolchain` as the first argument. These are equivalent: 426 427 cargo +nightly build 428 429 rustup run nightly cargo build"; 430 431static DOC_HELP: &str = r" 432Opens the documentation for the currently active toolchain with the 433default browser. 434 435By default, it opens the documentation index. Use the various flags to 436open specific pieces of documentation."; 437 438criterion_group!(benches, build_rustup, parse_rustup, parse_rustup_with_sc); 439 440criterion_main!(benches); 441