1use std::path::Path;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum ProjectType {
5 Node,
6 Ruby,
7 Python,
8 Rust,
9 Go,
10 Generic,
11}
12
13pub fn detect_project_type(base_dir: &Path) -> ProjectType {
14 if base_dir.join("package.json").exists() {
15 ProjectType::Node
16 } else if base_dir.join("Gemfile").exists() {
17 ProjectType::Ruby
18 } else if base_dir.join("requirements.txt").exists()
19 || base_dir.join("pyproject.toml").exists()
20 || base_dir.join("setup.py").exists()
21 {
22 ProjectType::Python
23 } else if base_dir.join("Cargo.toml").exists() {
24 ProjectType::Rust
25 } else if base_dir.join("go.mod").exists() {
26 ProjectType::Go
27 } else {
28 ProjectType::Generic
29 }
30}
31
32pub fn get_default_exclusions(project_type: ProjectType) -> Vec<&'static str> {
33 let mut exclusions = vec![".git", ".svn", ".hg", ".idea", ".vscode", ".DS_Store"];
34
35 match project_type {
36 ProjectType::Node => {
37 exclusions.extend_from_slice(&[
38 "node_modules",
39 "dist",
40 "build",
41 "coverage",
42 ".next",
43 ".nuxt",
44 ]);
45 }
46 ProjectType::Ruby => {
47 exclusions.extend_from_slice(&["vendor", ".bundle", "log", "tmp", "coverage"]);
48 }
49 ProjectType::Python => {
50 exclusions.extend_from_slice(&[
51 "venv",
52 ".venv",
53 "env",
54 ".env",
55 "__pycache__",
56 "*.egg-info",
57 ".pytest_cache",
58 ".mypy_cache",
59 ]);
60 }
61 ProjectType::Rust => {
62 exclusions.extend_from_slice(&["target"]);
63 }
64 ProjectType::Go => {
65 exclusions.extend_from_slice(&["vendor"]);
66 }
67 ProjectType::Generic => {
68 exclusions.extend_from_slice(&[
70 "node_modules", "vendor",
72 "dist",
73 "build",
74 "target",
75 ]);
76 }
77 }
78
79 exclusions
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use std::fs;
86 use tempfile::tempdir;
87
88 #[test]
89 fn test_detect_node_project() {
90 let dir = tempdir().unwrap();
91 fs::write(dir.path().join("package.json"), "{}").unwrap();
92 assert_eq!(detect_project_type(dir.path()), ProjectType::Node);
93 }
94
95 #[test]
96 fn test_detect_rust_project() {
97 let dir = tempdir().unwrap();
98 fs::write(dir.path().join("Cargo.toml"), "").unwrap();
99 assert_eq!(detect_project_type(dir.path()), ProjectType::Rust);
100 }
101
102 #[test]
103 fn test_detect_generic_project() {
104 let dir = tempdir().unwrap();
105 assert_eq!(detect_project_type(dir.path()), ProjectType::Generic);
106 }
107
108 #[test]
109 fn test_default_exclusions_node() {
110 let exclusions = get_default_exclusions(ProjectType::Node);
111 assert!(exclusions.contains(&"node_modules"));
112 assert!(exclusions.contains(&".git"));
113 }
114}