vx_core/
package_manager.rs

1//! Package manager trait and related types
2
3use crate::Result;
4use serde::{Deserialize, Serialize};
5use std::path::Path;
6
7/// Trait for package managers
8#[async_trait::async_trait]
9pub trait PackageManager: Send + Sync {
10    /// Get the name of this package manager
11    fn name(&self) -> &str;
12
13    /// Get the ecosystem this package manager belongs to
14    fn ecosystem(&self) -> Ecosystem;
15
16    /// Install packages
17    async fn install_packages(&self, packages: &[PackageSpec]) -> Result<()>;
18
19    /// Remove packages
20    async fn remove_packages(&self, packages: &[String]) -> Result<()>;
21
22    /// List installed packages
23    async fn list_packages(&self) -> Result<Vec<PackageInfo>>;
24
25    /// Search for packages
26    async fn search_packages(&self, query: &str) -> Result<Vec<PackageInfo>>;
27
28    /// Update packages
29    async fn update_packages(&self, packages: &[String]) -> Result<()>;
30
31    /// Check if this package manager is available on the system
32    async fn is_available(&self) -> Result<bool>;
33
34    /// Check if this package manager is preferred for the given project
35    fn is_preferred_for_project(&self, project_path: &Path) -> bool;
36
37    /// Get package manager configuration
38    fn get_config(&self) -> PackageManagerConfig;
39
40    /// Run a package manager command
41    async fn run_command(&self, args: &[String]) -> Result<i32>;
42}
43
44/// Package specification for installation
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct PackageSpec {
47    pub name: String,
48    pub version: Option<String>,
49    pub source: Option<String>,
50    pub dev_dependency: bool,
51}
52
53/// Information about a package
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct PackageInfo {
56    pub name: String,
57    pub version: String,
58    pub description: Option<String>,
59    pub homepage: Option<String>,
60    pub repository: Option<String>,
61    pub license: Option<String>,
62    pub dependencies: Vec<String>,
63}
64
65/// Ecosystem classification
66#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
67pub enum Ecosystem {
68    JavaScript,
69    Python,
70    Rust,
71    Go,
72    Ruby,
73    PHP,
74    DotNet,
75    Java,
76    System(SystemType),
77    Scientific,
78    VFX,
79    Container,
80    Other(String),
81}
82
83/// System type classification
84#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
85pub enum SystemType {
86    Linux(LinuxDistro),
87    MacOS,
88    Windows,
89    Unix,
90}
91
92/// Linux distribution types
93#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
94pub enum LinuxDistro {
95    Ubuntu,
96    Debian,
97    CentOS,
98    RHEL,
99    Fedora,
100    Arch,
101    Alpine,
102    Other(String),
103}
104
105/// Package manager configuration
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct PackageManagerConfig {
108    pub name: String,
109    pub version: Option<String>,
110    pub executable_path: Option<std::path::PathBuf>,
111    pub config_files: Vec<std::path::PathBuf>,
112    pub cache_directory: Option<std::path::PathBuf>,
113    pub supports_lockfiles: bool,
114    pub supports_workspaces: bool,
115    pub isolation_level: IsolationLevel,
116}
117
118/// Environment isolation level
119#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
120pub enum IsolationLevel {
121    /// No isolation, global installation
122    Global,
123    /// User-level isolation
124    User,
125    /// Project-level isolation
126    Project,
127    /// Complete sandboxing
128    Sandbox,
129}
130
131impl PackageSpec {
132    /// Create a new package spec
133    pub fn new(name: String) -> Self {
134        Self {
135            name,
136            version: None,
137            source: None,
138            dev_dependency: false,
139        }
140    }
141
142    /// Set version constraint
143    pub fn with_version(mut self, version: String) -> Self {
144        self.version = Some(version);
145        self
146    }
147
148    /// Set as dev dependency
149    pub fn as_dev_dependency(mut self) -> Self {
150        self.dev_dependency = true;
151        self
152    }
153
154    /// Set package source
155    pub fn with_source(mut self, source: String) -> Self {
156        self.source = Some(source);
157        self
158    }
159}