Bug: pkg/internal/cli/env lacks Cygwin/MSYS2 support and violates NO_COLOR spec
What happened:
While auditing the CLI terminal detection logic in pkg/internal/cli/env/env.go, I noticed two edge-case issues in how terminal state is calculated:
Missing Git Bash / MSYS2 / Cygwin support on Windows
IsTerminalcurrently only checks:isatty.IsTerminal(v.Fd())Windows MSYS/Cygwin environments, including Git Bash, may use pipes rather than native Windows console APIs. Because of this,
isatty.IsTerminal()can returnfalse, causing KIND to unnecessarily fall back to dumb-terminal behavior.The underlying
go-isattydependency already supports detecting these environments throughisatty.IsCygwinTerminal().Incorrect handling of an empty
NO_COLORvalueIsSmartTerminalcurrently disables ANSI output wheneverNO_COLORis present:if _, set := lookupEnv("NO_COLOR"); set { return false }However, the official
NO_COLORstandard linked in the source states thatNO_COLORshould only disable color when it is present and not an empty string.As a result:
NO_COLOR="" kind get clusterscurrently disables smart-terminal features, even though an empty
NO_COLORvalue should preserve normal color behavior.The existing table-driven test in
env_test.goalso currently enforces this incorrect behavior:Name: "tty, NO_COLOR=", FakeEnv: map[string]string{"NO_COLOR": ""}, IsSmart: false
What you expected to happen:
Users running KIND inside Git Bash, MSYS2, or Cygwin environments on Windows should receive normal smart-terminal functionality, including colors and spinners where supported.
Setting
NO_COLORto an empty string should not disable ANSI output or smart-terminal features:NO_COLOR="" kind <command>This should behave the same as
NO_COLORbeing unset, in accordance with theNO_COLORstandard.
How to reproduce it (as minimally and precisely as possible):
Bug 1 — Git Bash / MSYS terminal detection:
- Open Git Bash on Windows.
- Run any KIND command.
- Observe that KIND may detect the environment as a non-terminal and fall back to dumb-terminal behavior.
Bug 2 — Empty NO_COLOR:
Run the following in a normal Linux/macOS terminal:
NO_COLOR="" kind get clustersExpected: smart-terminal features and ANSI colors remain enabled.
Actual: ANSI output is disabled because NO_COLOR is detected as present, despite having an empty value.
Alternatively, this can be seen directly in the existing env_test.go test case:
Name: "tty, NO_COLOR=",
FakeEnv: map[string]string{"NO_COLOR": ""},
IsSmart: falseAnything else we need to know?:
The fixes appear to be straightforward.
For IsTerminal, the existing go-isatty support for Cygwin/MSYS terminals could be used:
if v, ok := w.(*os.File); ok {
return isatty.IsTerminal(v.Fd()) || isatty.IsCygwinTerminal(v.Fd())
}For IsSmartTerminal, NO_COLOR should only disable smart-terminal functionality when its value is non-empty:
if val, set := lookupEnv("NO_COLOR"); set && val != "" {
return false
}I would also update the corresponding table-driven tests in env_test.go to validate both behaviors.
If the issue are valid then I would like to open a PR implementing these changes if the maintainers agree with the approach.
Environment:
- kind version:
v0.24.0/ latestmainbranch at commite7f2238 - Runtime info: N/A — this is a CLI terminal-detection issue
- OS: Bug 1 affects Windows MSYS2/Cygwin environments such as Git Bash; Bug 2 affects all platforms
- Kubernetes version: N/A
- Any proxies or other special environment settings?: MSYS2/Cygwin (Git Bash) for Bug 1
Source: kubernetes-sigs/kind