diff --git a/functions/shell/extract_script_description.go b/functions/shell/extract_script_description.go new file mode 100644 index 00000000..05b0c7a1 --- /dev/null +++ b/functions/shell/extract_script_description.go @@ -0,0 +1,48 @@ +package shell + +import ( + "bufio" + "os" + "path/filepath" + "strings" +) + +// ExtractScriptDescription parses a script file and returns the first +// meaningful comment line as a description. Skips shebangs and empty lines. +// Falls back to the filename (without extension, underscores replaced by spaces). +func ExtractScriptDescription(scriptPath string) string { + file, err := os.Open(scriptPath) + if err != nil { + return fallbackDescription(scriptPath) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + lineCount := 0 + for scanner.Scan() && lineCount < 5 { + line := strings.TrimSpace(scanner.Text()) + lineCount++ + + if strings.HasPrefix(line, "#!") || line == "" { + continue + } + if strings.HasPrefix(line, "#") { + desc := strings.TrimSpace(strings.TrimPrefix(line, "#")) + desc = strings.TrimSpace(strings.TrimPrefix(desc, "Script:")) + desc = strings.TrimSpace(strings.TrimPrefix(desc, "Script para")) + desc = strings.TrimSpace(strings.TrimPrefix(desc, "Descripción:")) + desc = strings.TrimSpace(strings.TrimPrefix(desc, "Description:")) + if desc != "" { + return desc + } + } + } + + return fallbackDescription(scriptPath) +} + +func fallbackDescription(scriptPath string) string { + name := filepath.Base(scriptPath) + name = strings.TrimSuffix(name, filepath.Ext(name)) + return strings.ReplaceAll(name, "_", " ") +} diff --git a/functions/shell/extract_script_description.md b/functions/shell/extract_script_description.md new file mode 100644 index 00000000..f0cc6760 --- /dev/null +++ b/functions/shell/extract_script_description.md @@ -0,0 +1,46 @@ +--- +name: extract_script_description +kind: function +lang: go +domain: shell +version: "1.0.0" +purity: impure +signature: "func ExtractScriptDescription(scriptPath string) string" +description: "Parsea un archivo de script y extrae la primera linea de comentario util como descripcion. Salta shebangs y lineas vacias. Si no encuentra descripcion, usa el nombre del archivo." +tags: [shell, script, description, parse, comment, metadata] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [bufio, os, path/filepath, strings] +params: + - name: scriptPath + desc: "ruta al archivo de script (.sh, .ps1, .bat)" +output: "descripcion extraida del primer comentario, o nombre del archivo humanizado" +tested: false +tests: [] +test_file_path: "" +file_path: "functions/shell/extract_script_description.go" +source_repo: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/egutierrez/DevLauncher.git" +source_license: "MIT" +source_file: "launcher/middleware/reader.go" +--- + +## Ejemplo + +```go +// Dado un script con: +// #!/bin/bash +// # Analisis completo de DNS para un dominio +desc := shell.ExtractScriptDescription("/path/to/analisis_dns.sh") +// desc == "Analisis completo de DNS para un dominio" + +// Sin comentario util +desc2 := shell.ExtractScriptDescription("/path/to/instalar_go.sh") +// desc2 == "instalar go" (fallback del nombre) +``` + +## Notas + +Busca en las primeras 5 lineas. Remueve prefijos comunes como "Script:", "Descripción:", "Description:" del comentario. Si el archivo no existe o no tiene comentarios utiles, genera una descripcion a partir del nombre del archivo reemplazando underscores por espacios.