use crate::error::Result;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct InstalledBrewCask {
pub token: String,
pub version: Option<String>,
pub path: PathBuf,
}
pub fn caskroom_path(prefix: &Path) -> PathBuf {
prefix.join("Caskroom")
}
pub fn scan_caskroom(prefix: &Path) -> Result<Vec<InstalledBrewCask>> {
let caskroom = caskroom_path(prefix);
if !caskroom.exists() {
return Ok(Vec::new());
}
let mut casks = Vec::new();
let entries = std::fs::read_dir(&caskroom)?;
for entry in entries {
let entry = entry?;
if entry.file_type()?.is_symlink() {
continue;
}
if !entry.path().is_dir() {
continue;
}
let token = match entry.file_name().into_string() {
Ok(n) => n,
Err(_) => continue,
};
if token.starts_with('.') {
continue;
}
let version = read_cask_version(&entry.path());
casks.push(InstalledBrewCask {
token,
version,
path: entry.path(),
});
}
casks.sort_by(|a, b| a.token.cmp(&b.token));
Ok(casks)
}
fn read_cask_version(cask_dir: &Path) -> Option<String> {
let entries = std::fs::read_dir(cask_dir).ok()?;
let mut versions: Vec<String> = entries
.filter_map(|e| e.ok())
.filter(|e| e.path().is_dir())
.filter_map(|e| e.file_name().into_string().ok())
.filter(|name| !name.starts_with('.') && !name.ends_with(".upgrading"))
.collect();
versions.sort();
versions.pop()
}
pub fn register_cask_in_caskroom(prefix: &Path, token: &str, version: &str) -> std::io::Result<()> {
let token_dir = caskroom_path(prefix).join(token);
if token_dir.exists() {
std::fs::remove_dir_all(&token_dir)?;
}
std::fs::create_dir_all(token_dir.join(version))
}
pub fn unregister_cask_from_caskroom(
prefix: &Path,
token: &str,
_version: &str,
) -> std::io::Result<()> {
let token_dir = caskroom_path(prefix).join(token);
if token_dir.exists() {
std::fs::remove_dir_all(&token_dir)?;
}
Ok(())
}
pub fn count_caskroom_casks(prefix: &Path) -> usize {
let caskroom = caskroom_path(prefix);
if !caskroom.exists() {
return 0;
}
std::fs::read_dir(&caskroom)
.ok()
.map(|entries| {
entries
.filter_map(|e| e.ok())
.filter(|e| {
e.path().is_dir()
&& !e.file_type().map(|t| t.is_symlink()).unwrap_or(false)
&& e.file_name()
.to_str()
.map(|n| !n.starts_with('.'))
.unwrap_or(false)
})
.count()
})
.unwrap_or(0)
}