Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

xtask/src/main.rs

//! `cargo xtask <verb>`: edda'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 edda'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("."))
}

/// edda's CI plan: its locks, its workspace tests, and (full) its declared rows.
fn plan(root: &Path) -> Plan {
    Plan {
        repo: "edda".into(),
        root: root.to_path_buf(),
        steps: vec![
            lockcheck::step(root),
            // The whole workspace: nornir-auth-webauthn no longer links openssl in its
            // tests (webauthn-authenticator-rs went with the webauthn-rs path, A34-32).
            Step::cargo("test", &["test", "--workspace", "--locked"]),
            // The shared identity crates are all `default = []`, so `test` above compiles their
            // feature-gated tests to nothing: the conformance suite and the gRPC adapter
            // (nornir-identity), SSO, the directory's CSV and SCIM, sessions, the login script.
            // One step each, every feature on.
            Step::cargo("identity", &["test", "--locked", "-p", "nornir-identity", "--all-features"]),
            Step::cargo("identity-sso", &["test", "--locked", "-p", "nornir-identity-sso", "--all-features"]),
            Step::cargo("identity-directory", &["test", "--locked", "-p", "nornir-identity-directory", "--all-features"]),
            Step::cargo("identity-session", &["test", "--locked", "-p", "nornir-identity-session", "--all-features"]),
            Step::cargo("identity-web", &["test", "--locked", "-p", "nornir-identity-web", "--all-features"]),
            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!("edda xtask build: {e:#}");
            return 2;
        }
    };
    match nornir_build_thing::suite_cli::run(&root(), &parsed) {
        Ok(built) => {
            if !parsed.list && !built.is_empty() {
                println!("edda xtask build: built {}", built.join(", "));
            }
            0
        }
        Err(e) => {
            eprintln!("edda 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);
}

#[cfg(test)]
mod tests {
    use super::*;

    /// The shared identity crates are all `default = []`, so the workspace test
    /// compiles their feature-gated tests (the conformance suite, the gRPC adapter,
    /// SSO, the directory's CSV and SCIM) to nothing. Each must have its own step
    /// that turns its features on, or those tests never run in CI.
    #[test]
    fn plan_runs_every_identity_crate_with_its_features() {
        let plan = plan(Path::new("."));
        let lines: Vec<String> = plan.steps.iter().map(Step::describe).collect();
        for krate in [
            "nornir-identity",
            "nornir-identity-sso",
            "nornir-identity-directory",
            "nornir-identity-session",
            "nornir-identity-web",
        ] {
            let want = format!("cargo test --locked -p {krate} --all-features");
            assert!(
                lines.iter().any(|l| l.ends_with(&want)),
                "edda CI plan has no `{want}` step; steps: {lines:#?}"
            );
        }
    }
}