vyre-build-scan 0.1.0

Build-time filesystem scanner for flat trait-impl registries
Documentation
use std::fs;
use std::path::{Path, PathBuf};

#[test]
fn crate_files_stay_under_line_budget() {
    for path in source_files() {
        let contents = fs::read_to_string(&path).unwrap();
        let lines = contents.lines().count();
        assert!(
            lines < 500,
            "{} has {lines} lines; Fix: split it into single-responsibility siblings",
            path.display()
        );
    }
}

#[test]
fn public_reexports_are_never_globs() {
    let public_use = ["pub", "use"].join(" ");
    let glob_suffix = ["::", "*"].concat();
    for path in source_files() {
        let contents = fs::read_to_string(&path).unwrap();
        for (index, line) in contents.lines().enumerate() {
            assert!(
                !(line.trim_start().starts_with(&public_use) && line.contains(&glob_suffix)),
                "{}:{} exports a glob; Fix: name each public re-export explicitly",
                path.display(),
                index + 1
            );
        }
    }
}

#[test]
fn cargo_toml_inherits_workspace_lints() {
    let manifest = Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml");
    let contents = fs::read_to_string(&manifest).unwrap();
    assert!(
        contents.contains("[lints]\nworkspace = true"),
        "{} must inherit workspace lints; Fix: add `[lints] workspace = true`",
        manifest.display()
    );
}

fn source_files() -> Vec<PathBuf> {
    let root = Path::new(env!("CARGO_MANIFEST_DIR"));
    let mut files = Vec::new();
    collect_files(&root.join("src"), &mut files);
    collect_files(&root.join("tests"), &mut files);
    files.push(root.join("Cargo.toml"));
    files.push(root.join("README.md"));
    files
}

fn collect_files(dir: &Path, files: &mut Vec<PathBuf>) {
    for entry in fs::read_dir(dir).unwrap() {
        let path = entry.unwrap().path();
        if path.is_dir() {
            collect_files(&path, files);
        } else {
            files.push(path);
        }
    }
}