Skip to main content

lean_agent_core/
discover.rs

1//! Lean file discovery.
2
3use crate::{Error, LeanFile, Result};
4use camino::{Utf8Path, Utf8PathBuf};
5use ignore::WalkBuilder;
6
7/// Discover Lean source files from a file or directory.
8pub fn discover_lean_files(path: &Utf8Path, recursive: bool) -> Result<Vec<LeanFile>> {
9    if !path.exists() {
10        return Err(Error::PathDoesNotExist {
11            path: path.to_path_buf(),
12        });
13    }
14
15    if path.is_file() {
16        return Ok(vec![LeanFile::new(path.to_path_buf())?]);
17    }
18
19    let mut files = Vec::new();
20    let mut builder = WalkBuilder::new(path);
21    builder
22        .hidden(false)
23        .parents(true)
24        .git_ignore(true)
25        .git_exclude(true);
26
27    if !recursive {
28        builder.max_depth(Some(1));
29    }
30
31    for entry in builder.build() {
32        let entry = entry.map_err(|err| Error::Io(std::io::Error::other(err)))?;
33        if !entry
34            .file_type()
35            .is_some_and(|file_type| file_type.is_file())
36        {
37            continue;
38        }
39        let std_path = entry.into_path();
40        let utf8 = Utf8PathBuf::from_path_buf(std_path.clone())
41            .map_err(|_| Error::NonUtf8Path { path: std_path })?;
42        if utf8.extension() == Some("lean") {
43            files.push(LeanFile::new(utf8)?);
44        }
45    }
46
47    files.sort();
48    Ok(files)
49}