migrate: an unreadable applied flake.nix fails that repo's migration instead of being overwritten
Only a missing file counts as 'marker absent'; any other read error (EACCES, EIO, non-UTF-8) used to read as empty, so the agent's flake.nix was replaced and committed.
This commit is contained in:
parent
99785989b9
commit
ba1515aa5e
1 changed files with 34 additions and 5 deletions
|
|
@ -168,19 +168,29 @@ async fn enumerate_agents() -> Result<Vec<hive_types::Ident>> {
|
|||
}
|
||||
|
||||
async fn migrate_applied_repo(name: &str) -> Result<()> {
|
||||
let dir = crate::paths::applied_dir(name);
|
||||
migrate_applied_dir(name, &crate::paths::applied_dir(name)).await
|
||||
}
|
||||
|
||||
/// Rewrites the applied repo at `dir` to the module-only flake. A missing
|
||||
/// `flake.nix` counts as "marker absent"; any other read error fails the
|
||||
/// migration so the agent's file is never overwritten unread.
|
||||
async fn migrate_applied_dir(name: &str, dir: &Path) -> Result<()> {
|
||||
if !dir.join(".git").exists() {
|
||||
return Ok(());
|
||||
}
|
||||
let flake_path = dir.join("flake.nix");
|
||||
let cur = std::fs::read_to_string(&flake_path).unwrap_or_default();
|
||||
let cur = match std::fs::read_to_string(&flake_path) {
|
||||
Ok(cur) => cur,
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => String::new(),
|
||||
Err(e) => return Err(e).with_context(|| format!("read {}", flake_path.display())),
|
||||
};
|
||||
if cur.contains(MODULE_FLAKE_MARKER) {
|
||||
return Ok(());
|
||||
}
|
||||
let want = lifecycle::initial_flake_nix();
|
||||
std::fs::write(&flake_path, want).with_context(|| format!("write {}", flake_path.display()))?;
|
||||
raw_git(
|
||||
&dir,
|
||||
dir,
|
||||
&[
|
||||
"-c",
|
||||
"user.name=c0re",
|
||||
|
|
@ -192,7 +202,7 @@ async fn migrate_applied_repo(name: &str) -> Result<()> {
|
|||
)
|
||||
.await?;
|
||||
raw_git(
|
||||
&dir,
|
||||
dir,
|
||||
&[
|
||||
"-c",
|
||||
"user.name=c0re",
|
||||
|
|
@ -206,7 +216,7 @@ async fn migrate_applied_repo(name: &str) -> Result<()> {
|
|||
.await?;
|
||||
// Relocate deployed/0 to the migration commit so
|
||||
// setup_applied's existence check passes.
|
||||
raw_git(&dir, &["tag", "-f", "deployed/0", "HEAD"]).await?;
|
||||
raw_git(dir, &["tag", "-f", "deployed/0", "HEAD"]).await?;
|
||||
tracing::info!(%name, "migration: applied repo migrated to module-only flake");
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -241,3 +251,22 @@ async fn raw_git(dir: &Path, args: &[&str]) -> Result<()> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn unreadable_flake_is_left_untouched() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
std::fs::create_dir(dir.path().join(".git")).expect("mkdir .git");
|
||||
let flake = dir.path().join("flake.nix");
|
||||
let bytes = [0xff_u8, 0xfe, b'x'];
|
||||
std::fs::write(&flake, bytes).expect("write flake");
|
||||
|
||||
let res = migrate_applied_dir("t", dir.path()).await;
|
||||
|
||||
assert!(res.is_err(), "non-UTF-8 flake.nix must fail the migration");
|
||||
assert_eq!(std::fs::read(&flake).expect("read back"), bytes);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue