add --version flag with calver-dev version string
build.rs computes the dev version as YYYY-MM-DD-dev+COMMIT using git.
Release builds override via the RANGER_VERSION env var set in the
GitHub Actions workflow.
Cargo.toml version set to 0.0.0 since it is never used directly.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 687655f..33c9a57 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -29,6 +29,8 @@ jobs:
echo "version=${CALVER}+${SHORT_SHA}" >> $GITHUB_OUTPUT
- name: Build
+ env:
+ RANGER_VERSION: ${{ steps.version.outputs.version }}
run: |
cargo build --release
tar -czf ranger-aarch64-apple-darwin.tar.gz -C target/release ranger
diff --git a/Cargo.lock b/Cargo.lock
index bbd646e..6156cd0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1498,7 +1498,7 @@ dependencies = [
[[package]]
name = "ranger"
-version = "0.1.0"
+version = "0.0.0"
dependencies = [
"assert_cmd",
"axum",
diff --git a/Cargo.toml b/Cargo.toml
index 4b62f2c..eee5950 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "ranger"
-version = "0.1.0"
+version = "0.0.0"
edition = "2024"
[[bin]]
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..9b45b4a
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,23 @@
+use std::process::Command;
+
+fn main() {
+ // Release builds set RANGER_VERSION externally; don't override.
+ if std::env::var("RANGER_VERSION").is_ok() {
+ return;
+ }
+
+ let date = cmd("date", &["-u", "+%Y-%m-%d"]).unwrap_or("0000-00-00".into());
+ let commit = cmd("git", &["rev-parse", "--short=8", "HEAD"]).unwrap_or("unknown".into());
+ let version = format!("{date}-dev+{commit}");
+
+ println!("cargo:rustc-env=RANGER_VERSION={version}");
+}
+
+fn cmd(program: &str, args: &[&str]) -> Option<String> {
+ let output = Command::new(program).args(args).output().ok()?;
+ if !output.status.success() {
+ return None;
+ }
+ let s = String::from_utf8_lossy(&output.stdout).trim().to_string();
+ if s.is_empty() { None } else { Some(s) }
+}
diff --git a/src/bin/ranger/main.rs b/src/bin/ranger/main.rs
index 45f2623..eb11752 100644
--- a/src/bin/ranger/main.rs
+++ b/src/bin/ranger/main.rs
@@ -7,8 +7,11 @@ use clap_complete::engine::ArgValueCompleter;
use std::path::PathBuf;
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
+/// Build-time version set by build.rs (dev) or release workflow.
+const VERSION: &str = env!("RANGER_VERSION");
+
#[derive(Parser)]
-#[command(name = "ranger", about = "Personal task tracker")]
+#[command(name = "ranger", version = VERSION, about = "Personal task tracker")]
struct Cli {
/// Output as JSON
#[arg(long, global = true)]
diff --git a/tests/cli.rs b/tests/cli.rs
index 40d223b..df2a893 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -498,4 +498,12 @@ fn full_workflow() {
stdout.contains("Ranger"),
"backlog name completions should include backlog names"
);
+
+ // --version prints version string
+ ranger(db_path)
+ .args(["--version"])
+ .assert()
+ .success()
+ .stdout(predicates::str::contains("ranger "))
+ .stdout(predicates::str::is_match(r"ranger \S+").unwrap());
}