runner: hide PowerShell window + filter PS error noise from log
All checks were successful
release / build-and-release (push) Successful in 25s
All checks were successful
release / build-and-release (push) Successful in 25s
- HideWindow: true in SysProcAttr (Windows) prevents powershell.exe from opening a console window over the GUI - skipPSNoiseLine filters multi-line PS error blocks (At line:, CategoryInfo, FullyQualifiedErrorId, VERBOSE: etc.) - errors still appear via Write-Log Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d06af1a87f
commit
66dfdbf44c
3 changed files with 52 additions and 0 deletions
7
internal/runner/hidecmd_other.go
Normal file
7
internal/runner/hidecmd_other.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package runner
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
|
||||||
|
func hideWindow(cmd *exec.Cmd) {}
|
||||||
14
internal/runner/hidecmd_windows.go
Normal file
14
internal/runner/hidecmd_windows.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package runner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hideWindow prevents the child process from creating a visible console window.
|
||||||
|
// Without this, powershell.exe opens a full-size window on top of the GUI.
|
||||||
|
func hideWindow(cmd *exec.Cmd) {
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||||
|
}
|
||||||
|
|
@ -223,6 +223,7 @@ func (r *Runner) runScript(ctx context.Context, step Step, cfgArg string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, "powershell.exe", args...)
|
cmd := exec.CommandContext(ctx, "powershell.exe", args...)
|
||||||
|
hideWindow(cmd) // prevent PS console window from appearing over the GUI
|
||||||
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -237,6 +238,9 @@ func (r *Runner) runScript(ctx context.Context, step Step, cfgArg string) error
|
||||||
scanner := bufio.NewScanner(stdout)
|
scanner := bufio.NewScanner(stdout)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
if skipPSNoiseLine(line) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
r.onLog(LogLine{
|
r.onLog(LogLine{
|
||||||
StepID: step.ID,
|
StepID: step.ID,
|
||||||
Text: line,
|
Text: line,
|
||||||
|
|
@ -247,6 +251,33 @@ func (r *Runner) runScript(ctx context.Context, step Step, cfgArg string) error
|
||||||
return cmd.Wait()
|
return cmd.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skipPSNoiseLine returns true for PowerShell stderr noise that clutters the log:
|
||||||
|
// multi-line error blocks (At line:N, CategoryInfo, FullyQualifiedErrorId, etc.),
|
||||||
|
// blank lines, and VERBOSE: prefix lines already handled by Write-Log.
|
||||||
|
func skipPSNoiseLine(line string) bool {
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
if trimmed == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, prefix := range []string{
|
||||||
|
"At line:",
|
||||||
|
"+ CategoryInfo",
|
||||||
|
"+ FullyQualifiedErrorId",
|
||||||
|
"+ PositionMessage",
|
||||||
|
"VERBOSE:",
|
||||||
|
"DEBUG:",
|
||||||
|
} {
|
||||||
|
if strings.HasPrefix(trimmed, prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PS error continuation lines start with spaces + "+" or "~"
|
||||||
|
if len(trimmed) > 0 && (trimmed[0] == '+' || strings.HasPrefix(trimmed, "~")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// parseLevel extracts the log level from lines formatted as "[HH:mm:ss] [LEVEL] message".
|
// parseLevel extracts the log level from lines formatted as "[HH:mm:ss] [LEVEL] message".
|
||||||
func parseLevel(line string) string {
|
func parseLevel(line string) string {
|
||||||
if strings.Contains(line, "] [OK]") {
|
if strings.Contains(line, "] [OK]") {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue