use std::fs;
use std::path::Path;
fn source_files() -> Vec<(String, String)> {
let mut out = Vec::new();
collect(Path::new("src"), &mut out);
assert!(!out.is_empty(), "no source files found under src/");
out
}
fn collect(dir: &Path, out: &mut Vec<(String, String)>) {
for entry in fs::read_dir(dir).expect("read src dir") {
let path = entry.expect("dir entry").path();
if path.is_dir() {
collect(&path, out);
} else if path.extension().is_some_and(|e| e == "rs") {
let body = fs::read_to_string(&path).expect("read source file");
out.push((rel(&path), body));
}
}
}
fn rel(path: &Path) -> String {
path.to_string_lossy().replace('\\', "/")
}
fn code_lines(body: &str) -> impl Iterator<Item = (usize, &str)> {
body.lines()
.enumerate()
.map(|(i, line)| (i + 1, line.trim()))
.filter(|(_, line)| !line.starts_with("//"))
}
fn reads_env(line: &str) -> bool {
let cleaned = line
.replace("set_var", "")
.replace("remove_var", "")
.replace("env_remove", "")
.replace("env_set", "");
cleaned.contains("var(")
|| cleaned.contains("var_os(")
|| cleaned.contains("vars(")
|| cleaned.contains("vars_os(")
}
#[test]
fn murk_key_is_read_only_in_the_env_module() {
const ALLOWED: &str = "src/env.rs";
let offenders: Vec<String> = source_files()
.iter()
.filter(|(path, _)| path != ALLOWED)
.flat_map(|(path, body)| {
code_lines(body)
.filter(|(_, line)| {
let uses_const = line.contains("ENV_MURK_KEY");
let reads_literal = reads_env(line)
&& (line.contains("\"MURK_KEY\"") || line.contains("\"MURK_KEY_FILE\""));
uses_const || reads_literal
})
.map(move |(n, line)| format!(" {path}:{n}: {line}"))
})
.collect();
assert!(
offenders.is_empty(),
"MURK_KEY / MURK_KEY_FILE may only be read in {ALLOWED} (the single auth \
read path). Route new reads through env::resolve_key / env::key_from_env_only.\n{}",
offenders.join("\n"),
);
}
#[test]
fn library_modules_do_not_print_to_stdout() {
const UI_LAYER: &str = "src/main.rs";
let offenders: Vec<String> = source_files()
.iter()
.filter(|(path, _)| path != UI_LAYER)
.flat_map(|(path, body)| {
code_lines(body)
.filter(|(_, line)| {
(line.contains("println!") || line.contains("print!"))
&& !line.contains("eprintln!")
&& !line.contains("eprint!")
})
.map(move |(n, line)| format!(" {path}:{n}: {line}"))
})
.collect();
assert!(
offenders.is_empty(),
"library modules must not write to stdout — stdout belongs to the binary. \
Return the value and let main.rs print it, or use eprintln! for a warning.\n{}",
offenders.join("\n"),
);
}