use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::registry::{Registry, RegistryEntryLike};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct PackageRegistryEntry {
pub name: String,
pub description: Option<String>,
pub enabled: bool,
pub command: String,
pub args: Vec<String>,
pub output_file: String,
pub platforms: Option<Vec<String>>,
}
use crate::impl_registry_entry_like;
impl_registry_entry_like!(PackageRegistryEntry);
pub(crate) type PackageRegistry = Registry<PackageRegistryEntry>;
impl Default for PackageRegistry {
fn default() -> Self {
let mut entries = HashMap::new();
entries.insert(
"brew".to_string(),
PackageRegistryEntry {
name: "Homebrew".to_string(),
command: "brew".to_string(),
args: vec!["leaves".to_string()],
output_file: "brew.txt".to_string(),
enabled: true,
description: Some("Homebrew installed packages".to_string()),
platforms: Some(vec!["macos".to_string(), "linux".to_string()]),
},
);
entries.insert(
"brew_cask".to_string(),
PackageRegistryEntry {
name: "Homebrew Casks".to_string(),
command: "brew".to_string(),
args: vec!["list".to_string(), "--cask".to_string()],
output_file: "brew-cask.txt".to_string(),
enabled: true,
description: Some("Homebrew installed casks (applications)".to_string()),
platforms: Some(vec!["macos".to_string()]),
},
);
entries.insert(
"npm".to_string(),
PackageRegistryEntry {
name: "npm".to_string(),
command: "npm".to_string(),
args: vec!["ls".to_string(), "-g".to_string()],
output_file: "npm.txt".to_string(),
enabled: true,
description: Some("npm globally installed packages".to_string()),
platforms: None,
},
);
entries.insert(
"pnpm".to_string(),
PackageRegistryEntry {
name: "pnpm".to_string(),
command: "pnpm".to_string(),
args: vec!["ls".to_string(), "-g".to_string()],
output_file: "pnpm.txt".to_string(),
enabled: true,
description: Some("pnpm globally installed packages".to_string()),
platforms: None,
},
);
entries.insert(
"bun".to_string(),
PackageRegistryEntry {
name: "Bun".to_string(),
command: "bun".to_string(),
args: vec!["pm".to_string(), "ls".to_string(), "-g".to_string()],
output_file: "bun.txt".to_string(),
enabled: true,
description: Some("Bun globally installed packages".to_string()),
platforms: None,
},
);
entries.insert(
"deno".to_string(),
PackageRegistryEntry {
name: "Deno".to_string(),
command: "deno".to_string(),
args: vec![
"install".to_string(),
"--".to_string(),
"--list".to_string(),
],
output_file: "deno.txt".to_string(),
enabled: true,
description: Some("Deno globally installed packages".to_string()),
platforms: None,
},
);
entries.insert(
"cargo".to_string(),
PackageRegistryEntry {
name: "Cargo".to_string(),
command: "cargo".to_string(),
args: vec!["install".to_string(), "--list".to_string()],
output_file: "cargo.txt".to_string(),
enabled: true,
description: Some("Cargo installed packages".to_string()),
platforms: None,
},
);
entries.insert(
"uv".to_string(),
PackageRegistryEntry {
name: "uv".to_string(),
command: "uv".to_string(),
args: vec!["tool".to_string(), "list".to_string()],
output_file: "uv.txt".to_string(),
enabled: true,
description: Some("uv installed tools".to_string()),
platforms: None,
},
);
entries.insert(
"pip".to_string(),
PackageRegistryEntry {
name: "pip".to_string(),
command: "pip".to_string(),
args: vec!["list".to_string(), "--format=freeze".to_string()],
output_file: "pip.txt".to_string(),
enabled: false,
description: Some("pip globally installed packages".to_string()),
platforms: None,
},
);
Self {
version: "1.0.0".to_string(),
entries,
}
}
}
impl PackageRegistry {
pub fn get_platform_compatible_entries<'a>(
&'a self,
current_platform: &'a str,
) -> impl Iterator<Item = (&'a String, &'a PackageRegistryEntry)> + 'a {
self.entries.iter().filter(move |(_, entry)| {
entry.enabled
&& match &entry.platforms {
Some(platforms) => platforms.contains(¤t_platform.to_string()),
None => true,
}
})
}
pub fn get_current_platform() -> String {
#[cfg(target_os = "macos")]
return "macos".into();
#[cfg(target_os = "linux")]
return "linux".into();
#[cfg(target_os = "windows")]
return "windows".into();
#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
return "unknown".into();
}
}