diff --git a/crates/hammer-cli/src/alpine_import.rs b/crates/hammer-cli/src/alpine_import.rs index f370897d..4c53c5d5 100644 --- a/crates/hammer-cli/src/alpine_import.rs +++ b/crates/hammer-cli/src/alpine_import.rs @@ -105,10 +105,12 @@ pub fn recipe_from_apkbuild(text: &str) -> Result { } else { let mut s = String::from("\n[build.phases]\n"); if let Some(b) = compile { - s.push_str(&format!("# de build() de Alpine (abuild: CHOST/--shared/etc; adaptá a estático):\ncompile = {}\n", toml_multiline(&b))); + let t = translate_abuild(&b, &pkgname, &version); + s.push_str(&format!("# de build() de Alpine (traducido; revisá $CBUILD/$CHOST/--shared para estático):\ncompile = {}\n", toml_multiline(&t))); } if let Some(p) = install { - s.push_str(&format!("# de package() de Alpine (usa $pkgdir → ajustá a /out):\ninstall = {}\n", toml_multiline(&p))); + let t = translate_abuild(&p, &pkgname, &version); + s.push_str(&format!("# de package() de Alpine (traducido $pkgdir→/out):\ninstall = {}\n", toml_multiline(&t))); } s } @@ -245,6 +247,19 @@ fn func_body(text: &str, name: &str) -> Option { } } +/// Traduce las variables de abuild a su equivalente en el lab de hammer. Substituciones SEGURAS +/// (inequívocas): `$pkgdir`→`/out` (el DESTDIR del lab), `$pkgname`→nombre, `$pkgver`→versión. +/// NO toca `$CBUILD/$CHOST/$srcdir/$builddir` ni `--shared` (juicio por-paquete; quedan para el +/// humano, marcados en el comentario de la fase). `make DESTDIR="$pkgdir"` → `make DESTDIR="/out"`. +fn translate_abuild(body: &str, name: &str, version: &str) -> String { + body.replace("${pkgdir}", "/out") + .replace("$pkgdir", "/out") + .replace("${pkgname}", name) + .replace("$pkgname", name) + .replace("${pkgver}", version) + .replace("$pkgver", version) +} + /// Primer hash de un bloque `sha512sums=" \n..."`. fn first_sha(block: &str) -> String { block @@ -305,9 +320,21 @@ package() { assert!(recipe.deps.build.contains(&"openssl".to_string())); assert!(recipe.deps.build.contains(&"linux-headers".to_string())); assert!(recipe.deps.build.contains(&"bar".to_string())); - // fases capturadas de build()/package(): + // fases capturadas de build()/package() y TRADUCIDAS: $pkgdir → /out. assert!(recipe.build.phases.compile.as_deref().unwrap().contains("./configure")); - assert!(recipe.build.phases.install.as_deref().unwrap().contains("DESTDIR")); + let install = recipe.build.phases.install.as_deref().unwrap(); + assert!(install.contains("DESTDIR=\"/out\""), "instala a /out: {install}"); + assert!(!install.contains("$pkgdir"), "no debe quedar $pkgdir: {install}"); + } + + #[test] + fn translate_abuild_substitutes_vars() { + let body = "make DESTDIR=\"$pkgdir\" install\ncp x ${pkgdir}/usr/share/$pkgname/\necho $pkgver"; + let t = translate_abuild(body, "foo", "2.5"); + assert!(t.contains("DESTDIR=\"/out\"")); + assert!(t.contains("/out/usr/share/foo/")); + assert!(t.contains("echo 2.5")); + assert!(!t.contains("$pkg")); } #[test] diff --git a/scripts/alpine-import.sh b/scripts/alpine-import.sh index 900a3a50..ab1e82dd 100755 --- a/scripts/alpine-import.sh +++ b/scripts/alpine-import.sh @@ -17,6 +17,19 @@ BASE="https://gitlab.alpinelinux.org/alpine/aports/-/raw/${BRANCH}/${REPO}/${PKG apk=$(curl -fsSL "${BASE}/APKBUILD") || { echo "no encontré ${REPO}/${PKG} en aports@${BRANCH}" >&2; exit 1; } toml=$(printf '%s' "$apk" | $HAMMER import-alpine -) + +# sha256 automático: Alpine publica sha512, pero hammer pide sha256. Bajamos el tarball UNA vez y +# lo calculamos, reemplazando el FIXME ⇒ receta lista para `pack --build` sin tocar el hash a mano. +url=$(printf '%s\n' "$toml" | sed -n 's/^tarball = "\(.*\)"$/\1/p' | head -1) +if [ -n "$url" ]; then + sha=$(curl -fsSL "$url" 2>/dev/null | sha256sum | cut -d' ' -f1) + if [ -n "$sha" ] && [ "$sha" != "$(printf '' | sha256sum | cut -d' ' -f1)" ]; then + toml=$(printf '%s\n' "$toml" | sed "s|FIXME-sha256|$sha|") + echo " sha256 calculado: $sha" >&2 + else + echo " ⚠ no pude bajar el tarball para sha256 (queda FIXME): $url" >&2 + fi +fi printf '%s\n' "$toml" # Bajar los .patch referenciados (los parches de musl que hacen al paquete compilar).