tidy/
filenames.rs

1//! Tidy check to ensure that there are no filenames containing forbidden characters
2//! checked into the source tree by accident:
3//! - Non-UTF8 filenames
4//! - Control characters such as CR or TAB
5//! - Filenames containing ":" as they are not supported on Windows
6//!
7//! Only files added to git are checked, as it may be acceptable to have temporary
8//! invalid filenames in the local directory during development.
9
10use std::path::Path;
11use std::process::Command;
12
13use crate::diagnostics::DiagCtx;
14
15pub fn check(root_path: &Path, diag_ctx: DiagCtx) {
16    let mut check = diag_ctx.start_check("filenames");
17    let stat_output = Command::new("git")
18        .arg("-C")
19        .arg(root_path)
20        .args(["ls-files", "-z"])
21        .output()
22        .unwrap()
23        .stdout;
24    for filename in stat_output.split(|&b| b == 0) {
25        match str::from_utf8(filename) {
26            Err(_) => check.error(format!(
27                r#"non-UTF8 file names are not supported: "{}""#,
28                String::from_utf8_lossy(filename),
29            )),
30            Ok(name) if name.chars().any(|c| c.is_control()) => check.error(format!(
31                r#"control characters are not supported in file names: "{}""#,
32                String::from_utf8_lossy(filename),
33            )),
34            Ok(name) if name.contains(':') => check.error(format!(
35                r#"":" is not supported in file names because of Windows compatibility: "{name}""#,
36            )),
37            _ => (),
38        }
39    }
40}