hydrate: un artefacto VACÍO ya no se proyecta como éxito

Tercer sitio con la misma pregunta mal hecha, encontrado con el grep que la lección del
commit anterior pedía hacer: `has` (tapado 2026-08-10), `seal` (tapado hoy) y `hydrate`,
que seguía con `is_dir()` pelado. Un directorio vacío pasaba el chequeo, proyectaba 0
ficheros y devolvía un HydrateReport de éxito.

Duele especial acá porque el escritorio se hidrata así (`hammer hydrate <hash> --into`,
137/137 en KDE): un FHS proyectado desde nada sale «OK» y falla mucho más tarde, sin
rastro de qué artefacto faltaba.

Queda a propósito sin tocar `hammer-mirror::index`: ahí el vacío se autocorrige, porque
indexa por `of_tree` y el contenido difiere del origen ⇒ el sync lo trae.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
This commit is contained in:
Sergio
2026-08-29 18:50:14 +00:00
co-authored by Claude Opus 5
parent 1eb39976b0
commit ccb3d6af2f
+10 -2
View File
@@ -62,9 +62,17 @@ pub fn hydrate(
mode: LinkMode,
dynamic: Option<&DynamicSpec>,
) -> hammer_core::Result<HydrateReport> {
if !artifact_dir.is_dir() {
// `is_dir()` a secas acepta un directorio VACÍO: hydrate proyectaría 0 ficheros y devolvería
// un HydrateReport de éxito. Es el mismo agujero que ya se tapó en `Store::has` (2026-08-10) y
// en `Store::seal` (2026-08-29): un vacío no es un artefacto, es un nombre. Acá duele especial
// porque el escritorio se hidrata así (`hammer hydrate <hash> --into`), y un FHS proyectado
// desde nada sale "OK" y falla mucho más tarde, sin rastro de cuál artefacto faltaba.
let vacio = std::fs::read_dir(artifact_dir)
.map(|mut e| e.next().is_none())
.unwrap_or(true);
if !artifact_dir.is_dir() || vacio {
return Err(hammer_core::Error::Store(format!(
"artefacto inexistente: {}",
"artefacto inexistente o VACÍO: {}",
artifact_dir.display()
)));
}