From 7839ae6fa73bfcab2431bbe614e99a0a63859447 Mon Sep 17 00:00:00 2001 From: Kayvan Sylvan Date: Sat, 14 Feb 2026 00:45:46 -0800 Subject: [PATCH] MAESTRO: i18n: extract hard-coded strings from internal/plugins/template/extension_executor.go Co-Authored-By: Claude Opus 4.6 --- internal/i18n/locales/de.json | 14 ++++++++- internal/i18n/locales/en.json | 14 ++++++++- internal/i18n/locales/es.json | 14 ++++++++- internal/i18n/locales/fa.json | 14 ++++++++- internal/i18n/locales/fr.json | 14 ++++++++- internal/i18n/locales/it.json | 14 ++++++++- internal/i18n/locales/ja.json | 14 ++++++++- internal/i18n/locales/pt-BR.json | 14 ++++++++- internal/i18n/locales/pt-PT.json | 14 ++++++++- internal/i18n/locales/zh.json | 14 ++++++++- .../plugins/template/extension_executor.go | 30 ++++++++++--------- 11 files changed, 146 insertions(+), 24 deletions(-) diff --git a/internal/i18n/locales/de.json b/internal/i18n/locales/de.json index 0263a63f..6ab53cb1 100644 --- a/internal/i18n/locales/de.json +++ b/internal/i18n/locales/de.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "Hash-Abweichung der Programmdatei für %s", "extension_failed_marshal_registry": "Erweiterungsregistrierung konnte nicht serialisiert werden: %w", "extension_failed_read_registry": "Erweiterungsregistrierung konnte nicht gelesen werden: %w", - "extension_failed_parse_registry": "Erweiterungsregistrierung konnte nicht geparst werden: %w" + "extension_failed_parse_registry": "Erweiterungsregistrierung konnte nicht geparst werden: %w", + "extension_failed_get_extension": "Erweiterung konnte nicht abgerufen werden: %w", + "extension_failed_format_command": "Befehl konnte nicht formatiert werden: %w", + "extension_empty_command": "Leerer Befehl nach Formatierung", + "extension_operation_not_found": "Operation %s für Erweiterung %s nicht gefunden", + "extension_executing_command": "Befehl wird ausgeführt: %s\n", + "extension_execution_failed_stderr": "Ausführung fehlgeschlagen: %w\nstderr: %s", + "extension_no_file_config": "Keine Dateikonfiguration gefunden", + "extension_no_output_file": "Keine Ausgabedatei in der Konfiguration angegeben", + "extension_execution_timed_out": "Ausführung nach %v abgelaufen", + "extension_execution_failed_err": "Ausführung fehlgeschlagen: %w\nerr: %s", + "extension_failed_read_output_file": "Ausgabedatei konnte nicht gelesen werden: %w", + "extension_failed_get_output_path": "Ausgabepfad konnte nicht ermittelt werden: %w\nerr: %s" } diff --git a/internal/i18n/locales/en.json b/internal/i18n/locales/en.json index 087f165e..af127e58 100644 --- a/internal/i18n/locales/en.json +++ b/internal/i18n/locales/en.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "executable hash mismatch for %s", "extension_failed_marshal_registry": "failed to marshal extension registry: %w", "extension_failed_read_registry": "failed to read extension registry: %w", - "extension_failed_parse_registry": "failed to parse extension registry: %w" + "extension_failed_parse_registry": "failed to parse extension registry: %w", + "extension_failed_get_extension": "failed to get extension: %w", + "extension_failed_format_command": "failed to format command: %w", + "extension_empty_command": "empty command after formatting", + "extension_operation_not_found": "operation %s not found for extension %s", + "extension_executing_command": "Executing command: %s\n", + "extension_execution_failed_stderr": "execution failed: %w\nstderr: %s", + "extension_no_file_config": "no file configuration found", + "extension_no_output_file": "no output file specified in configuration", + "extension_execution_timed_out": "execution timed out after %v", + "extension_execution_failed_err": "execution failed: %w\nerr: %s", + "extension_failed_read_output_file": "failed to read output file: %w", + "extension_failed_get_output_path": "failed to get output path: %w\nerr: %s" } diff --git a/internal/i18n/locales/es.json b/internal/i18n/locales/es.json index 72060986..d53f383c 100644 --- a/internal/i18n/locales/es.json +++ b/internal/i18n/locales/es.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "discrepancia de hash del ejecutable para %s", "extension_failed_marshal_registry": "no se pudo serializar el registro de extensiones: %w", "extension_failed_read_registry": "no se pudo leer el registro de extensiones: %w", - "extension_failed_parse_registry": "no se pudo analizar el registro de extensiones: %w" + "extension_failed_parse_registry": "no se pudo analizar el registro de extensiones: %w", + "extension_failed_get_extension": "no se pudo obtener la extensión: %w", + "extension_failed_format_command": "no se pudo formatear el comando: %w", + "extension_empty_command": "comando vacío después del formateo", + "extension_operation_not_found": "operación %s no encontrada para la extensión %s", + "extension_executing_command": "Ejecutando comando: %s\n", + "extension_execution_failed_stderr": "la ejecución falló: %w\nstderr: %s", + "extension_no_file_config": "no se encontró configuración de archivo", + "extension_no_output_file": "no se especificó archivo de salida en la configuración", + "extension_execution_timed_out": "la ejecución expiró después de %v", + "extension_execution_failed_err": "la ejecución falló: %w\nerr: %s", + "extension_failed_read_output_file": "no se pudo leer el archivo de salida: %w", + "extension_failed_get_output_path": "no se pudo obtener la ruta de salida: %w\nerr: %s" } diff --git a/internal/i18n/locales/fa.json b/internal/i18n/locales/fa.json index 698ef924..f349c7e8 100644 --- a/internal/i18n/locales/fa.json +++ b/internal/i18n/locales/fa.json @@ -376,5 +376,17 @@ "extension_executable_hash_mismatch": "عدم تطابق هش فایل اجرایی برای %s", "extension_failed_marshal_registry": "سریال‌سازی رجیستری افزونه‌ها ناموفق بود: %w", "extension_failed_read_registry": "خواندن رجیستری افزونه‌ها ناموفق بود: %w", - "extension_failed_parse_registry": "تجزیه رجیستری افزونه‌ها ناموفق بود: %w" + "extension_failed_parse_registry": "تجزیه رجیستری افزونه‌ها ناموفق بود: %w", + "extension_failed_get_extension": "دریافت افزونه ناموفق بود: %w", + "extension_failed_format_command": "قالب‌بندی دستور ناموفق بود: %w", + "extension_empty_command": "دستور خالی پس از قالب‌بندی", + "extension_operation_not_found": "عملیات %s برای افزونه %s یافت نشد", + "extension_executing_command": "در حال اجرای دستور: %s\n", + "extension_execution_failed_stderr": "اجرا ناموفق بود: %w\nstderr: %s", + "extension_no_file_config": "پیکربندی فایل یافت نشد", + "extension_no_output_file": "فایل خروجی در پیکربندی مشخص نشده است", + "extension_execution_timed_out": "اجرا پس از %v منقضی شد", + "extension_execution_failed_err": "اجرا ناموفق بود: %w\nerr: %s", + "extension_failed_read_output_file": "خواندن فایل خروجی ناموفق بود: %w", + "extension_failed_get_output_path": "دریافت مسیر خروجی ناموفق بود: %w\nerr: %s" } diff --git a/internal/i18n/locales/fr.json b/internal/i18n/locales/fr.json index 0cf1d527..cfbc244a 100644 --- a/internal/i18n/locales/fr.json +++ b/internal/i18n/locales/fr.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "discordance de hash de l'exécutable pour %s", "extension_failed_marshal_registry": "impossible de sérialiser le registre d'extensions : %w", "extension_failed_read_registry": "impossible de lire le registre d'extensions : %w", - "extension_failed_parse_registry": "impossible d'analyser le registre d'extensions : %w" + "extension_failed_parse_registry": "impossible d'analyser le registre d'extensions : %w", + "extension_failed_get_extension": "impossible d'obtenir l'extension : %w", + "extension_failed_format_command": "impossible de formater la commande : %w", + "extension_empty_command": "commande vide après le formatage", + "extension_operation_not_found": "opération %s introuvable pour l'extension %s", + "extension_executing_command": "Exécution de la commande : %s\n", + "extension_execution_failed_stderr": "l'exécution a échoué : %w\nstderr : %s", + "extension_no_file_config": "aucune configuration de fichier trouvée", + "extension_no_output_file": "aucun fichier de sortie spécifié dans la configuration", + "extension_execution_timed_out": "l'exécution a expiré après %v", + "extension_execution_failed_err": "l'exécution a échoué : %w\nerr : %s", + "extension_failed_read_output_file": "impossible de lire le fichier de sortie : %w", + "extension_failed_get_output_path": "impossible d'obtenir le chemin de sortie : %w\nerr : %s" } diff --git a/internal/i18n/locales/it.json b/internal/i18n/locales/it.json index 7dbfba7a..93669f8d 100644 --- a/internal/i18n/locales/it.json +++ b/internal/i18n/locales/it.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "discrepanza hash dell'eseguibile per %s", "extension_failed_marshal_registry": "impossibile serializzare il registro estensioni: %w", "extension_failed_read_registry": "impossibile leggere il registro estensioni: %w", - "extension_failed_parse_registry": "impossibile analizzare il registro estensioni: %w" + "extension_failed_parse_registry": "impossibile analizzare il registro estensioni: %w", + "extension_failed_get_extension": "impossibile ottenere l'estensione: %w", + "extension_failed_format_command": "impossibile formattare il comando: %w", + "extension_empty_command": "comando vuoto dopo la formattazione", + "extension_operation_not_found": "operazione %s non trovata per l'estensione %s", + "extension_executing_command": "Esecuzione comando: %s\n", + "extension_execution_failed_stderr": "esecuzione fallita: %w\nstderr: %s", + "extension_no_file_config": "nessuna configurazione file trovata", + "extension_no_output_file": "nessun file di output specificato nella configurazione", + "extension_execution_timed_out": "esecuzione scaduta dopo %v", + "extension_execution_failed_err": "esecuzione fallita: %w\nerr: %s", + "extension_failed_read_output_file": "impossibile leggere il file di output: %w", + "extension_failed_get_output_path": "impossibile ottenere il percorso di output: %w\nerr: %s" } diff --git a/internal/i18n/locales/ja.json b/internal/i18n/locales/ja.json index 121dbc76..42132dce 100644 --- a/internal/i18n/locales/ja.json +++ b/internal/i18n/locales/ja.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "%s の実行ファイルのハッシュが一致しません", "extension_failed_marshal_registry": "拡張機能レジストリのシリアル化に失敗しました: %w", "extension_failed_read_registry": "拡張機能レジストリの読み込みに失敗しました: %w", - "extension_failed_parse_registry": "拡張機能レジストリの解析に失敗しました: %w" + "extension_failed_parse_registry": "拡張機能レジストリの解析に失敗しました: %w", + "extension_failed_get_extension": "拡張機能の取得に失敗しました: %w", + "extension_failed_format_command": "コマンドのフォーマットに失敗しました: %w", + "extension_empty_command": "フォーマット後のコマンドが空です", + "extension_operation_not_found": "拡張機能 %s にオペレーション %s が見つかりません", + "extension_executing_command": "コマンドを実行中: %s\n", + "extension_execution_failed_stderr": "実行に失敗しました: %w\nstderr: %s", + "extension_no_file_config": "ファイル設定が見つかりません", + "extension_no_output_file": "設定に出力ファイルが指定されていません", + "extension_execution_timed_out": "%v 後に実行がタイムアウトしました", + "extension_execution_failed_err": "実行に失敗しました: %w\nerr: %s", + "extension_failed_read_output_file": "出力ファイルの読み取りに失敗しました: %w", + "extension_failed_get_output_path": "出力パスの取得に失敗しました: %w\nerr: %s" } diff --git a/internal/i18n/locales/pt-BR.json b/internal/i18n/locales/pt-BR.json index b8631563..25042170 100644 --- a/internal/i18n/locales/pt-BR.json +++ b/internal/i18n/locales/pt-BR.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "discrepância de hash do executável para %s", "extension_failed_marshal_registry": "falha ao serializar o registro de extensões: %w", "extension_failed_read_registry": "falha ao ler o registro de extensões: %w", - "extension_failed_parse_registry": "falha ao analisar o registro de extensões: %w" + "extension_failed_parse_registry": "falha ao analisar o registro de extensões: %w", + "extension_failed_get_extension": "falha ao obter a extensão: %w", + "extension_failed_format_command": "falha ao formatar o comando: %w", + "extension_empty_command": "comando vazio após a formatação", + "extension_operation_not_found": "operação %s não encontrada para a extensão %s", + "extension_executing_command": "Executando comando: %s\n", + "extension_execution_failed_stderr": "execução falhou: %w\nstderr: %s", + "extension_no_file_config": "nenhuma configuração de arquivo encontrada", + "extension_no_output_file": "nenhum arquivo de saída especificado na configuração", + "extension_execution_timed_out": "execução expirou após %v", + "extension_execution_failed_err": "execução falhou: %w\nerr: %s", + "extension_failed_read_output_file": "falha ao ler o arquivo de saída: %w", + "extension_failed_get_output_path": "falha ao obter o caminho de saída: %w\nerr: %s" } diff --git a/internal/i18n/locales/pt-PT.json b/internal/i18n/locales/pt-PT.json index dc4b0e63..3555666a 100644 --- a/internal/i18n/locales/pt-PT.json +++ b/internal/i18n/locales/pt-PT.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "discrepância de hash do executável para %s", "extension_failed_marshal_registry": "falha ao serializar o registo de extensões: %w", "extension_failed_read_registry": "falha ao ler o registo de extensões: %w", - "extension_failed_parse_registry": "falha ao analisar o registo de extensões: %w" + "extension_failed_parse_registry": "falha ao analisar o registo de extensões: %w", + "extension_failed_get_extension": "falha ao obter a extensão: %w", + "extension_failed_format_command": "falha ao formatar o comando: %w", + "extension_empty_command": "comando vazio após a formatação", + "extension_operation_not_found": "operação %s não encontrada para a extensão %s", + "extension_executing_command": "A executar comando: %s\n", + "extension_execution_failed_stderr": "execução falhou: %w\nstderr: %s", + "extension_no_file_config": "nenhuma configuração de ficheiro encontrada", + "extension_no_output_file": "nenhum ficheiro de saída especificado na configuração", + "extension_execution_timed_out": "execução expirou após %v", + "extension_execution_failed_err": "execução falhou: %w\nerr: %s", + "extension_failed_read_output_file": "falha ao ler o ficheiro de saída: %w", + "extension_failed_get_output_path": "falha ao obter o caminho de saída: %w\nerr: %s" } diff --git a/internal/i18n/locales/zh.json b/internal/i18n/locales/zh.json index 7e3076d0..1827c11c 100644 --- a/internal/i18n/locales/zh.json +++ b/internal/i18n/locales/zh.json @@ -384,5 +384,17 @@ "extension_executable_hash_mismatch": "%s 的可执行文件哈希不匹配", "extension_failed_marshal_registry": "序列化扩展注册表失败:%w", "extension_failed_read_registry": "读取扩展注册表失败:%w", - "extension_failed_parse_registry": "解析扩展注册表失败:%w" + "extension_failed_parse_registry": "解析扩展注册表失败:%w", + "extension_failed_get_extension": "获取扩展失败:%w", + "extension_failed_format_command": "格式化命令失败:%w", + "extension_empty_command": "格式化后命令为空", + "extension_operation_not_found": "扩展 %s 中未找到操作 %s", + "extension_executing_command": "正在执行命令:%s\n", + "extension_execution_failed_stderr": "执行失败:%w\nstderr:%s", + "extension_no_file_config": "未找到文件配置", + "extension_no_output_file": "配置中未指定输出文件", + "extension_execution_timed_out": "执行在 %v 后超时", + "extension_execution_failed_err": "执行失败:%w\nerr:%s", + "extension_failed_read_output_file": "读取输出文件失败:%w", + "extension_failed_get_output_path": "获取输出路径失败:%w\nerr:%s" } diff --git a/internal/plugins/template/extension_executor.go b/internal/plugins/template/extension_executor.go index b0ab51ff..68c71fcf 100644 --- a/internal/plugins/template/extension_executor.go +++ b/internal/plugins/template/extension_executor.go @@ -9,6 +9,8 @@ import ( "path/filepath" "strings" "time" + + "github.com/danielmiessler/fabric/internal/i18n" ) // ExtensionExecutor handles the secure execution of extensions @@ -34,19 +36,19 @@ func (e *ExtensionExecutor) Execute(name, operation, value string) (string, erro // Get and verify extension from registry ext, err := e.registry.GetExtension(name) if err != nil { - return "", fmt.Errorf("failed to get extension: %w", err) + return "", fmt.Errorf(i18n.T("extension_failed_get_extension"), err) } // Format the command using our template system cmdStr, err := e.formatCommand(ext, operation, value) if err != nil { - return "", fmt.Errorf("failed to format command: %w", err) + return "", fmt.Errorf(i18n.T("extension_failed_format_command"), err) } // Split the command string into command and arguments cmdParts := strings.Fields(cmdStr) if len(cmdParts) < 1 { - return "", fmt.Errorf("empty command after formatting") + return "", fmt.Errorf("%s", i18n.T("extension_empty_command")) } // Create command with the Executable and formatted arguments @@ -72,7 +74,7 @@ func (e *ExtensionExecutor) formatCommand(ext *ExtensionDefinition, operation st // Get operation config opConfig, exists := ext.Operations[operation] if !exists { - return "", fmt.Errorf("operation %s not found for extension %s", operation, ext.Name) + return "", fmt.Errorf("%s", fmt.Sprintf(i18n.T("extension_operation_not_found"), operation, ext.Name)) } vars := make(map[string]string) @@ -97,10 +99,10 @@ func (e *ExtensionExecutor) executeStdout(cmd *exec.Cmd, ext *ExtensionDefinitio cmd.Stderr = &stderr //debug output - fmt.Printf("Executing command: %s\n", cmd.String()) + fmt.Printf(i18n.T("extension_executing_command"), cmd.String()) if err := cmd.Run(); err != nil { - return "", fmt.Errorf("execution failed: %w\nstderr: %s", err, stderr.String()) + return "", fmt.Errorf(i18n.T("extension_execution_failed_stderr"), err, stderr.String()) } return stdout.String(), nil @@ -111,7 +113,7 @@ func (e *ExtensionExecutor) executeWithFile(cmd *exec.Cmd, ext *ExtensionDefinit // Parse timeout - this is now a first-class field timeout, err := time.ParseDuration(ext.Timeout) if err != nil { - return "", fmt.Errorf("invalid timeout format: %w", err) + return "", fmt.Errorf(i18n.T("extension_invalid_timeout_format"), err) } // Create context with timeout @@ -126,7 +128,7 @@ func (e *ExtensionExecutor) executeWithFile(cmd *exec.Cmd, ext *ExtensionDefinit fileConfig := ext.GetFileConfig() if fileConfig == nil { - return "", fmt.Errorf("no file configuration found") + return "", fmt.Errorf("%s", i18n.T("extension_no_file_config")) } // Handle path from stdout case @@ -139,7 +141,7 @@ func (e *ExtensionExecutor) executeWithFile(cmd *exec.Cmd, ext *ExtensionDefinit outputFile, _ := fileConfig["output_file"].(string) if outputFile == "" { - return "", fmt.Errorf("no output file specified in configuration") + return "", fmt.Errorf("%s", i18n.T("extension_no_output_file")) } // Set working directory if specified @@ -152,9 +154,9 @@ func (e *ExtensionExecutor) executeWithFile(cmd *exec.Cmd, ext *ExtensionDefinit if err := cmd.Run(); err != nil { if ctx.Err() == context.DeadlineExceeded { - return "", fmt.Errorf("execution timed out after %v", timeout) + return "", fmt.Errorf("%s", fmt.Sprintf(i18n.T("extension_execution_timed_out"), timeout)) } - return "", fmt.Errorf("execution failed: %w\nerr: %s", err, stderr.String()) + return "", fmt.Errorf(i18n.T("extension_execution_failed_err"), err, stderr.String()) } // Construct full file path @@ -165,7 +167,7 @@ func (e *ExtensionExecutor) executeWithFile(cmd *exec.Cmd, ext *ExtensionDefinit content, err := os.ReadFile(outputPath) if err != nil { - return "", fmt.Errorf("failed to read output file: %w", err) + return "", fmt.Errorf(i18n.T("extension_failed_read_output_file"), err) } // Handle cleanup if enabled @@ -183,13 +185,13 @@ func (e *ExtensionExecutor) handlePathFromStdout(cmd *exec.Cmd, ext *ExtensionDe cmd.Stderr = &stderr if err := cmd.Run(); err != nil { - return "", fmt.Errorf("failed to get output path: %w\nerr: %s", err, stderr.String()) + return "", fmt.Errorf(i18n.T("extension_failed_get_output_path"), err, stderr.String()) } outputPath := strings.TrimSpace(stdout.String()) content, err := os.ReadFile(outputPath) if err != nil { - return "", fmt.Errorf("failed to read output file: %w", err) + return "", fmt.Errorf(i18n.T("extension_failed_read_output_file"), err) } if ext.IsCleanupEnabled() {