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…
Etapa G: orquestador de tandas `import-batch.sh` (escalera nix→Alpine, yield por tier)
1#!/bin/sh
2# import-batch.sh <pkg...> | import-batch.sh -f <listfile> — Etapa G: importa una TANDA a
3# escala aplicando la ESCALERA DE FALLBACK (memoria etapa-g): por cada paquete intenta primero nix
4# (Rust/Go/CLI moderno, ~100% en musl) y, si el import falla (src no-clasificable, eval error), cae
5# a Alpine (que TRAE los parches de musl) probando `main` y luego `community`. Escribe la receta a
6# OUTDIR/<pkg>.toml y, al final, MIDE EL YIELD POR TIER (nix / alpine / fallaron) — el dato real que
7# decide dónde está la fricción al escalar, sin especular.
8#
9# Es sólo el IMPORT (barato). El trabajo real es construir: encadená con
10# scripts/pin-recipes.sh "$OUTDIR"/*.toml (Fase 2: tag→SHA en lote)
11# scripts/build-repo.sh (Etapa F: pack --build + repo firmado)
12#
13# Ej: scripts/import-batch.sh ripgrep fd bat hyperfine
14# scripts/import-batch.sh -f tandas/cli-rust.txt
15# OUTDIR=recipes/incoming scripts/import-batch.sh sd dust
16# Env: OUTDIR (default recipes), NIX_STORE (p.ej. $HOME/.nixstore si /nix/store no es escribible),
17# ALPINE_BRANCH (default master), HAMMER (cmd del cli). Un nombre puede mapear nix→alpine
18# distintos con `nixattr=alpinepkg` (p.ej. `ripgrep=ripgrep`, `the_silver_searcher=the-silver-searcher`).
19set -eu
20
21here=$(dirname "$0")
22OUTDIR="${OUTDIR:-recipes}"
23export OUTDIR # alpine-import.sh baja sus .patch acá
24
25# Resolver la lista de paquetes: -f <fichero> (una entrada por línea, '#' comenta) o argumentos.
26if [ "${1:-}" = "-f" ]; then
27 [ -n "${2:-}" ] || { echo "uso: import-batch.sh -f <listfile>" >&2; exit 1; }
28 pkgs=$(sed -e 's/#.*//' -e '/^[[:space:]]*$/d' "$2")
29else
30 [ "$#" -gt 0 ] || { echo "uso: import-batch.sh <pkg...> | -f <listfile>" >&2; exit 1; }
31 pkgs=$(printf '%s\n' "$@")
32fi
33
34mkdir -p "$OUTDIR"
35nix_n=0; alpine_n=0; failed=""; got=""
36
37# IFS=newline para tolerar una entrada por línea; restaurar después no hace falta (sub-shell del for).
38OLDIFS=$IFS; IFS='
39'
40for entry in $pkgs; do
41 IFS=$OLDIFS
42 # Mapeo opcional nixattr=alpinepkg; si no hay '=', el mismo nombre sirve para ambas fuentes.
43 case $entry in
44 *=*) nixattr=${entry%%=*}; alpinepkg=${entry#*=} ;;
45 *) nixattr=$entry; alpinepkg=$entry ;;
46 esac
47 out="$OUTDIR/${nixattr}.toml"
48
49 printf '%-24s ' "$nixattr" >&2
50 if "$here/nix-import.sh" "$nixattr" > "$out.tmp" 2>/dev/null && [ -s "$out.tmp" ]; then
51 mv "$out.tmp" "$out"
52 nix_n=$((nix_n + 1)); got="$got $nixattr"
53 echo "✓ nix" >&2
54 elif "$here/alpine-import.sh" "$alpinepkg" main > "$out.tmp" 2>/dev/null && [ -s "$out.tmp" ]; then
55 mv "$out.tmp" "$out"
56 alpine_n=$((alpine_n + 1)); got="$got $nixattr"
57 echo "✓ alpine/main (parches musl)" >&2
58 elif "$here/alpine-import.sh" "$alpinepkg" community > "$out.tmp" 2>/dev/null && [ -s "$out.tmp" ]; then
59 mv "$out.tmp" "$out"
60 alpine_n=$((alpine_n + 1)); got="$got $nixattr"
61 echo "✓ alpine/community (parches musl)" >&2
62 else
63 rm -f "$out.tmp"
64 failed="$failed $nixattr"
65 echo "✗ ni nix ni Alpine" >&2
66 fi
67done
68
69total=$((nix_n + alpine_n))
70echo >&2
71echo "yield import: $total/$((total + $(printf '%s' "$failed" | wc -w))) — nix=$nix_n, alpine=$alpine_n.${failed:+ FALLARON:$failed}" >&2
72echo "recetas en $OUTDIR/.${got:+ Siguiente: pin + build —} ${got:+scripts/pin-recipes.sh}${got:+ $OUTDIR/*.toml}" >&2
73# Salida limpia en stdout: los nombres importados (para encadenar con xargs si se quiere).
74printf '%s\n' $got