cadmus_core/ota/
cleanup.rs1use std::io;
2use std::path::Path;
3
4include!(concat!(env!("OUT_DIR"), "/bundled_assets.rs"));
5
6pub fn clean_bundled_files(install_dir: &Path) -> io::Result<()> {
13 for asset in BUNDLED_ASSET_FILES {
14 remove_file_if_exists(&install_dir.join(asset))?;
15 remove_empty_parent_dirs(&install_dir.join(asset), install_dir)?;
16 }
17
18 clean_libs_dir(&install_dir.join("libs"))?;
19 remove_empty_parent_dirs(&install_dir.join("libs"), install_dir)?;
20
21 Ok(())
22}
23
24fn clean_libs_dir(libs_dir: &Path) -> io::Result<()> {
25 if let Err(e) = std::fs::remove_dir_all(libs_dir) {
26 if e.kind() != io::ErrorKind::NotFound {
27 return Err(e);
28 }
29 }
30
31 Ok(())
32}
33
34fn remove_file_if_exists(path: &Path) -> io::Result<()> {
35 match std::fs::remove_file(path) {
36 Ok(()) => Ok(()),
37 Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()),
38 Err(e) => Err(e),
39 }
40}
41
42fn remove_empty_parent_dirs(path: &Path, install_dir: &Path) -> io::Result<()> {
43 let mut current = path.parent();
44
45 while let Some(dir) = current {
46 if dir == install_dir {
47 return Ok(());
48 }
49
50 if !remove_empty_dir_if_exists(dir)? {
51 return Ok(());
52 }
53
54 current = dir.parent();
55 }
56
57 Ok(())
58}
59
60fn remove_empty_dir_if_exists(path: &Path) -> io::Result<bool> {
61 match std::fs::remove_dir(path) {
62 Ok(()) => Ok(true),
63 Err(e)
64 if e.kind() == io::ErrorKind::NotFound
65 || e.kind() == io::ErrorKind::DirectoryNotEmpty =>
66 {
67 Ok(false)
68 }
69 Err(e) => Err(e),
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::device::CURRENT_DEVICE;
77
78 #[test]
79 fn cleanup_removes_bundled_files_but_keeps_user_files() {
80 let tmp = tempfile::tempdir().unwrap();
81 let install_dir = tmp.path().join(CURRENT_DEVICE.install_subdir());
82
83 std::fs::create_dir_all(install_dir.join("fonts")).unwrap();
84 std::fs::create_dir_all(install_dir.join("icons")).unwrap();
85 std::fs::create_dir_all(install_dir.join("libs")).unwrap();
86
87 std::fs::write(install_dir.join("fonts/NotoSans-Regular.ttf"), b"owned").unwrap();
88 std::fs::write(install_dir.join("fonts/custom.ttf"), b"user").unwrap();
89 std::fs::write(install_dir.join("icons/home.svg"), b"owned").unwrap();
90 std::fs::write(install_dir.join("libs/libfoo.so.1"), b"owned").unwrap();
91 std::fs::write(install_dir.join("Settings.toml"), b"user").unwrap();
92
93 clean_bundled_files(&install_dir).unwrap();
94
95 assert!(!install_dir.join("fonts/NotoSans-Regular.ttf").exists());
96 assert!(install_dir.join("fonts/custom.ttf").exists());
97 assert!(!install_dir.join("icons/home.svg").exists());
98 assert!(!install_dir.join("libs/libfoo.so.1").exists());
99 assert!(install_dir.join("Settings.toml").exists());
100 }
101}