use adrs_core::{AdrStatus, Repository};
use anyhow::{Context, Result};
use std::path::Path;
pub fn status(
root: &Path,
adr_number: u32,
new_status: &str,
superseded_by: Option<u32>,
) -> Result<()> {
if new_status.trim().is_empty() {
anyhow::bail!("Status cannot be empty or whitespace-only");
}
let repo = Repository::open(root).context("Failed to open ADR repository")?;
let status: AdrStatus = new_status.parse().unwrap_or_else(|_| {
AdrStatus::Custom(new_status.to_string())
});
if superseded_by.is_some() && !matches!(status, AdrStatus::Superseded) {
anyhow::bail!("--by can only be used with 'superseded' status");
}
let path = repo
.set_status(adr_number, status.clone(), superseded_by)
.context(format!("Failed to update status for ADR {}", adr_number))?;
match superseded_by {
Some(by) => println!(
"ADR {} status changed to {} (superseded by {})\n {}",
adr_number,
status,
by,
path.display()
),
None => println!(
"ADR {} status changed to {}\n {}",
adr_number,
status,
path.display()
),
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[test]
fn test_status_rejects_empty_and_whitespace() {
let temp = TempDir::new().unwrap();
let repo = Repository::init(temp.path(), None, true).unwrap();
let before = repo.get(1).unwrap().status;
for bad in ["", " ", " ", "\t"] {
let err = status(temp.path(), 1, bad, None).unwrap_err();
assert!(
err.to_string().contains("empty or whitespace-only"),
"expected empty-status error for {:?}, got: {}",
bad,
err
);
}
let adr = repo.get(1).unwrap();
assert_eq!(adr.status, before);
}
}