in metalos/metalctl/src/generator.rs [473:531]
fn compare_dir_inner(
base_dir: &Path,
expected_contents: &mut BTreeMap<PathBuf, GeneratedFile>,
) -> Result<()> {
for entry in std::fs::read_dir(base_dir).context("failed to read base dir")? {
let entry = entry.context("failed to read next entry from base dir")?;
let path = entry.path();
if path.is_dir() {
compare_dir_inner(&path, expected_contents)
.context(format!("Failed to process directory {:?}", path))?;
} else {
match expected_contents.remove(&path) {
Some(expected_content) => match expected_content {
GeneratedFile::Contents(expected_content) => {
let content = std::fs::read_to_string(&path)
.context(format!("Can't read file {:?}", path))?;
if expected_content != content {
return Err(anyhow!(
"File contents for {:?} differs from expected:\ncontents: {:?}\nexpected: {:?}\n",
path,
content,
expected_content,
));
}
}
GeneratedFile::SymlinkTo(dst) => {
match std::fs::read_link(&path) {
Ok(link_dst) => {
if dst != link_dst {
bail!(
"Expected {:?} to link to {:?}, but actually pointed to {:?}",
path,
dst,
link_dst
);
}
}
Err(e) => bail!(
"Expected {:?} to link to {:?}, but reading the link failed: {:?}",
path,
dst,
e
),
};
}
},
None => {
return Err(anyhow!(
"Found unexpected file {:?} in directory {:?}",
entry.path(),
base_dir
));
}
}
}
}
Ok(())
}