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

nordisk/holger

server/cli/tests/the_packaged_server_names_its_commit.rs

//! **A `cargo install holger` binary names the commit it was published from**
//! (lane GUN-VERSION-STAMP, 2026-10-31).
//!
//! `cargo install holger` 3.0.0 from crates.io printed `holger v3.0.0 (unknown)`: a
//! published crate has no `.git`, so `server/lib/build.rs` found no HEAD to read. cargo
//! writes `.cargo_vcs_info.json` (with `git.sha1`) into every package it makes from a git
//! checkout, and that is the commit the crate was published from.
//!
//! This test does what crates.io does: `cargo package -p holger-server-lib`, the package
//! unpacked into a directory outside every git checkout, and a small binary built on the
//! unpacked copy that prints `holger_server_lib::VERSION_LINE`, the line `holger --version`
//! prints (`server/cli/src/lib.rs`). The other holger crates come from this checkout
//! (`[patch.crates-io]`), as crates.io's copies of the same commit would. Then:
//!
//! 1. the line names the short sha of the package's `.cargo_vcs_info.json`, never `unknown`;
//! 2. the same binary built on the git checkout keeps its old line: HEAD's short sha.

use std::path::{Path, PathBuf};
use std::process::Command;

fn root() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR"))
        .ancestors()
        .nth(2)
        .expect("server/cli is two below the root")
        .to_path_buf()
}

fn cargo() -> String {
    std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())
}

/// The target directory this test binary was built in (`<target>/debug/deps/<test>`), so the
/// nested builds below reuse their dependencies from one run to the next.
fn target_root() -> PathBuf {
    if let Some(t) = std::env::var_os("CARGO_TARGET_DIR") {
        return PathBuf::from(t);
    }
    let exe = std::env::current_exe().expect("the test binary has a path");
    exe.ancestors()
        .nth(3)
        .expect("<target>/<profile>/deps/<test>")
        .to_path_buf()
}

fn run(cmd: &mut Command, what: &str) -> String {
    let out = cmd
        .output()
        .unwrap_or_else(|e| panic!("{what}: could not run: {e}"));
    assert!(
        out.status.success(),
        "{what} failed ({}):\n{}\n{}",
        out.status,
        String::from_utf8_lossy(&out.stdout),
        String::from_utf8_lossy(&out.stderr)
    );
    String::from_utf8_lossy(&out.stdout).into_owned()
}

/// The workspace crates `of` reaches by path (normal and build edges, transitively).
fn path_edges(of: &str) -> Vec<String> {
    let meta = run(
        Command::new(cargo())
            .args(["metadata", "--no-deps", "--format-version", "1"])
            .current_dir(root()),
        "cargo metadata",
    );
    let meta: serde_json::Value = serde_json::from_str(&meta).expect("cargo metadata is JSON");
    let packages = meta["packages"].as_array().expect("packages");
    let edges = |name: &str| -> Vec<String> {
        packages
            .iter()
            .filter(|p| p["name"] == name)
            .flat_map(|p| p["dependencies"].as_array().cloned().unwrap_or_default())
            .filter(|d| d["path"].is_string() && d["kind"] != "dev")
            .map(|d| d["name"].as_str().expect("a dependency name").to_string())
            // Only this workspace's members (an estate crate such as holger-fleet is
            // packaged from its own workspace, at the version crates.io has).
            .filter(|n| packages.iter().any(|p| p["name"] == n.as_str()))
            .collect()
    };
    let mut seen: Vec<String> = Vec::new();
    let mut todo = edges(of);
    while let Some(c) = todo.pop() {
        if c != of && !seen.contains(&c) {
            todo.extend(edges(&c));
            seen.push(c);
        }
    }
    seen.sort();
    seen
}

/// Every workspace member but holger-server-lib, as `name = { path = ... }` patch lines.
fn sibling_patches() -> String {
    let meta = run(
        Command::new(cargo())
            .args(["metadata", "--no-deps", "--format-version", "1"])
            .current_dir(root()),
        "cargo metadata",
    );
    let meta: serde_json::Value = serde_json::from_str(&meta).expect("cargo metadata is JSON");
    let mut out = String::new();
    for p in meta["packages"].as_array().expect("packages") {
        let name = p["name"].as_str().expect("a name");
        if name == "holger-server-lib" {
            continue;
        }
        let dir = Path::new(p["manifest_path"].as_str().expect("a manifest"))
            .parent()
            .expect("a manifest dir")
            .display()
            .to_string();
        out.push_str(&format!("{name} = {{ path = {dir:?} }}\n"));
    }
    out
}

