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 1393Shell 130Rust 79Markdown 732501 Definiciones

Etapa G capa-de-adaptación #4: plantilla Cargo para imports Rust de nix

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>] (bin =
  meta.mainProgram, ripgrep→rg) + install "cp target/release/<bin> /out/usr/bin/<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 <noreply@anthropic.com>

c3f890c7d1fdfaf2a15382c3bd295d78a3ec4c99 · por sergio · (hace 4 meses) · padre b66cae91a · ver el árbol en este commit

Delta semántico · 3

crates/hammer-cli/src/nix_import.rs

2 archivos · +43 −2

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<String>,
     #[serde(default)]
     pub native_build_inputs: Vec<String>,
+    /// `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<String, String> {
         format!("\n[deps]\nbuild = [{list}]\n")
     };
 
+    // Rust (buildRustPackage): emite la plantilla Cargo de hammer — `--bin <bin>` (cargo exige UN
+    // target) + install copiando `target/release/<bin>` 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<String, String> {
          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 -