1use crate::Result;
4use serde::{Deserialize, Serialize};
5use std::path::Path;
6
7#[async_trait::async_trait]
9pub trait PackageManager: Send + Sync {
10 fn name(&self) -> &str;
12
13 fn ecosystem(&self) -> Ecosystem;
15
16 async fn install_packages(&self, packages: &[PackageSpec]) -> Result<()>;
18
19 async fn remove_packages(&self, packages: &[String]) -> Result<()>;
21
22 async fn list_packages(&self) -> Result<Vec<PackageInfo>>;
24
25 async fn search_packages(&self, query: &str) -> Result<Vec<PackageInfo>>;
27
28 async fn update_packages(&self, packages: &[String]) -> Result<()>;
30
31 async fn is_available(&self) -> Result<bool>;
33
34 fn is_preferred_for_project(&self, project_path: &Path) -> bool;
36
37 fn get_config(&self) -> PackageManagerConfig;
39
40 async fn run_command(&self, args: &[String]) -> Result<i32>;
42}
43
44#[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#[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#[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#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
85pub enum SystemType {
86 Linux(LinuxDistro),
87 MacOS,
88 Windows,
89 Unix,
90}
91
92#[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#[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#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
120pub enum IsolationLevel {
121 Global,
123 User,
125 Project,
127 Sandbox,
129}
130
131impl PackageSpec {
132 pub fn new(name: String) -> Self {
134 Self {
135 name,
136 version: None,
137 source: None,
138 dev_dependency: false,
139 }
140 }
141
142 pub fn with_version(mut self, version: String) -> Self {
144 self.version = Some(version);
145 self
146 }
147
148 pub fn as_dev_dependency(mut self) -> Self {
150 self.dev_dependency = true;
151 self
152 }
153
154 pub fn with_source(mut self, source: String) -> Self {
156 self.source = Some(source);
157 self
158 }
159}