use std::collections::BTreeMap;
use camino::Utf8Path;
use super::{BLOCK_DESTINATIONS, CrateShape, TargetEvidence};
use crate::landing::manifest::Manifest;
impl TargetEvidence {
pub fn gather(target: &Utf8Path, recorded: Option<&Manifest>) -> std::io::Result<Self> {
gather(target, recorded)
}
}
pub fn gather(target: &Utf8Path, recorded: Option<&Manifest>) -> std::io::Result<TargetEvidence> {
let mut documents = BTreeMap::new();
for destination in BLOCK_DESTINATIONS {
if let Some(bytes) = read_optional(&target.join(destination))? {
documents.insert(destination.to_owned(), bytes);
}
}
let (flake_nix_present, flake_lock_present) = flake_presence(target)?;
Ok(TargetEvidence {
documents,
crate_shape: crate_shape(target),
flake_nix_present,
flake_lock_present,
flake_recorded: flake_recorded(recorded),
})
}
#[must_use]
pub fn flake_recorded(recorded: Option<&Manifest>) -> bool {
recorded.is_some_and(|record| record.file("flake.nix").is_some())
}
#[must_use]
pub fn crate_shape(target: &Utf8Path) -> CrateShape {
CrateShape {
cargo_toml: std::fs::read_to_string(target.join("Cargo.toml")).ok(),
cargo_lock: target.join("Cargo.lock").is_file(),
main_rs: target.join("src/main.rs").is_file(),
}
}
pub fn flake_presence(target: &Utf8Path) -> std::io::Result<(bool, bool)> {
let present = |name: &str| match std::fs::symlink_metadata(target.join(name).as_std_path()) {
Ok(_) => Ok(true),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false),
Err(e) => Err(e),
};
Ok((present("flake.nix")?, present("flake.lock")?))
}
fn read_optional(path: &Utf8Path) -> std::io::Result<Option<Vec<u8>>> {
match std::fs::read(path) {
Ok(bytes) => Ok(Some(bytes)),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(e) => Err(e),
}
}