cs/config/
exclusions.rs

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            // Add common exclusions for generic projects if needed
69            exclusions.extend_from_slice(&[
70                "node_modules", // Common enough to include by default?
71                "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}