Skip to content

Commit bbdc3b7

Browse files
euxaristiaqwencoder
andcommitted
fix(update): check version exists before confirming uninstall
Previously, `spacetime version uninstall <ver>` would show a y/N confirmation prompt even when the version wasn't installed, then fail with a cryptic "No such file or directory (os error 2)" after the user confirmed. Now the command checks if the version directory exists before prompting, and returns a clear error: "v{ver} is not installed". Added 4 unit tests covering: - Nonexistent version errors before prompt - Current version cannot be uninstalled - "current" keyword cannot be uninstalled - Successful uninstall removes the version directory Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
1 parent 7475969 commit bbdc3b7

1 file changed

Lines changed: 89 additions & 2 deletions

File tree

crates/update/src/cli/uninstall.rs

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,97 @@ impl Uninstall {
2828
Ok(None) => {}
2929
Err(e) => tracing::warn!("{e:#}"),
3030
}
31+
let dir = paths.cli_bin_dir.version_dir(&version);
32+
if !dir.0.exists() {
33+
anyhow::bail!("v{version} is not installed");
34+
}
3135
if yes.confirm(format!("Uninstall v{version}?"))? {
32-
let dir = paths.cli_bin_dir.version_dir(&version);
33-
std::fs::remove_dir_all(dir)?;
36+
std::fs::remove_dir_all(&dir)?;
3437
}
3538
Ok(())
3639
}
3740
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use super::*;
45+
use spacetimedb_paths::FromPathUnchecked;
46+
use spacetimedb_paths::RootDir;
47+
48+
fn make_temp_paths() -> (tempfile::TempDir, SpacetimePaths) {
49+
let tmp = tempfile::tempdir().unwrap();
50+
let base = tmp.path().join("spacetime");
51+
std::fs::create_dir_all(&base).unwrap();
52+
let root = RootDir::from_path_unchecked(base);
53+
let paths = SpacetimePaths::from_root_dir(&root);
54+
(tmp, paths)
55+
}
56+
57+
#[test]
58+
fn test_uninstall_nonexistent_version_errors_before_prompt() {
59+
let (_tmp, paths) = make_temp_paths();
60+
let uninstall = Uninstall {
61+
version: "9.9.9".to_owned(),
62+
yes: ForceYes { yes: true },
63+
};
64+
let result = uninstall.exec(&paths);
65+
assert!(result.is_err());
66+
let err = result.unwrap_err();
67+
assert!(
68+
err.to_string().contains("9.9.9"),
69+
"error should mention the version number"
70+
);
71+
assert!(
72+
err.to_string().contains("not installed"),
73+
"error should say 'not installed'"
74+
);
75+
}
76+
77+
#[test]
78+
fn test_uninstall_current_version_errors() {
79+
let (_tmp, paths) = make_temp_paths();
80+
// Create the "current" symlink target so it exists on disk
81+
let current_dir = paths.cli_bin_dir.version_dir("2.0.0");
82+
std::fs::create_dir_all(&current_dir.0).unwrap();
83+
paths.cli_bin_dir.set_current_version("2.0.0").unwrap();
84+
85+
let uninstall = Uninstall {
86+
version: "2.0.0".to_owned(),
87+
yes: ForceYes { yes: true },
88+
};
89+
let result = uninstall.exec(&paths);
90+
assert!(result.is_err());
91+
assert!(result.unwrap_err().to_string().contains("currently used version"),);
92+
}
93+
94+
#[test]
95+
fn test_uninstall_current_keyword_errors() {
96+
let (_tmp, paths) = make_temp_paths();
97+
let uninstall = Uninstall {
98+
version: "current".to_owned(),
99+
yes: ForceYes { yes: true },
100+
};
101+
let result = uninstall.exec(&paths);
102+
assert!(result.is_err());
103+
assert!(result.unwrap_err().to_string().contains("cannot remove `current`"),);
104+
}
105+
106+
#[test]
107+
fn test_uninstall_existing_version_with_yes() {
108+
let (_tmp, paths) = make_temp_paths();
109+
let version_dir = paths.cli_bin_dir.version_dir("1.0.0");
110+
std::fs::create_dir_all(&version_dir.0).unwrap();
111+
// Create a dummy file so we can verify the directory existed
112+
std::fs::write(version_dir.0.join("spacetime"), "dummy").unwrap();
113+
114+
assert!(version_dir.0.exists(), "version dir should exist before");
115+
116+
let uninstall = Uninstall {
117+
version: "1.0.0".to_owned(),
118+
yes: ForceYes { yes: true },
119+
};
120+
uninstall.exec(&paths).unwrap();
121+
122+
assert!(!version_dir.0.exists(), "version dir should be removed after uninstall");
123+
}
124+
}

0 commit comments

Comments
 (0)