tawasuyu

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 1572Shell 203Rust 109Markdown 993728 Definiciones

Etapa G: detect_go_main ve el main bajo header de comentario de bloque

cmd/helm/helm.go arranca con un header Apache /* ... */ cuyas líneas internas no llevan '*';
el filtro por-línea ingenuo de is_main_go cortaba en 'Copyright ...' y daba 'no es main' ⇒
detect_go_main no hallaba cmd/helm y caía a '.' (raíz sin .go → 'no Go files in /src'). Ahora
rastrea el estado dentro/fuera de bloque /* */. Afecta a cualquier .go con header de bloque.
Test: detect_go_main_sees_main_under_block_comment_header.

3b23463ac1c42864a7bf2a869409c211047b5744 · por sergio · (hace 3 meses) · padre 06ba41733 · ver el árbol en este commit

Delta semántico · 3

crates/hammer-build/src/lib.rs

1 archivos · +50 −2

diff --git a/crates/hammer-build/src/lib.rs b/crates/hammer-build/src/lib.rs
index 011155e3..19323680 100644
--- a/crates/hammer-build/src/lib.rs
+++ b/crates/hammer-build/src/lib.rs
@@ -488,11 +488,45 @@ fn detect_build_system(src: &Path) -> BuildSys {
 fn detect_go_main(src: &Path) -> String {
     fn is_main_go(path: &Path) -> bool {
         let Ok(text) = std::fs::read_to_string(path) else { return false };
+        // El primer token significativo de un .go es la cláusula `package` (tras build-constraints
+        // `//go:build`, comentarios de línea y el header de licencia). Hay que saltar comentarios de
+        // BLOQUE `/* ... */` correctamente: muchos headers Apache son `/*\nCopyright ...\n*/` y las
+        // líneas internas NO arrancan con `*` ⇒ un filtro por-línea ingenuo cortaría ahí y fallaría
+        // (p.ej. cmd/helm/helm.go). Escaneamos rastreando el estado dentro/fuera de bloque.
+        let mut in_block = false;
         for line in text.lines() {
-            let l = line.trim();
-            if l.is_empty() || l.starts_with("//") || l.starts_with("/*") || l.starts_with('*') {
+            let mut l = line.trim();
+            if in_block {
+                match l.find("*/") {
+                    Some(i) => {
+                        l = l[i + 2..].trim();
+                        in_block = false;
+                    }
+                    None => continue,
+                }
+            }
+            if l.is_empty() || l.starts_with("//") {
                 continue;
             }
+            if let Some(i) = l.find("/*") {
+                let before = l[..i].trim();
+                if !before.is_empty() {
+                    return before.starts_with("package main");
+                }
+                match l[i + 2..].find("*/") {
+                    Some(j) => {
+                        let after = l[i + 2 + j + 2..].trim();
+                        if after.is_empty() {
+                            continue;
+                        }
+                        return after.starts_with("package main");
+                    }
+                    None => {
+                        in_block = true;
+                        continue;
+                    }
+                }
+            }
             return l.starts_with("package main");
         }
         false
@@ -800,6 +834,20 @@ commit = "deadbeef"
         assert_eq!(detect_go_main(d.path()), "./cmd/mlr");
     }
 
+    #[test]
+    fn detect_go_main_sees_main_under_block_comment_header() {
+        // header de licencia `/* ... */` con líneas internas SIN `*` (estilo Apache de helm):
+        // el main en cmd/helm debe detectarse igual (regresión del corte ingenuo por-línea).
+        let d = tempfile::tempdir().unwrap();
+        std::fs::create_dir_all(d.path().join("cmd/helm")).unwrap();
+        std::fs::write(
+            d.path().join("cmd/helm/helm.go"),
+            b"/*\nCopyright The Helm Authors.\nLicensed under the Apache License 2.0\n*/\n\npackage main\n\nfunc main() {}\n",
+        )
+        .unwrap();
+        assert_eq!(detect_go_main(d.path()), "./cmd/helm");
+    }
+
     #[test]
     fn detect_autoconf_raw_when_only_configure_ac() {
         let d = tempfile::tempdir().unwrap();