Skip to main content

xtask/
utils.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3
4use anyhow::Result;
5use xshell::Shell;
6
7pub fn find_files<P: AsRef<Path>>(dir: P, extension: &str) -> Result<Vec<PathBuf>> {
8    let mut result = Vec::new();
9    let dir_path = dir.as_ref();
10    find_files_recursive(dir_path, extension, &mut result)?;
11    Ok(result)
12}
13
14fn find_files_recursive(dir: &Path, extension: &str, result: &mut Vec<PathBuf>) -> Result<()> {
15    for entry_result in fs::read_dir(dir)? {
16        let entry = entry_result?;
17        let path = entry.path();
18
19        if path.is_dir() {
20            find_files_recursive(&path, extension, result)?;
21        } else if path.is_file() && path.extension().is_some_and(|ext| ext == extension) {
22            result.push(path);
23        }
24    }
25    Ok(())
26}
27
28pub fn project_root() -> PathBuf {
29    Path::new(env!("CARGO_MANIFEST_DIR"))
30        .parent()
31        .expect("Failed to find project root")
32        .to_path_buf()
33}
34
35pub fn to_relative_paths<P: AsRef<Path>>(paths: Vec<PathBuf>, base_dir: P) -> Vec<PathBuf> {
36    let base_path = base_dir.as_ref();
37    paths
38        .into_iter()
39        .filter_map(|path| path.strip_prefix(base_path).ok().map(PathBuf::from))
40        .collect()
41}
42
43pub fn verbose_cd<P: AsRef<Path>>(sh: &Shell, dir: P) {
44    sh.change_dir(dir);
45    eprintln!(
46        "\n$ cd {}{}",
47        sh.current_dir().display(),
48        std::path::MAIN_SEPARATOR
49    );
50}