use std::path::PathBuf;
use anyhow::{
Context,
Result,
};
use clap::Parser;
#[derive(Parser, Debug)]
pub struct DevArgs {
#[arg(long, default_value = ".")]
repo_path: PathBuf,
#[arg(long, default_value = "version")]
format: String,
}
pub fn dev(args: DevArgs) -> Result<()> {
let repo = gix::discover(&args.repo_path).with_context(|| {
format!(
"Failed to discover git repository at {}",
args.repo_path.display()
)
})?;
let head = repo.head().context("Failed to read HEAD")?;
let commit_id = head.id().context("HEAD does not point to a commit")?;
let short_sha = commit_id
.shorten()
.context("Failed to shorten commit SHA")?;
let dev_version = format!("0.0.0-dev-{}", short_sha);
match args.format.as_str() {
"version" => println!("{}", dev_version),
"json" => println!(
"{{\"version\":\"{}\",\"sha\":\"{}\"}}",
dev_version, short_sha
),
_ => anyhow::bail!("Invalid format: {}", args.format),
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dev_current_repo() {
let args = DevArgs {
repo_path: ".".into(),
format: "version".to_string(),
};
let result = dev(args);
if let Err(e) = result {
let err_msg = e.to_string();
assert!(
err_msg.contains("Failed to discover git repository")
|| err_msg.contains("Failed to read HEAD")
|| err_msg.contains("HEAD does not point to a commit")
);
}
}
#[test]
fn test_dev_json_format() {
let args = DevArgs {
repo_path: ".".into(),
format: "json".to_string(),
};
let _ = dev(args);
}
#[test]
fn test_dev_invalid_format() {
let args = DevArgs {
repo_path: ".".into(),
format: "invalid".to_string(),
};
let result = dev(args);
if let Err(e) = result {
let err_msg = e.to_string();
assert!(
err_msg.contains("Invalid format")
|| err_msg.contains("Failed to discover git repository")
|| err_msg.contains("Failed to read HEAD")
|| err_msg.contains("HEAD does not point to a commit")
);
} else {
}
}
#[test]
fn test_dev_nonexistent_repo() {
let args = DevArgs {
repo_path: "/nonexistent/path".into(),
format: "version".to_string(),
};
assert!(dev(args).is_err());
}
}