refactor(cli): apply simplify findings (Plan B Phases 4-6 polish)

- session.rs: drop save_manifest_raw — its only caller was
  after_manifest_change itself; the pub(crate) advertised the exact
  bypass-the-cache-refresh footgun the wrapper exists to eliminate.
  Inline the encrypt + atomic_write pair.
- session.rs: into_kdf_params(self) → to_kdf_params(&self). Body just
  copies three u32s; the consume-self had no ownership benefit and
  forced the round-trip test to rebuild a ParamsFile field-by-field.
- helpers.rs: add git_rm(repo, paths, context) wrapper around git_run
  + the load-bearing --ignore-unmatch flag. Replaces two near-identical
  three-line "build rm_args, extend, git_run" blocks in trash.rs.
- trash.rs: purge_item_filesystem drops the if x.exists() pre-checks
  (TOCTOU + redundant stat per item per trash-empty iteration). Uses
  ErrorKind::NotFound swallow on remove_file/remove_dir_all instead.
- basic_flows.rs: trim trash_empty_batches_into_one_commit's sleep
  comment to just the WHY.
This commit is contained in:
adlee-was-taken
2026-05-09 11:50:42 -04:00
parent 4b657e71f1
commit c4777cc0bb
4 changed files with 29 additions and 38 deletions

View File

@@ -49,15 +49,20 @@ pub(super) fn purge_item_filesystem(
id: &relicario_core::ItemId,
title: &str,
) -> Result<Vec<String>> {
use std::fs;
use std::{fs, io::ErrorKind};
let item_rel = format!("items/{}.enc", id.as_str());
let att_rel = format!("attachments/{}", id.as_str());
let item_path = vault.item_path(id);
if item_path.exists() { fs::remove_file(&item_path)?; }
let att_dir = vault.root().join("attachments").join(id.as_str());
if att_dir.exists() { fs::remove_dir_all(&att_dir)?; }
let ignore_missing = |r: std::io::Result<()>| -> Result<()> {
match r {
Ok(()) => Ok(()),
Err(e) if e.kind() == ErrorKind::NotFound => Ok(()),
Err(e) => Err(e.into()),
}
};
ignore_missing(fs::remove_file(vault.item_path(id)))?;
ignore_missing(fs::remove_dir_all(vault.root().join("attachments").join(id.as_str())))?;
manifest.remove(id);
eprintln!("Purged: {title}");
@@ -76,10 +81,7 @@ pub fn cmd_purge(query: String) -> Result<()> {
vault.after_manifest_change(&manifest)?;
let purge_ctx = format!("purge \"{}\" ({})", title, id.as_str());
let mut rm_args: Vec<&str> = vec!["rm", "-rf", "--ignore-unmatch"];
let path_refs: Vec<&str> = paths.iter().map(String::as_str).collect();
rm_args.extend(path_refs.iter().copied());
crate::helpers::git_run(vault.root(), &rm_args, &format!("{purge_ctx}: git rm"))?;
crate::helpers::git_rm(vault.root(), &paths, &format!("{purge_ctx}: git rm"))?;
crate::helpers::git_run(
vault.root(),
&["add", "manifest.enc"],
@@ -130,10 +132,7 @@ pub fn cmd_trash_empty() -> Result<()> {
vault.after_manifest_change(&manifest)?;
let mut rm_args: Vec<&str> = vec!["rm", "-rf", "--ignore-unmatch"];
let path_refs: Vec<&str> = all_paths.iter().map(String::as_str).collect();
rm_args.extend(path_refs.iter().copied());
crate::helpers::git_run(vault.root(), &rm_args, "trash empty: git rm")?;
crate::helpers::git_rm(vault.root(), &all_paths, "trash empty: git rm")?;
crate::helpers::git_run(
vault.root(),
&["add", "manifest.enc"],