/// A small binary on `holger_server_lib` at `dep`, printing `VERSION_LINE`.
fn version_probe(dir: &Path, dep: &Path, patches: &str) {
    std::fs::create_dir_all(dir.join("src")).unwrap();
    std::fs::write(
        dir.join("Cargo.toml"),
        format!(
            "[package]\nname = \"version-probe\"\nversion = \"0.0.0\"\nedition = \"2021\"\npublish = false\n\n\
             [dependencies]\nholger-server-lib = {{ path = {:?}, default-features = false }}\n\n\
             [patch.crates-io]\n{patches}\n[workspace]\n",
            dep.display().to_string()
        ),
    )
    .unwrap();
    std::fs::write(
        dir.join("src/main.rs"),
        "fn main() {\n    println!(\"{}\", holger_server_lib::VERSION_LINE);\n}\n",
    )
    .unwrap();
    // The workspace's lock: the probe builds the versions the workspace builds.
    std::fs::copy(root().join("Cargo.lock"), dir.join("Cargo.lock")).unwrap();
}

fn probe_version(dir: &Path, target: &Path) -> String {
    run(
        Command::new(cargo())
            .args(["run", "--quiet", "--manifest-path"])
            .arg(dir.join("Cargo.toml"))
            .arg("--target-dir")
            .arg(target)
            .current_dir(dir),
        "the version probe",
    )
    .trim()
    .to_owned()
}

/// The `git.sha1` of a `.cargo_vcs_info.json`.
fn vcs_sha1(json: &str) -> String {
    let v: serde_json::Value = serde_json::from_str(json).expect(".cargo_vcs_info.json is JSON");
    let sha = v["git"]["sha1"].as_str().expect("git.sha1").to_owned();
    assert!(
        sha.len() == 40 && sha.bytes().all(|b| b.is_ascii_hexdigit()),
        "git.sha1 is a 40-hex commit id: {sha:?}"
    );
    sha
}

#[test]
fn a_packaged_holger_names_the_commit_it_was_published_from() {
    let work = target_root().join("packaged-version");
    let pkg_target = work.join("package-target");
    let probe_target = work.join("probe-target");
    let version = env!("CARGO_PKG_VERSION"); // the workspace version, holger-server-lib's too

    // 1. What crates.io gets: the package of holger-server-lib, with its .cargo_vcs_info.json.
    run(
        Command::new(cargo())
            .arg("package")
            // holger-server-lib's own edges at this commit (holger-job-runner's `heimdall`,
            // lane HOL-HEIMDALL-02; holger-sandbox 4.0.0 and the 3.1.0 crates of a release,
            // HOL-310-RELEASE) resolve against the packages made beside it, as a publish in
            // order would against crates.io: every workspace crate it reaches by path.
            .args(
                path_edges("holger-server-lib")
                    .iter()
                    .flat_map(|c| ["-p", c.as_str()]),
            )
            .args(["-p", "holger-server-lib", "--no-verify", "--allow-dirty"])
            .arg("--target-dir")
            .arg(&pkg_target)
            .current_dir(root()),
        "cargo package -p holger-server-lib",
    );
    let crate_file = pkg_target.join(format!("package/holger-server-lib-{version}.crate"));

    // 2. Unpacked OUTSIDE every git checkout: crates.io's copy has no `.git` above it either.
    let outside = std::env::temp_dir().join(format!(
        "holger-packaged-version-{}-{}",
        std::process::id(),
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_nanos()
    ));
    std::fs::create_dir_all(&outside).unwrap();
    run(
        Command::new("tar")
            .arg("-xzf")
            .arg(&crate_file)
            .arg("-C")
            .arg(&outside),
        "unpacking the package",
    );
    let unpacked = outside.join(format!("holger-server-lib-{version}"));
    let in_git = Command::new("git")
        .args(["rev-parse", "--git-dir"])
        .current_dir(&unpacked)
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false);
    assert!(
        !in_git,
        "{} is inside a git checkout; the test needs a temp dir outside one",
        unpacked.display()
    );
    let vcs = std::fs::read_to_string(unpacked.join(".cargo_vcs_info.json"))
        .expect("cargo package wrote .cargo_vcs_info.json");
    let sha = vcs_sha1(&vcs);
    let short = &sha[..7];

    // 3. The packaged copy names the commit it was packaged from.
    let patches = sibling_patches();
    let probe = outside.join("probe");
    version_probe(&probe, &unpacked, &patches);
    let line = probe_version(&probe, &probe_target);
    assert_eq!(
        line,
        format!("holger v{version} ({short})"),
        "a packaged holger must name its commit {short} (from .cargo_vcs_info.json)"
    );

    // 4. The git checkout keeps its line: HEAD's short sha.
    let head = run(
        Command::new("git")
            .args(["-c", "safe.directory=*", "rev-parse", "HEAD"])
            .current_dir(root()),
        "git rev-parse HEAD",
    );
    let checkout_probe = outside.join("checkout-probe");
    version_probe(&checkout_probe, &root().join("server/lib"), &patches);
    let line = probe_version(&checkout_probe, &probe_target);
    assert_eq!(
        line,
        format!("holger v{version} ({})", &head.trim()[..7]),
        "a git checkout keeps HEAD's short sha"
    );

    let _ = std::fs::remove_dir_all(&outside);
}