Etapa F paquetería #6: repo sobre red — install --repo URL (HTTP/HTTPS)

El repo son ficheros estáticos (index.json + .swm) ⇒ cualquier servidor estático lo sirve.

- hammer-cli: `RepoSource` {Local(path) | Http(url)}. `install --repo` ahora acepta path o URL.
  Para HTTP: lee index.json por GET, materializa un repo LOCAL temporal bajando el índice + los
  .swm del cierre de deps (curl, vía download::fetch_url_bytes), y de ahí el flujo es IDÉNTICO al
  local (resolución de deps, verificación de release/firma/base, reproduce + hidrata). tempfile
  pasa a dep normal de hammer-cli.
- Validado E2E: server HTTP estático + install openssh vía http:// → "release: trusted" (índice
  firmado bajado por red) → "repo: bajados 3 .swm" (cierre openssh+zlib+openssl) → resuelve del
  temporal. (El proxy del sandbox exige NO_PROXY para localhost; el código es correcto.) 31 verde.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 07:07:32 -04:00
co-authored by Claude Opus 4.8
parent 9d1b2d4a76
commit 910db267ef
3 changed files with 95 additions and 15 deletions
+12 -9
View File
@@ -137,12 +137,15 @@ CLI:
`strip_components`, y las `deps` por nombre; los patches de la receta viajan inline
(concatenados). Si la receta declara build-deps, `pack` recuerda publicarlas en el mismo repo.
Con `--repo DIR` **publica** en un repositorio (ver abajo) en vez de (o además de) `--out`.
- `hammer install <nombre> [--repo DIR]`**consume** del repositorio: resuelve `nombre` en el
índice, verifica la firma (con `--trust DIR`) y la base (con `--base-ref`), **resuelve el cierre
transitivo de build-deps** desde el índice (orden topológico) poblando un catálogo de recetas, y
delega en el camino de `apply` (reproduce el `source_patch` desde fuente, con sus deps
materializadas en el sandbox, + hidrata). Nunca corre un binario ajeno. `--prefix`/
`--skip-source-patch` para staging y dry-run de schema.
- `hammer install <nombre> [--repo DIR|URL]`**consume** del repositorio: resuelve `nombre` en
el índice, verifica la firma del release y la del `.swm` (con `--trust DIR`) y la base (con
`--base-ref`), **resuelve el cierre transitivo de build-deps** desde el índice (orden
topológico) poblando un catálogo de recetas, y delega en el camino de `apply` (reproduce el
`source_patch` desde fuente, con sus deps materializadas en el sandbox, + hidrata). Nunca corre
un binario ajeno. Registra el paquete en la DB de instalados (`--db`). `--repo` admite un
directorio local **o una URL HTTP(S)** (el repo son ficheros estáticos: `index.json` + los
`.swm`; con URL baja el índice + el cierre de deps a un temporal y procede igual).
`--prefix`/`--skip-source-patch` para staging y dry-run de schema.
- `hammer repo list [--repo DIR]` — lista el catálogo (`<repo>/index.json`).
- `hammer repo sign --repo DIR --key KEY` — firma el ÍNDICE entero (release). Re-firmá tras
publicar (cada `pack --repo` invalida la firma del release).
@@ -159,9 +162,9 @@ Un **repo** es un directorio con los `.swm` + un `index.json` que mapea `nombre
diffeable). Un `.swm` no lleva identidad propia (es un manifiesto de mutación, no "el paquete
X"); la identidad la asigna el repo al publicar — el índice es el namespace. `pack --repo`
publica con el nombre/versión de la receta (upsert idempotente por nombre; una versión nueva
retira el `.swm` huérfano). El transporte del repo (filesystem / sshfs / mirror) es ortogonal:
ver `hammer-mirror` para el CAS del store. Tipos en `hammer-core::repo` (`RepoIndex`,
`PackageEntry`).
retira el `.swm` huérfano). El repo son ficheros estáticos, así que `install --repo URL` lo
consume por HTTP(S) (cualquier servidor estático sirve; baja `index.json` + el cierre de deps a
un temporal). Tipos en `hammer-core::repo` (`RepoIndex`, `PackageEntry`).
**Dependencias.** Un `source_patch` lleva sus build-deps por NOMBRE (las de la receta original);
la `PackageEntry` las espeja para resolver el grafo sin abrir cada `.swm`. `install <nombre>`