xtask/src/main.rs
//! `cargo xtask <verb>`: Skidbladnir's repository tasks.
//!
//! ```text
//! cargo xtask ci [--quick|--nightly] [--list] [--only <prefix>]
//! cargo xtask build --suite ORIGINAL [--variant <v>] [--list]
//! ```
//!
//! The plan runner, the receipt and the lock check are nornir-xtask-support's; the
//! rows are read off `.nornir/build-variants.toml` by nornir-build-thing. This file
//! only lists Skidbladnir's steps.
use std::path::{Path, PathBuf};
use nornir_xtask_support::ci::{self, Mode, Plan, Step};
use nornir_xtask_support::lockcheck;
fn root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).parent().map(Path::to_path_buf).unwrap_or_else(|| PathBuf::from("."))
}
/// Skidbladnir's CI plan: its locks, its workspace tests, and (full) its declared rows.
fn plan(root: &Path) -> Plan {
Plan {
repo: "Skidbladnir".into(),
root: root.to_path_buf(),
steps: vec![
lockcheck::step(root),
Step::cargo("test", &["test", "--workspace", "--locked"]),
Step::cargo("rows:ORIGINAL", &["xtask", "build", "--suite", "ORIGINAL"]).from(Mode::Full),
],
}
}
fn build(args: &[String]) -> i32 {
let parsed = match nornir_build_thing::suite_cli::parse(args) {
Ok(p) => p,
Err(e) => {
eprintln!("Skidbladnir xtask build: {e:#}");
return 2;
}
};
match nornir_build_thing::suite_cli::run(&root(), &parsed) {
Ok(built) => {
if !parsed.list && !built.is_empty() {
println!("Skidbladnir xtask build: built {}", built.join(", "));
}
0
}
Err(e) => {
eprintln!("Skidbladnir xtask build FAILED: {e:#}");
1
}
}
}
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let code = match args.first().map(String::as_str) {
Some("ci") => ci::main(&plan(&root()), &args[1..]),
Some("build") => build(&args[1..]),
_ => {
eprintln!("usage: cargo xtask ci [--quick|--nightly] [--list] | build --suite ORIGINAL [--variant <v>] [--list]");
2
}
};
std::process::exit(code);
}