diff --git a/crates/font-store/src/store.rs b/crates/font-store/src/store.rs index db1bd6f0..880d9857 100644 --- a/crates/font-store/src/store.rs +++ b/crates/font-store/src/store.rs @@ -639,12 +639,16 @@ impl FontStore { entry.files.retain(|f| !removing.contains(&f.name)); let folder = self.dir.join(&entry.dir); let stage = Stage::new(&self.dir)?; - let moving: Vec<(PathBuf, PathBuf)> = if entry.files.is_empty() { + let mut moving: Vec<(PathBuf, PathBuf)> = removing.iter().map(|f| (folder.join(f), stage.dir.join(f))).collect(); + let last = entry.files.is_empty(); + if last { + // The licence goes with the last style. Files the store didn't install stay, and + // keep the folder. + if let Some(licence) = entry.license_file.clone().filter(|n| safe_file_name(n) && !removing.contains(n)) { + moving.push((folder.join(&licence), stage.dir.join(&licence))); + } manifest.families.remove(pos); - vec![(folder, stage.dir.join("removed"))] - } else { - removing.iter().map(|f| (folder.join(f), stage.dir.join(f))).collect() - }; + } let mut moved = Vec::new(); for (from, to) in &moving { if from.exists() { @@ -653,7 +657,12 @@ impl FontStore { } } match self.write_manifest(&manifest) { - Ok(()) => Ok(()), + Ok(()) => { + if last { + let _ = std::fs::remove_dir(&folder); + } + Ok(()) + } Err(e) => { for (from, to) in moved { let _ = std::fs::rename(to, from); diff --git a/crates/font-store/src/tests.rs b/crates/font-store/src/tests.rs index cb0420e8..de1aece8 100644 --- a/crates/font-store/src/tests.rs +++ b/crates/font-store/src/tests.rs @@ -694,6 +694,19 @@ mod store { assert!(dir.join("outside.ttf").exists()); assert!(!dir.join("testsans/TestSans-Bold.ttf").exists()); assert_eq!(store.installed_family(GOOGLE_FONTS, "Test Sans").unwrap().files.len(), 2); + + // The last style takes the licence with it; the unlisted file and its folder stay. + let rest: Vec = store.installed_family(GOOGLE_FONTS, "Test Sans").unwrap().files.iter().map(|f| f.name.clone()).collect(); + store.remove_files(GOOGLE_FONTS, "Test Sans", &rest).unwrap(); + assert!(store.installed_family(GOOGLE_FONTS, "Test Sans").is_none()); + let left: Vec<_> = std::fs::read_dir(dir.join("testsans")).unwrap().map(|e| e.unwrap().file_name()).collect(); + assert_eq!(left, ["Unlisted.ttf"]); + + // A folder left empty goes. + std::fs::remove_file(dir.join("testsans/Unlisted.ttf")).unwrap(); + store.install_face(&index, index.find_face("Test Sans", "Bold").unwrap(), &Cancel::new(), &mut none).unwrap(); + store.remove_files(GOOGLE_FONTS, "Test Sans", &["TestSans-Bold.ttf".into()]).unwrap(); + assert!(!dir.join("testsans").exists()); let _ = std::fs::remove_dir_all(dir); }