From d1a5ee9be52850e34e582aa0f6f68907203cdab4 Mon Sep 17 00:00:00 2001 From: Gegy Date: Sat, 15 Jul 2023 13:50:23 +0200 Subject: [PATCH] Fix: drop all old files from destinations, even if replaced --- src/cache.rs | 48 ++++++++++++++++++++++++------------------------ src/main.rs | 10 ++++------ 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 6271f28..3fad034 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -30,6 +30,7 @@ async fn write_cache_index>(path: P, index: &Index) -> io::Result pub struct Loader { root: PathBuf, + old_entries: HashMap, entries: HashMap, used_entries: HashSet, } @@ -42,13 +43,15 @@ impl Loader { } let index = read_cache_index(&root.join("index.json")).await?; - let entries = index + let entries: HashMap = index .entries .into_iter() .map(|entry| (entry.key.clone(), entry)) .collect(); - Ok(Loader { root, entries, used_entries: HashSet::new() }) + let old_entries = entries.clone(); + + Ok(Loader { root, old_entries, entries, used_entries: HashSet::new() }) } pub fn entry>(&mut self, key: K) -> Entry { @@ -68,10 +71,27 @@ impl Loader { } } - pub async fn close(self) -> io::Result<()> { + pub async fn close(mut self) -> io::Result> { + let stale_entries: Vec = self + .entries + .values() + .filter(|entry| !self.used_entries.contains(&entry.key)) + .map(|entry| entry.key.clone()) + .collect(); + for key in stale_entries { + let entry = self.entries.remove(&key).unwrap(); + let reference = self.reference_for(&entry); + fs::remove_file(&reference.path).await?; + } + + let old_files = self.old_entries.clone().values() + .map(|entry| self.reference_for(&entry)) + .collect(); + let entries = self.entries.into_values().collect(); write_cache_index(&self.root.join("index.json"), &Index { entries }).await?; - Ok(()) + + Ok(old_files) } async fn update_entry( @@ -127,26 +147,6 @@ impl Loader { fn path_for(&self, key: &str) -> PathBuf { self.root.join(key) } - - pub async fn drop_stale(&mut self) -> io::Result> { - let stale_entries: Vec = self - .entries - .values() - .filter(|entry| !self.used_entries.contains(&entry.key)) - .map(|entry| entry.key.clone()) - .collect(); - - let mut stale_references = Vec::with_capacity(stale_entries.len()); - for key in stale_entries { - let entry = self.entries.remove(&key).unwrap(); - let reference = self.reference_for(&entry); - fs::remove_file(&reference.path).await?; - - stale_references.push(reference); - } - - Ok(stale_references) - } } #[derive(Serialize, Deserialize, Clone)] diff --git a/src/main.rs b/src/main.rs index 7c4e1b4..f688f1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,27 +183,25 @@ async fn prepare_destination( } } - let stale_files = cache.drop_stale().await?; - - cache.close().await?; + let old_files = cache.close().await?; Ok(PreparedDestination { root: destination.path.clone(), cache_files, - stale_files, + old_files, }) } struct PreparedDestination { root: PathBuf, cache_files: Vec<(String, cache::Reference)>, - stale_files: Vec, + old_files: Vec, } impl PreparedDestination { async fn apply(&self) -> Result<()> { if self.root.exists() { - for reference in &self.stale_files { + for reference in &self.old_files { reference.remove_from(&self.root).await?; } } else {