use crate::checkers::{
base::CheckError,
package::{
Installer, Package,
command::{run_command_stream, run_command_stream_capture_stdout},
},
};
pub(crate) struct UV;
impl Installer for UV {
fn install(package: &Package) -> Result<(), CheckError> {
let mut options = vec!["tool", "install"];
let package_specifier = if let Some(version) = &package.version {
format!("{package}=={version}", package = &package.name)
} else {
package.name.to_owned()
};
options.push(&package_specifier);
if package.version.is_some() {
options.push("-U");
}
run_command_stream("uv", &options)
}
fn uninstall(package: &Package) -> Result<(), CheckError> {
run_command_stream(
"uv",
vec!["tool", "uninstall", package.name.as_str()].as_ref(),
)
}
fn is_upgradable(package: &Package) -> Result<bool, CheckError> {
Ok(package.version.is_none())
}
fn is_installed(package: &Package) -> Result<bool, CheckError> {
let stdout = run_command_stream_capture_stdout("uv", vec!["tool", "list"].as_ref())?;
let packages: Vec<&str> = stdout
.lines()
.filter(|line| line.starts_with(format!("{package} ", package = package.name).as_str()))
.collect();
Ok(if packages.len() != 1 {
false
} else if let Some(version) = package.version.as_ref() {
packages
.first()
.expect("1 item present")
.split_once(" ")
.expect("space is present")
.1
== version
} else {
true
})
}
}