use std::path::Path;
use crate::kind::ProjectKind;
use crate::signals::SIGNAL_FILES;
pub fn detect_in_dir(dir: &Path) -> (ProjectKind, Vec<String>) {
let mut signals = Vec::new();
if !dir.is_dir() {
return (ProjectKind::Unknown, signals);
}
for sf in SIGNAL_FILES {
if dir.join(sf.name).exists() {
signals.push(sf.name.to_string());
}
}
let has = |name: &str| signals.iter().any(|s| s == name);
let kind = if has("Cargo.toml") {
ProjectKind::Rust
} else if has("bun.lock") || has("bun.lockb") || has("bunfig.toml") {
ProjectKind::Bun
} else if has("deno.json") || has("deno.jsonc") || has("deno.lock") {
ProjectKind::Deno
} else if has("package.json") {
ProjectKind::Node
} else if has("pyproject.toml")
|| has("requirements.txt")
|| has("setup.py")
|| has("setup.cfg")
{
ProjectKind::Python
} else if has(".luarc.json") || has_any_extension(dir, "rockspec") {
ProjectKind::Lua
} else if has("CMakeLists.txt") {
if has_any_extension(dir, "cpp") || has_any_extension(dir, "cc") || has_any_extension(dir, "cxx") {
ProjectKind::Cpp
} else if has_any_extension(dir, "c") {
ProjectKind::C
} else {
ProjectKind::Unknown
}
} else {
ProjectKind::Unknown
};
(kind, signals)
}
fn has_any_extension(dir: &Path, ext: &str) -> bool {
let Ok(read) = std::fs::read_dir(dir) else {
return false;
};
for entry in read.flatten() {
if entry.path().extension().map(|e| e == ext).unwrap_or(false) {
return true;
}
}
false
}