From c3f890c7d1fdfaf2a15382c3bd295d78a3ec4c99 Mon Sep 17 00:00:00 2001 From: sergio Date: Sun, 21 Jun 2026 08:21:47 -0400 Subject: [PATCH] =?UTF-8?q?Etapa=20G=20capa-de-adaptaci=C3=B3n=20#4:=20pla?= =?UTF-8?q?ntilla=20Cargo=20para=20imports=20Rust=20de=20nix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El tier de mayor yield (Rust) salía como github sin --bin ni install ⇒ no buildeable. Ahora un paquete buildRustPackage sale build-ready, con el patrón de la receta ripgrep. - nix_import.rs: NixPkg gana is_rust + main_program. Si is_rust ⇒ flags=["--bin", ] (bin = meta.mainProgram, ripgrep→rg) + install "cp target/release/ /out/usr/bin/". +1 test. - nix-import.sh: detecta Rust por `hasAttr "cargoDeps" p`; main_program = meta.mainProgram or pname. - Validado real: import fd → repo+commit, flags=["--bin","fd"], install template. Build-ready (sólo el commit es tag, no SHA — refinamiento aparte). 31 suites verde. Co-Authored-By: Claude Opus 4.8 --- crates/hammer-cli/src/nix_import.rs | 42 +++++++++++++++++++++++++++-- scripts/nix-import.sh | 3 +++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/crates/hammer-cli/src/nix_import.rs b/crates/hammer-cli/src/nix_import.rs index 26bad405..9d421236 100644 --- a/crates/hammer-cli/src/nix_import.rs +++ b/crates/hammer-cli/src/nix_import.rs @@ -28,6 +28,13 @@ pub struct NixPkg { pub build_inputs: Vec, #[serde(default)] pub native_build_inputs: Vec, + /// `true` si nixpkgs lo construye con `rustPlatform.buildRustPackage` (el wrapper lo detecta + /// por `cargoDeps`). Activa la plantilla Cargo de hammer (`--bin` + cp target/release). + #[serde(default)] + pub is_rust: bool, + /// El binario principal (`meta.mainProgram` de nix; p.ej. ripgrep→"rg"). Para el `--bin`. + #[serde(default)] + pub main_program: String, } /// El origen TAL CUAL lo da `nix eval` del `p.src`: la URL fetcheada + el `outputHash`/mode de la @@ -160,9 +167,26 @@ pub fn to_recipe_toml(pkg: &NixPkg) -> Result { format!("\n[deps]\nbuild = [{list}]\n") }; + // Rust (buildRustPackage): emite la plantilla Cargo de hammer — `--bin ` (cargo exige UN + // target) + install copiando `target/release/` a /out (mismo patrón que la receta ripgrep). + // El bin = meta.mainProgram de nix (ripgrep→rg), o el pname. Esto deja la receta build-ready. + let (flags_line, rust_install) = if pkg.is_rust { + let bin = if pkg.main_program.is_empty() { name.clone() } else { sanitize_name(&pkg.main_program) }; + ( + format!("flags = [\"--bin\", \"{bin}\"]\n"), + format!( + "\n[build.phases]\ninstall = \"mkdir -p /out/usr/bin && cp target/release/{bin} /out/usr/bin/{bin}\"\n" + ), + ) + } else { + ("flags = []\n".to_string(), String::new()) + }; + // configureFlags → una fase configure explícita (si las hay). Si no, se deja a la heurística // del lab. NOTA: muchos paquetes nix no son autotools (cmake/meson); esto es best-effort. - let phases_block = if pkg.configure_flags.is_empty() { + let phases_block = if !rust_install.is_empty() { + rust_install + } else if pkg.configure_flags.is_empty() { String::new() } else { let flags = pkg @@ -189,7 +213,7 @@ pub fn to_recipe_toml(pkg: &NixPkg) -> Result { compiler = \"zig-cc\"\n\ target = \"x86_64-linux-musl\"\n\ link = \"static\"\n\ - flags = []\n\ + {flags_line}\ {phases_block}{deps_block}" ); Ok(toml) @@ -372,6 +396,20 @@ mod tests { assert!(recipe.build.phases.configure.as_deref().unwrap().contains("--disable-nls")); } + #[test] + fn rust_package_gets_bin_and_install_template() { + let json = r#"{ + "pname": "ripgrep", "version": "14.1.1", + "source": { "url": "https://github.com/BurntSushi/ripgrep/archive/14.1.1.tar.gz", "output_hash_mode": "recursive" }, + "is_rust": true, "main_program": "rg" + }"#; + let pkg: NixPkg = serde_json::from_str(json).unwrap(); + let recipe = hammer_core::Recipe::from_toml(&to_recipe_toml(&pkg).unwrap()).unwrap(); + assert_eq!(recipe.build.flags, vec!["--bin", "rg"]); + let inst = recipe.build.phases.install.as_deref().unwrap(); + assert!(inst.contains("cp target/release/rg /out/usr/bin/rg"), "{inst}"); + } + #[test] fn filters_nix_stdenv_noise() { let json = r#"{ diff --git a/scripts/nix-import.sh b/scripts/nix-import.sh index 687ac94c..1a72c3b8 100755 --- a/scripts/nix-import.sh +++ b/scripts/nix-import.sh @@ -31,6 +31,9 @@ json=$(nix eval $NIXFLAGS --json "${NIXPKGS}#${ATTR}" --apply ' configure_flags = p.configureFlags or []; build_inputs = builtins.filter (s: s != "") (map (x: x.pname or x.name or "") (p.buildInputs or [])); native_build_inputs = builtins.filter (s: s != "") (map (x: x.pname or x.name or "") (p.nativeBuildInputs or [])); + # Rust: buildRustPackage setea cargoDeps ⇒ activa la plantilla Cargo del importador. + is_rust = builtins.hasAttr "cargoDeps" p; + main_program = p.meta.mainProgram or p.pname or ""; }') printf '%s' "$json" | $HAMMER import-nix -