Skip to main content

provenant/
golden_maintenance.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3use std::process::Command;
4
5use anyhow::{Context, Result};
6
7pub fn find_files_with_extension(dir: &Path, extension: &str) -> Result<Vec<PathBuf>> {
8    let mut paths = Vec::new();
9    if !dir.is_dir() {
10        return Ok(paths);
11    }
12
13    fn recurse(dir: &Path, extension: &str, out: &mut Vec<PathBuf>) -> Result<()> {
14        for entry in fs::read_dir(dir)? {
15            let entry = entry?;
16            let path = entry.path();
17            if path.is_dir() {
18                recurse(&path, extension, out)?;
19            } else if path
20                .extension()
21                .and_then(|ext| ext.to_str())
22                .is_some_and(|ext| ext == extension)
23            {
24                out.push(path);
25            }
26        }
27        Ok(())
28    }
29
30    recurse(dir, extension, &mut paths)?;
31    paths.sort();
32    Ok(paths)
33}
34
35pub fn run_prettier(paths: &[PathBuf]) -> Result<()> {
36    if paths.is_empty() {
37        return Ok(());
38    }
39
40    let ignore_path = std::env::temp_dir().join("provenant-empty-prettierignore");
41    if !ignore_path.exists() {
42        fs::write(&ignore_path, "").context("failed to create empty prettier ignore file")?;
43    }
44
45    const CHUNK_SIZE: usize = 100;
46    for chunk in paths.chunks(CHUNK_SIZE) {
47        let mut cmd = Command::new("npm");
48        cmd.args([
49            "exec",
50            "--",
51            "prettier",
52            "--write",
53            "--ignore-path",
54            ignore_path
55                .to_str()
56                .context("temporary prettier ignore path is not valid UTF-8")?,
57        ]);
58        for path in chunk {
59            cmd.arg(path);
60        }
61
62        let output = cmd
63            .output()
64            .context("failed to run `npm exec -- prettier --write`")?;
65
66        if !output.status.success() {
67            let stderr = String::from_utf8_lossy(&output.stderr);
68            anyhow::bail!(
69                "prettier formatting failed (status: {}): {}",
70                output.status,
71                stderr.trim()
72            );
73        }
74    }
75
76    Ok(())
77}