font-store: removing a family's last style keeps files the store didn't install

This commit is contained in:
aiongg committed 2026-10-26 01:55:20 +00:00
1 parent e51a392278
commit fdecd50f47
2 files changed
+28 -6

No files matched your search

+15 -6
View File
@@ -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);
+13
View File
@@ -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<String> = 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);
}