1mod registry;
7mod node;
8mod rust;
9mod python;
10mod go;
11mod java;
12mod dotnet;
13mod swift;
14
15pub use registry::*;
16pub use node::NodePlugin;
17pub use rust::RustPlugin;
18pub use python::PythonPlugin;
19pub use go::GoPlugin;
20pub use java::{MavenPlugin, GradlePlugin};
21pub use dotnet::DotNetPlugin;
22pub use swift::SwiftPlugin;
23
24use crate::core::{Artifact, ProjectKind, ProjectMarker};
25use crate::error::Result;
26use std::path::Path;
27
28pub trait Plugin: Send + Sync {
30 fn id(&self) -> &'static str;
32
33 fn name(&self) -> &'static str;
35
36 fn supported_kinds(&self) -> &[ProjectKind];
38
39 fn markers(&self) -> Vec<ProjectMarker>;
41
42 fn detect(&self, path: &Path) -> Option<ProjectKind>;
44
45 fn find_artifacts(&self, project_root: &Path) -> Result<Vec<Artifact>>;
47
48 fn calculate_size(&self, artifact: &Artifact) -> Result<u64> {
50 default_calculate_size(&artifact.path)
51 }
52
53 fn pre_clean(&self, _artifact: &Artifact) -> Result<()> {
55 Ok(())
56 }
57
58 fn post_clean(&self, _artifact: &Artifact) -> Result<()> {
60 Ok(())
61 }
62
63 fn priority(&self) -> u8 {
65 50
66 }
67
68 fn cleanable_dirs(&self) -> &[&'static str] {
70 &[]
71 }
72}
73
74pub fn default_calculate_size(path: &Path) -> Result<u64> {
76 use rayon::prelude::*;
77 use walkdir::WalkDir;
78
79 if !path.exists() {
80 return Ok(0);
81 }
82
83 let entries: Vec<_> = WalkDir::new(path)
85 .into_iter()
86 .filter_map(|e| e.ok())
87 .collect();
88
89 let size: u64 = entries
90 .par_iter()
91 .filter_map(|entry| entry.metadata().ok())
92 .filter(|m| m.is_file())
93 .map(|m| m.len())
94 .sum();
95
96 Ok(size)
97}
98
99pub fn count_files(path: &Path) -> Result<u64> {
101 use walkdir::WalkDir;
102
103 if !path.exists() {
104 return Ok(0);
105 }
106
107 let count = WalkDir::new(path)
108 .into_iter()
109 .filter_map(|e| e.ok())
110 .filter(|e| e.file_type().is_file())
111 .count() as u64;
112
113 Ok(count)
114}
115
116pub fn builtin_plugins() -> Vec<Box<dyn Plugin>> {
118 vec![
119 Box::new(NodePlugin),
120 Box::new(RustPlugin),
121 Box::new(PythonPlugin),
122 Box::new(GoPlugin),
123 Box::new(MavenPlugin),
124 Box::new(GradlePlugin),
125 Box::new(DotNetPlugin),
126 Box::new(SwiftPlugin),
127 ]
128}