jacquardSnapshot

← snapshot

1511 bytes
//! Module-layout checks.
//!
//! `clippy::mod_module_files` is the primary enforcement for the no-`mod.rs`
//! rule, but it is a `restriction` lint with reported cases of failing to fire
//! (rust-clippy#8123), and a layout rule that silently stops being enforced is
//! worse than no rule. This is the independent second mechanism.

use std::fs;
use std::path::{Path, PathBuf};

use anyhow::{Result, bail};

pub(crate) fn run() -> Result<()> {
    let root = crate::workspace_root()?;
    let mut mod_rs = Vec::new();

    for dir in ["crates", "xtask"] {
        let path = root.join(dir);
        if path.is_dir() {
            walk(&path, &mut mod_rs)?;
        }
    }

    if !mod_rs.is_empty() {
        eprintln!("module layout: `mod.rs` is not permitted; use `foo.rs` alongside `foo/`");
        for p in &mod_rs {
            eprintln!("  {}", p.display());
        }
        bail!("layout check failed");
    }

    eprintln!("layout: ok (no mod.rs)");
    Ok(())
}

fn walk(dir: &Path, mod_rs: &mut Vec<PathBuf>) -> Result<()> {
    for entry in fs::read_dir(dir)? {
        let entry = entry?;
        let path = entry.path();
        let file_type = entry.file_type()?;

        if file_type.is_dir() {
            if path.file_name().is_some_and(|n| n == "target") {
                continue;
            }
            walk(&path, mod_rs)?;
            continue;
        }

        if path.file_name().is_some_and(|n| n == "mod.rs") {
            mod_rs.push(path);
        }
    }
    Ok(())
}