0d9e5e1344
* fix: route air's own log messages to stderr instead of stdout Air's internal loggers (main, build, runner, watcher) were writing to stdout, causing air's messages to intermix with the user's application output. This made it impossible to separate them with shell redirections like `air 2>/dev/null`. Change the log output destination from os.Stdout/color.Output to os.Stderr/color.Error so air's messages go to stderr while the user's app output remains on stdout. Also remove dead `c.Stdout` and `c.Stderr` assignments in startCmd() on all platforms — these had no effect after StdoutPipe()/StderrPipe() were already called. Fixes #744 Signed-off-by: majiayu000 <1835304752@qq.com> * test: add regression test for logger stderr routing Signed-off-by: majiayu000 <1835304752@qq.com> * fix: route warning messages in config.go to stderr Signed-off-by: majiayu000 <1835304752@qq.com> * fix: update smoke test to check stderr for air log messages Since air's log output now goes to stderr, the smoke test must check nohup.err instead of nohup.out for the "running" message. Signed-off-by: majiayu000 <1835304752@qq.com> * fix: print splash banner to stderr --------- Signed-off-by: majiayu000 <1835304752@qq.com> Co-authored-by: xiantang <zhujingdi1998@gmail.com>
53 lines
1.1 KiB
Go
53 lines
1.1 KiB
Go
package runner
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestLogFuncWritesToStderr(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Capture stderr
|
|
oldStderr := os.Stderr
|
|
rErr, wErr, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("failed to create stderr pipe: %v", err)
|
|
}
|
|
os.Stderr = wErr
|
|
|
|
// Capture stdout
|
|
oldStdout := os.Stdout
|
|
rOut, wOut, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("failed to create stdout pipe: %v", err)
|
|
}
|
|
os.Stdout = wOut
|
|
|
|
logFn := newLogFunc(rawColor, cfgLog{})
|
|
logFn("test message from air")
|
|
|
|
wErr.Close()
|
|
wOut.Close()
|
|
os.Stderr = oldStderr
|
|
os.Stdout = oldStdout
|
|
|
|
stderrOut, err := io.ReadAll(rErr)
|
|
if err != nil {
|
|
t.Fatalf("failed to read stderr: %v", err)
|
|
}
|
|
stdoutOut, err := io.ReadAll(rOut)
|
|
if err != nil {
|
|
t.Fatalf("failed to read stdout: %v", err)
|
|
}
|
|
|
|
if !strings.Contains(string(stderrOut), "test message from air") {
|
|
t.Errorf("expected log output on stderr, got: %q", stderrOut)
|
|
}
|
|
if strings.Contains(string(stdoutOut), "test message from air") {
|
|
t.Errorf("log output should not appear on stdout, got: %q", stdoutOut)
|
|
}
|
|
}
|