winbrew_engines\portable/
remove.rs1use anyhow::Result;
2use std::fs;
3use std::io::ErrorKind;
4
5use crate::models::install::installed::InstalledPackage;
6
7pub(crate) fn remove(package: &InstalledPackage) -> Result<()> {
8 match fs::remove_dir_all(&package.install_dir) {
9 Ok(()) => Ok(()),
10 Err(err) if err.kind() == ErrorKind::NotFound => Ok(()),
11 Err(err) => Err(err.into()),
12 }
13}
14
15#[cfg(test)]
16mod tests {
17 use super::remove;
18 use crate::models::install::engine::EngineKind;
19 use crate::models::install::installed::{InstalledPackage, PackageStatus};
20 use crate::models::install::installer::InstallerType;
21 use std::fs;
22 use tempfile::tempdir;
23
24 fn package(name: &str, install_dir: &std::path::Path) -> InstalledPackage {
25 InstalledPackage {
26 name: name.to_string(),
27 version: "1.0.0".to_string(),
28 kind: InstallerType::Portable,
29 deployment_kind: InstallerType::Portable.deployment_kind(),
30 engine_kind: EngineKind::Portable,
31 engine_metadata: None,
32 install_dir: install_dir.to_string_lossy().into_owned(),
33 dependencies: Vec::new(),
34 status: PackageStatus::Ok,
35 installed_at: "2026-04-05T00:00:00Z".to_string(),
36 }
37 }
38
39 #[test]
40 fn remove_deletes_existing_directory() {
41 let temp_root = tempdir().expect("temp root");
42 let install_dir = temp_root.path().join("packages").join("Contoso.Portable");
43
44 fs::create_dir_all(&install_dir).expect("create install dir");
45 fs::write(install_dir.join("tool.exe"), b"binary").expect("write file");
46
47 remove(&package("Contoso.Portable", &install_dir)).expect("remove directory");
48
49 assert!(!install_dir.exists());
50 }
51
52 #[test]
53 fn remove_allows_missing_directory() {
54 let temp_root = tempdir().expect("temp root");
55 let install_dir = temp_root.path().join("packages").join("Contoso.Missing");
56
57 remove(&package("Contoso.Missing", &install_dir))
58 .expect("missing directory should be ignored");
59 }
60}