gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1389Shell 137Markdown 80Rust 802602 Definiciones

Etapa G: orquestador de tandas `import-batch.sh` (escalera nix→Alpine, yield por tier)

Faltaba el orquestador de "importar tandas a escala": las piezas per-paquete ya
existían (nix-import.sh, alpine-import.sh) pero sin un driver que aplicara la ESCALERA
DE FALLBACK en lote.

- import-batch.sh <pkg...> | -f <listfile>: por paquete intenta nix (Rust/Go/CLI,
  ~100% musl) y cae a Alpine main→community si el import falla (Alpine trae los parches
  de musl). Mapeo opcional nixattr=alpinepkg. Escribe OUTDIR/<pkg>.toml.
- Mide el YIELD POR TIER (nix / alpine / fallaron) — el dato real al escalar, sin
  especular. stdout limpio = nombres importados (encadenable con xargs/pin-recipes).
- Encadena con las piezas existentes: pin-recipes.sh (Fase 2 tag→SHA) + build-repo.sh
  (Etapa F pack --build + repo firmado).
- tandas/cli-rust.txt: primera tanda curada (tier 1 Rust) para el modo -f.

VALIDADO REAL en vivo (nix 2.34.7): tanda {fd, hyperfine, jq} → yield 3/3, nix=2
(fd/hyperfine), alpine=1 (jq cae a main + baja test-portable.patch). pin en lote sobre
la tanda: fd v10.4.2 → SHA 7027d453, jq (tarball) salteado.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

66dbc3a56131892836f73323c6ec7fb548ad1905 · por sergio · (hace 4 meses) · padre 41aec1704 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

2 archivos · +90 −0

diff --git a/scripts/import-batch.sh b/scripts/import-batch.sh
new file mode 100755
index 00000000..d8a3c675
--- /dev/null
+++ b/scripts/import-batch.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+# import-batch.sh <pkg...>   |   import-batch.sh -f <listfile>   — Etapa G: importa una TANDA a
+# escala aplicando la ESCALERA DE FALLBACK (memoria etapa-g): por cada paquete intenta primero nix
+# (Rust/Go/CLI moderno, ~100% en musl) y, si el import falla (src no-clasificable, eval error), cae
+# a Alpine (que TRAE los parches de musl) probando `main` y luego `community`. Escribe la receta a
+# OUTDIR/<pkg>.toml y, al final, MIDE EL YIELD POR TIER (nix / alpine / fallaron) — el dato real que
+# decide dónde está la fricción al escalar, sin especular.
+#
+# Es sólo el IMPORT (barato). El trabajo real es construir: encadená con
+#   scripts/pin-recipes.sh "$OUTDIR"/*.toml     (Fase 2: tag→SHA en lote)
+#   scripts/build-repo.sh                       (Etapa F: pack --build + repo firmado)
+#
+# Ej:  scripts/import-batch.sh ripgrep fd bat hyperfine
+#      scripts/import-batch.sh -f tandas/cli-rust.txt
+#      OUTDIR=recipes/incoming scripts/import-batch.sh sd dust
+# Env: OUTDIR (default recipes), NIX_STORE (p.ej. $HOME/.nixstore si /nix/store no es escribible),
+#      ALPINE_BRANCH (default master), HAMMER (cmd del cli).  Un nombre puede mapear nix→alpine
+#      distintos con `nixattr=alpinepkg` (p.ej. `ripgrep=ripgrep`, `the_silver_searcher=the-silver-searcher`).
+set -eu
+
+here=$(dirname "$0")
+OUTDIR="${OUTDIR:-recipes}"
+export OUTDIR  # alpine-import.sh baja sus .patch acá
+
+# Resolver la lista de paquetes: -f <fichero> (una entrada por línea, '#' comenta) o argumentos.
+if [ "${1:-}" = "-f" ]; then
+  [ -n "${2:-}" ] || { echo "uso: import-batch.sh -f <listfile>" >&2; exit 1; }
+  pkgs=$(sed -e 's/#.*//' -e '/^[[:space:]]*$/d' "$2")
+else
+  [ "$#" -gt 0 ] || { echo "uso: import-batch.sh <pkg...> | -f <listfile>" >&2; exit 1; }
+  pkgs=$(printf '%s\n' "$@")
+fi
+
+mkdir -p "$OUTDIR"
+nix_n=0; alpine_n=0; failed=""; got=""
+
+# IFS=newline para tolerar una entrada por línea; restaurar después no hace falta (sub-shell del for).
+OLDIFS=$IFS; IFS='
+'
+for entry in $pkgs; do
+  IFS=$OLDIFS
+  # Mapeo opcional nixattr=alpinepkg; si no hay '=', el mismo nombre sirve para ambas fuentes.
+  case $entry in
+    *=*) nixattr=${entry%%=*}; alpinepkg=${entry#*=} ;;
+    *)   nixattr=$entry; alpinepkg=$entry ;;
+  esac
+  out="$OUTDIR/${nixattr}.toml"
+
+  printf '%-24s ' "$nixattr" >&2
+  if "$here/nix-import.sh" "$nixattr" > "$out.tmp" 2>/dev/null && [ -s "$out.tmp" ]; then
+    mv "$out.tmp" "$out"
+    nix_n=$((nix_n + 1)); got="$got $nixattr"
+    echo "✓ nix" >&2
+  elif "$here/alpine-import.sh" "$alpinepkg" main > "$out.tmp" 2>/dev/null && [ -s "$out.tmp" ]; then
+    mv "$out.tmp" "$out"
+    alpine_n=$((alpine_n + 1)); got="$got $nixattr"
+    echo "✓ alpine/main (parches musl)" >&2
+  elif "$here/alpine-import.sh" "$alpinepkg" community > "$out.tmp" 2>/dev/null && [ -s "$out.tmp" ]; then
+    mv "$out.tmp" "$out"
+    alpine_n=$((alpine_n + 1)); got="$got $nixattr"
+    echo "✓ alpine/community (parches musl)" >&2
+  else
+    rm -f "$out.tmp"
+    failed="$failed $nixattr"
+    echo "✗ ni nix ni Alpine" >&2
+  fi
+done
+
+total=$((nix_n + alpine_n))
+echo >&2
+echo "yield import: $total/$((total + $(printf '%s' "$failed" | wc -w))) — nix=$nix_n, alpine=$alpine_n.${failed:+ FALLARON:$failed}" >&2
+echo "recetas en $OUTDIR/.${got:+ Siguiente: pin + build —} ${got:+scripts/pin-recipes.sh}${got:+ $OUTDIR/*.toml}" >&2
+# Salida limpia en stdout: los nombres importados (para encadenar con xargs si se quiere).
+printf '%s\n' $got
diff --git a/tandas/cli-rust.txt b/tandas/cli-rust.txt
new file mode 100644
index 00000000..4f629933
--- /dev/null
+++ b/tandas/cli-rust.txt
@@ -0,0 +1,16 @@
+# Tanda CLI Rust moderno — Etapa G. Tier 1 de la escalera (Rust/musl-friendly → import-nix ~100%).
+# Uso:  NIX_STORE=$HOME/.nixstore OUTDIR=recipes/incoming scripts/import-batch.sh -f tandas/cli-rust.txt
+# Luego: scripts/pin-recipes.sh recipes/incoming/*.toml  &&  (pack --build para medir build-yield).
+# Sintaxis: un paquete por línea; '#' comenta; `nixattr=alpinepkg` si los nombres difieren.
+fd
+bat
+hyperfine
+ripgrep
+sd
+dust
+procs
+tokei
+hexyl
+xh
+zoxide
+bottom