Phase 6c fix: TagStore delete/contains also see stamped #74

Merged
osobh merged 1 commits from phase-6c-fix-delete-contains into main 2026-07-14 19:27:42 +00:00
+26 -9
View File
@@ -268,22 +268,39 @@ impl TagStore {
/// no such tag existed. /// no such tag existed.
pub async fn delete(&self, key: &str) -> Result<bool> { pub async fn delete(&self, key: &str) -> Result<bool> {
validate_key(key)?; validate_key(key)?;
let path = self.tag_path(key); // Phase 6c fix (2026-07-14): try both layers. Modern pins
match tokio::fs::remove_file(&path).await { // land in tags-v2/; without unlinking the stamped file too,
Ok(()) => Ok(true), // `unpin` prints "no such tag" and leaves the tag behind.
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false), let mut removed = false;
Err(e) => Err(anyhow::Error::from(e)), let legacy = self.tag_path(key);
match tokio::fs::remove_file(&legacy).await {
Ok(()) => removed = true,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(anyhow::Error::from(e)),
} }
let stamped = self.stamped_tag_path(key);
match tokio::fs::remove_file(&stamped).await {
Ok(()) => removed = true,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(anyhow::Error::from(e)),
}
// Also clear any TTL sidecar.
let expiry = self.stamped_expiry_path(key);
let _ = tokio::fs::remove_file(&expiry).await;
Ok(removed)
} }
/// Whether a tag with the given name exists. /// Whether a tag with the given name exists.
pub async fn contains(&self, key: &str) -> Result<bool> { pub async fn contains(&self, key: &str) -> Result<bool> {
validate_key(key)?; validate_key(key)?;
match tokio::fs::metadata(self.tag_path(key)).await { // Same fallthrough as get(): visible via either layer counts.
Ok(_) => Ok(true), if tokio::fs::metadata(self.tag_path(key)).await.is_ok() {
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false), return Ok(true);
Err(e) => Err(anyhow::Error::from(e)),
} }
if tokio::fs::metadata(self.stamped_tag_path(key)).await.is_ok() {
return Ok(true);
}
Ok(false)
} }
/// List every stored tag. Sorted by key for deterministic output. /// List every stored tag. Sorted by key for deterministic output.