use std::path::{Path, PathBuf};
pub struct Index {
pub root: PathBuf,
pub files: Vec<String>,
}
pub fn project_root(start: &Path) -> PathBuf {
let mut dir = start;
loop {
if dir.join(".git").exists() {
return dir.to_path_buf();
}
match dir.parent() {
Some(p) => dir = p,
None => return start.to_path_buf(),
}
}
}
impl Index {
pub fn build(root: PathBuf, max: usize, ignore: &[String]) -> Index {
let mut files = Vec::new();
let mut stack = vec![root.clone()];
while let Some(dir) = stack.pop() {
if files.len() >= max {
break;
}
let Ok(entries) = std::fs::read_dir(&dir) else { continue };
for entry in entries.flatten() {
let path = entry.path();
let name = entry.file_name().to_string_lossy().to_string();
let is_dir = entry.file_type().map(|t| t.is_dir()).unwrap_or(false);
if is_dir {
if name.starts_with('.') || ignore.iter().any(|i| i == &name) {
continue;
}
stack.push(path);
} else {
if files.len() >= max {
break;
}
if let Ok(rel) = path.strip_prefix(&root) {
files.push(rel.to_string_lossy().replace('\\', "/"));
}
}
}
}
files.sort();
Index { root, files }
}
}