//! **Every crate here names this repository's real home** (A28 L17).
//!
//! The old forge is gone. A `repository =` that still points at it, or at
//! another of our own old addresses, sends a reader of crates.io or a
//! `cargo metadata` consumer to a dead or wrong place. This test walks every
//! `Cargo.toml` in the repository (detached workspaces and fixtures too) and
//! every `THIRD_PARTY_LICENSES*.md`, and fails on the first such line.
use std::path::{Path, PathBuf};
/// Where this repository lives.
const HOME: &str = "https://git.gunnar.rs/mikronova/openzl-sys-rs";
/// The old forge's host, spelled so a search for it finds only real uses.
const OLD_FORGE: &str = concat!("code", "berg", ".org");
/// Our own hosts and organisations: a `repository =` on one of these must be [`HOME`].
const OURS: &[&str] = &[
"https://gunnar.rs/",
"https://git.gunnar.rs/",
"https://github.com/vetra-automation/",
"https://github.com/nordisk/",
"https://github.com/mikronova/",
];
/// The repository root: the first ancestor holding `.git`, else the top-most
/// ancestor that still holds a `Cargo.toml`.
fn repo_root() -> PathBuf {
let start = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut top = start.clone();
for dir in start.ancestors() {
if dir.join(".git").exists() {
return dir.to_path_buf();
}
if dir.join("Cargo.toml").is_file() {
top = dir.to_path_buf();
}
}
top
}
fn walk(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else { return };
for entry in entries.flatten() {
let path = entry.path();
let name = entry.file_name();
let name = name.to_string_lossy();
let Ok(meta) = std::fs::symlink_metadata(&path) else { continue };
if meta.is_dir() {
if name == "target" || name == "node_modules" || name.starts_with('.') {
continue;
}
walk(&path, out);
} else if meta.is_file() && (name == "Cargo.toml" || (name.starts_with("THIRD_PARTY_LICENSES") && name.ends_with(".md"))) {
out.push(path);
}
}
}
/// The quoted value of a `repository = "…"` line, if this is one.
fn repository_value(line: &str) -> Option<&str> {
let rest = line.trim_start().strip_prefix("repository")?;
let rest = rest.trim_start().strip_prefix('=')?.trim_start().strip_prefix('"')?;
rest.split('"').next()
}
fn offences(path: &Path, text: &str) -> Vec<String> {
let mut found = Vec::new();
let manifest = path.file_name().is_some_and(|n| n == "Cargo.toml");
for (i, line) in text.lines().enumerate() {
let at = format!("{}:{}", path.display(), i + 1);
if line.contains(OLD_FORGE) {
found.push(format!("{at}: names the old forge"));
continue;
}
if manifest {
if let Some(v) = repository_value(line) {
if OURS.iter().any(|o| v.starts_with(o)) && v != HOME {
found.push(format!("{at}: repository is {v}, not {HOME}"));
}
}
}
}
found
}
#[test]
fn every_manifest_names_this_repositorys_real_home() {
let root = repo_root();
let mut files = Vec::new();
walk(&root, &mut files);
files.sort();
assert!(files.iter().any(|p| p.ends_with("Cargo.toml")), "no Cargo.toml found under {}", root.display());
let mut all = Vec::new();
for f in &files {
let text = std::fs::read_to_string(f).unwrap_or_default();
all.extend(offences(f, &text));
}
assert!(all.is_empty(), "{} line(s) name an old home:\n{}", all.len(), all.join("\n"));
}
#[test]
fn the_guard_reads_a_repository_line_and_spots_the_old_forge() {
assert_eq!(repository_value(r#"repository = "https://x/y""#), Some("https://x/y"));
assert_eq!(repository_value(r#"repository = "a""#), Some("a"));
assert_eq!(repository_value("repository.workspace = true"), None);
let p = Path::new("Cargo.toml");
let old = format!("repository = \"https://{OLD_FORGE}/nordisk/x\"");
assert_eq!(offences(p, &old).len(), 1);
assert_eq!(offences(p, "repository = \"https://github.com/vetra-automation/elsewhere\"").len(), 1);
assert!(offences(p, &format!("repository = \"{HOME}\"")).is_empty());
assert!(offences(p, "repository = \"https://github.com/apache/iceberg-rust\"").is_empty());
}
// ── N7-left (A28 L17): our own repositories are never addressed on the old forge ──
/// Our organisations on the old forge, in each spelling a link, a clone URL or a provenance
/// check uses. A forge KIND of that name (a mirror source a user picks) is not a home.
const OLD_HOMES: &[&str] = &[
concat!("code", "berg", ".org/nordisk"),
concat!("code", "berg", ".org:nordisk"),
concat!("code", "berg", ".org/mikronova"),
concat!("code", "berg", ".org:mikronova"),
];
/// The text files that can name a home: code, protos, manifests, configs and docs. The
/// dated notes under `.nornir/` (and every other dot directory) are history: `walk_text`
/// does not enter them.
fn is_text(name: &str) -> bool {
let ext = name.rsplit('.').next().unwrap_or("");
name != "Cargo.lock" && ["rs", "proto", "toml", "yaml", "yml", "md", "json", "go", "py", "sh", "ts", "html", "txt"].contains(&ext)
}
fn walk_text(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else { return };
for entry in entries.flatten() {
let path = entry.path();
let name = entry.file_name();
let name = name.to_string_lossy();
let Ok(meta) = std::fs::symlink_metadata(&path) else { continue };
if meta.is_dir() {
if name == "target" || name == "node_modules" || name.starts_with('.') {
continue;
}
walk_text(&path, out);
} else if meta.is_file() && is_text(&name) {
out.push(path);
}
}
}
fn old_home_lines(path: &Path, text: &str) -> Vec<String> {
text.lines()
.enumerate()
.filter(|(_, l)| OLD_HOMES.iter().any(|o| l.contains(o)))
.map(|(i, _)| format!("{}:{}: addresses one of our repositories on the old forge", path.display(), i + 1))
.collect()
}
#[test]
fn no_file_addresses_our_repositories_on_the_old_forge() {
let root = repo_root();
let mut files = Vec::new();
walk_text(&root, &mut files);
files.sort();
let mut all = Vec::new();
for f in &files {
let text = std::fs::read_to_string(f).unwrap_or_default();
all.extend(old_home_lines(f, &text));
}
assert!(all.is_empty(), "{} line(s) address an old home:\n{}", all.len(), all.join("\n"));
}
#[test]
fn the_guard_tells_an_old_home_from_a_forge_kind() {
let p = Path::new("x.rs");
assert_eq!(old_home_lines(p, &format!("a link to https://{}/x", OLD_HOMES[0])).len(), 1);
assert_eq!(old_home_lines(p, &format!("git@{}/x.git", OLD_HOMES[3])).len(), 1);
assert!(old_home_lines(p, "a mirror from GitHub, Codeberg or GitLab").is_empty());
assert!(is_text("lib.rs") && is_text("README.md") && !is_text("Cargo.lock") && !is_text("manual.pdf"));
}