perf(xtask): Split xtask binaries

This will allow running an xtask without requiring building the world.
In most cases, a user will already have been building cargo but not in
CI.

The packages keep an `xtask-` prefix to help raise awareness of them but
exposed as `cargo <suffix>` to avoid having a direction proxy to wrap
`cargo run -p xtask-<suffix>` as `cargo xtask <suffix>`.
This commit is contained in:
Ed Page 2023-04-26 11:18:51 -05:00
parent c6f8ee9e51
commit 5b13963044
6 changed files with 75 additions and 88 deletions

View File

@ -1,2 +1,2 @@
[alias] [alias]
xtask = "run --package xtask --" unpublished = "run --package xtask-unpublished --"

2
Cargo.lock generated
View File

@ -3695,7 +3695,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "xtask" name = "xtask-unpublished"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",

View File

@ -1,5 +1,5 @@
[package] [package]
name = "xtask" name = "xtask-unpublished"
version = "0.0.0" version = "0.0.0"
edition = "2021" edition = "2021"
publish = false publish = false

View File

@ -1,4 +1,3 @@
mod unpublished;
mod xtask; mod xtask;
fn main() { fn main() {

View File

@ -5,10 +5,76 @@ use cargo::core::SourceId;
use cargo::util::command_prelude::*; use cargo::util::command_prelude::*;
pub fn cli() -> clap::Command { pub fn cli() -> clap::Command {
clap::Command::new("unpublished") clap::Command::new("xtask-unpublished")
.arg(
opt(
"verbose",
"Use verbose output (-vv very verbose/build.rs output)",
)
.short('v')
.action(ArgAction::Count)
.global(true),
)
.arg_quiet()
.arg(
opt("color", "Coloring: auto, always, never")
.value_name("WHEN")
.global(true),
)
.arg(flag("frozen", "Require Cargo.lock and cache are up to date").global(true))
.arg(flag("locked", "Require Cargo.lock is up to date").global(true))
.arg(flag("offline", "Run without accessing the network").global(true))
.arg(multi_opt("config", "KEY=VALUE", "Override a configuration value").global(true))
.arg(
Arg::new("unstable-features")
.help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
.short('Z')
.value_name("FLAG")
.action(ArgAction::Append)
.global(true),
)
} }
pub fn exec(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> cargo::CliResult { pub fn exec(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> cargo::CliResult {
config_configure(config, args)?;
unpublished(args, config)?;
Ok(())
}
fn config_configure(config: &mut Config, args: &ArgMatches) -> CliResult {
let verbose = args.verbose();
// quiet is unusual because it is redefined in some subcommands in order
// to provide custom help text.
let quiet = args.flag("quiet");
let color = args.get_one::<String>("color").map(String::as_str);
let frozen = args.flag("frozen");
let locked = args.flag("locked");
let offline = args.flag("offline");
let mut unstable_flags = vec![];
if let Some(values) = args.get_many::<String>("unstable-features") {
unstable_flags.extend(values.cloned());
}
let mut config_args = vec![];
if let Some(values) = args.get_many::<String>("config") {
config_args.extend(values.cloned());
}
config.configure(
verbose,
quiet,
color,
frozen,
locked,
offline,
&None,
&unstable_flags,
&config_args,
)?;
Ok(())
}
fn unpublished(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> cargo::CliResult {
let ws = args.workspace(config)?; let ws = args.workspace(config)?;
let mut results = Vec::new(); let mut results = Vec::new();
{ {
@ -84,3 +150,8 @@ pub fn exec(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> cargo:
Ok(()) Ok(())
} }
#[test]
fn verify_cli() {
cli().debug_assert();
}

View File

@ -1,83 +0,0 @@
use cargo::util::command_prelude::*;
pub fn cli() -> clap::Command {
clap::Command::new("xtask")
.subcommand_required(true)
.arg_required_else_help(true)
.arg(
opt(
"verbose",
"Use verbose output (-vv very verbose/build.rs output)",
)
.short('v')
.action(ArgAction::Count)
.global(true),
)
.arg_quiet()
.arg(
opt("color", "Coloring: auto, always, never")
.value_name("WHEN")
.global(true),
)
.arg(flag("frozen", "Require Cargo.lock and cache are up to date").global(true))
.arg(flag("locked", "Require Cargo.lock is up to date").global(true))
.arg(flag("offline", "Run without accessing the network").global(true))
.arg(multi_opt("config", "KEY=VALUE", "Override a configuration value").global(true))
.arg(
Arg::new("unstable-features")
.help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
.short('Z')
.value_name("FLAG")
.action(ArgAction::Append)
.global(true),
)
.subcommands([crate::unpublished::cli()])
}
pub fn exec(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> cargo::CliResult {
config_configure(config, args)?;
match args.subcommand() {
Some(("unpublished", args)) => crate::unpublished::exec(args, config)?,
Some((name, _)) => unreachable!("clap enforces {name} to not exist"),
None => unreachable!("clap enforces a subcommand is present"),
}
Ok(())
}
fn config_configure(config: &mut Config, args: &ArgMatches) -> CliResult {
let verbose = args.verbose();
// quiet is unusual because it is redefined in some subcommands in order
// to provide custom help text.
let quiet = args.flag("quiet");
let color = args.get_one::<String>("color").map(String::as_str);
let frozen = args.flag("frozen");
let locked = args.flag("locked");
let offline = args.flag("offline");
let mut unstable_flags = vec![];
if let Some(values) = args.get_many::<String>("unstable-features") {
unstable_flags.extend(values.cloned());
}
let mut config_args = vec![];
if let Some(values) = args.get_many::<String>("config") {
config_args.extend(values.cloned());
}
config.configure(
verbose,
quiet,
color,
frozen,
locked,
offline,
&None,
&unstable_flags,
&config_args,
)?;
Ok(())
}
#[test]
fn verify_cli() {
cli().debug_assert();
}