You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vibed/nbd/.beans/nbd-no88--add-version-flag-...

4.3 KiB

title status type priority created_at updated_at
Add --version flag with X.Y.Z+GitSha format completed feature normal 2026-03-10T23:30:31Z 2026-03-10T23:30:31Z

Goal

Add a --version / -V flag to nbd that prints the version in the format:

0.1.0+7e311d6

where 0.1.0 comes from Cargo.toml and 7e311d6 is the short git SHA of the commit the binary was built from, embedded at compile time via build.rs.

Why

Allows agents and users to confirm exactly which build of nbd is running without inspecting the binary separately.

Implementation plan

1. Create build.rs at the crate root

fn main() {
    // Capture the short git SHA at build time.
    // Falls back to "unknown" when git is unavailable (e.g. CI without repo).
    let sha = std::process::Command::new("git")
        .args(["rev-parse", "--short", "HEAD"])
        .output()
        .ok()
        .and_then(|o| if o.status.success() { Some(o.stdout) } else { None })
        .and_then(|b| String::from_utf8(b).ok())
        .map(|s| s.trim().to_string())
        .unwrap_or_else(|| "unknown".to_string());

    println\!("cargo:rustc-env=GIT_SHORT_SHA={sha}");
    // Re-run whenever HEAD changes (new commits).
    println\!("cargo:rerun-if-changed=.git/HEAD");
    println\!("cargo:rerun-if-changed=.git/refs");
}

Key points:

  • Uses std::process::Command — no extra build dependencies.
  • Graceful fallback to "unknown" when git is absent (clean Nix sandbox builds may not have .git/).
  • rerun-if-changed directives ensure the SHA is refreshed on every commit without forcing a full rebuild every run.

2. Add a VERSION constant in src/main.rs

Add near the top of main.rs after the existing CLAUDE_MD_SNIPPET constant:

/// Full version string embedded at compile time: `"X.Y.Z+shortsha"`.
const VERSION: &str = concat\!(env\!("CARGO_PKG_VERSION"), "+", env\!("GIT_SHORT_SHA"));

3. Wire VERSION into the clap #[command(...)] attribute

Change:

#[command(name = "nbd", about = "Manage work tickets for agent workflows")]

to:

#[command(name = "nbd", about = "Manage work tickets for agent workflows", version = VERSION)]

clap automatically handles -V / --version when version is set: it prints the string and exits 0. No manual subcommand or dispatch code needed.

4. Update README.md

Add a brief note in the Usage section or Installation section:

nbd --version   # prints e.g. 0.1.0+7e311d6

5. Add an integration test in tests/integration.rs

/// `nbd --version` exits 0 and stdout contains the semver.
#[test]
fn version_flag_exits_zero_with_semver() {
    let tmp = tempfile::tempdir().expect("tempdir");
    let output = std::process::Command::new(env\!("CARGO_BIN_EXE_nbd"))
        .arg("--version")
        .current_dir(tmp.path())
        .output()
        .expect("spawn nbd");
    assert\!(output.status.success(), "--version should exit 0");
    let stdout = String::from_utf8(output.stdout).unwrap();
    // Should contain the package version (semver).
    assert\!(stdout.contains("0.1.0"), "--version should include semver: {stdout}");
    // Should contain a '+' separator and at least one hex char after it.
    assert\!(stdout.contains('+'), "--version should contain '+': {stdout}");
}

Files to change

File Change
build.rs Create — emit GIT_SHORT_SHA env var
src/main.rs Add VERSION const; add version = VERSION to #[command]
README.md Add nbd --version example
tests/integration.rs Add version_flag_exits_zero_with_semver test

Edge cases

  • No git available (Nix sandbox): build.rs falls back to "unknown", producing 0.1.0+unknown. This is acceptable for packaged builds where the version is already pinned by the derivation.
  • clap version output format: clap 4 prints nbd X.Y.Z+sha (prefixed by the binary name) to stdout, then exits 0. This is standard behaviour — the test should check stdout.contains("0.1.0") rather than an exact match.
  • No --json support for --version: clap intercepts --version before dispatch reaches the --json handling. This is acceptable; version output is always plain text.

Validation

cargo fmt && cargo check && cargo clippy && cargo test
cargo run -- --version
# Expected output: nbd 0.1.0+<sha>