1use anyhow::Context;
7use anyhow::Result;
8use cargo_metadata::{Metadata, MetadataCommand, Package};
9use clap::{Args, Parser, Subcommand};
10use once_cell::sync::OnceCell;
11
12mod bump_versions;
13mod install;
14mod versions;
15
16#[derive(Parser)]
17#[command(name = "xtask")]
18#[command(about = "Sched ext repository scripts and helpers")]
19struct Cli {
20 #[arg(short = 'v', long = "verbose", help = "Verbose logging")]
21 verbose: bool,
22
23 #[command(subcommand)]
24 command: Commands,
25}
26
27#[derive(Args)]
28#[group(required = true, multiple = false)]
29struct BumpTarget {
30 #[arg(short = 'p', long = "package", help = "Specific crates to bump")]
31 packages: Vec<String>,
32 #[arg(long, help = "Bump all workspace crates")]
33 all: bool,
34}
35
36#[derive(Subcommand)]
37enum Commands {
38 Versions {
39 #[arg(short = 'f', long = "format", default_value = "json")]
40 format: versions::Format,
41 },
42 BumpVersions {
43 #[command(flatten)]
44 target: BumpTarget,
45 #[arg(
46 short = 'm',
47 long = "min-version",
48 help = "Minimum version floor; crates below this are set to it, others bump patch"
49 )]
50 min_version: Option<String>,
51 },
52 Install(install::InstallArgs),
55}
56
57fn main() {
58 let cli = Cli::parse();
59
60 let log_level = if cli.verbose {
61 log::LevelFilter::Debug
62 } else {
63 log::LevelFilter::Warn
64 };
65
66 simplelog::TermLogger::init(
67 log_level,
68 simplelog::Config::default(),
69 simplelog::TerminalMode::Stderr,
70 simplelog::ColorChoice::Auto,
71 )
72 .unwrap();
73
74 let res = match cli.command {
75 Commands::Versions { format } => versions::version_command(format),
76 Commands::BumpVersions {
77 target,
78 min_version,
79 } => bump_versions::bump_versions_command(target.packages, target.all, min_version),
80 Commands::Install(args) => install::install_command(args),
81 };
82
83 if let Err(e) = res {
84 eprintln!("Failed to run command: {e}");
85 std::process::exit(1);
86 }
87}
88
89pub fn get_cargo_metadata() -> Result<&'static Metadata> {
90 static CARGO_METADATA: OnceCell<Metadata> = OnceCell::new();
91
92 CARGO_METADATA.get_or_try_init(|| {
93 MetadataCommand::new()
94 .exec()
95 .context("Failed to run cargo metadata")
96 })
97}
98
99pub fn get_workspace_packages() -> Result<Vec<&'static Package>> {
100 let metadata = get_cargo_metadata()?;
101
102 let workspace_packages: Vec<&Package> = metadata
104 .packages
105 .iter()
106 .filter(|package| metadata.workspace_members.contains(&package.id))
107 .collect();
108
109 Ok(workspace_packages)
110}
111
112pub fn get_rust_paths() -> Result<Vec<std::path::PathBuf>> {
113 let packages = get_workspace_packages()?;
114 Ok(packages
115 .iter()
116 .map(|pkg| pkg.manifest_path.as_std_path().to_path_buf())
117 .collect())
118}