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.
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user