|
| 1 | +package cmdio |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "io" |
| 6 | + "strings" |
| 7 | + |
| 8 | + "github.com/databricks/cli/libs/env" |
| 9 | +) |
| 10 | + |
| 11 | +// Capabilities represents terminal I/O capabilities detected from environment. |
| 12 | +type Capabilities struct { |
| 13 | + // Raw TTY detection results |
| 14 | + stdinIsTTY bool |
| 15 | + stdoutIsTTY bool |
| 16 | + stderrIsTTY bool |
| 17 | + |
| 18 | + // Environment flags |
| 19 | + color bool // Color output is enabled (NO_COLOR not set and TERM not dumb) |
| 20 | + isGitBash bool // Git Bash on Windows |
| 21 | +} |
| 22 | + |
| 23 | +// newCapabilities detects terminal capabilities from context and I/O streams. |
| 24 | +func newCapabilities(ctx context.Context, in io.Reader, out, err io.Writer) Capabilities { |
| 25 | + return Capabilities{ |
| 26 | + stdinIsTTY: isTTY(in), |
| 27 | + stdoutIsTTY: isTTY(out), |
| 28 | + stderrIsTTY: isTTY(err), |
| 29 | + color: env.Get(ctx, "NO_COLOR") == "" && env.Get(ctx, "TERM") != "dumb", |
| 30 | + isGitBash: detectGitBash(ctx), |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +// SupportsInteractive returns true if terminal supports interactive features (colors, spinners). |
| 35 | +func (c Capabilities) SupportsInteractive() bool { |
| 36 | + return c.stderrIsTTY && c.color |
| 37 | +} |
| 38 | + |
| 39 | +// SupportsPrompt returns true if terminal supports user prompting. |
| 40 | +func (c Capabilities) SupportsPrompt() bool { |
| 41 | + return c.SupportsInteractive() && c.stdinIsTTY && c.stdoutIsTTY && !c.isGitBash |
| 42 | +} |
| 43 | + |
| 44 | +// SupportsColor returns true if the given writer supports colored output. |
| 45 | +// This checks both TTY status and environment variables (NO_COLOR, TERM=dumb). |
| 46 | +func (c Capabilities) SupportsColor(w io.Writer) bool { |
| 47 | + return isTTY(w) && c.color |
| 48 | +} |
| 49 | + |
| 50 | +// detectGitBash returns true if running in Git Bash on Windows (has broken promptui support). |
| 51 | +// We do not allow prompting in Git Bash on Windows. |
| 52 | +// Likely due to fact that Git Bash does not correctly support ANSI escape sequences, |
| 53 | +// we cannot use promptui package there. |
| 54 | +// See known issues: |
| 55 | +// - https://github.com/manifoldco/promptui/issues/208 |
| 56 | +// - https://github.com/chzyer/readline/issues/191 |
| 57 | +func detectGitBash(ctx context.Context) bool { |
| 58 | + // Check if the MSYSTEM environment variable is set to "MINGW64" |
| 59 | + msystem := env.Get(ctx, "MSYSTEM") |
| 60 | + if strings.EqualFold(msystem, "MINGW64") { |
| 61 | + // Check for typical Git Bash env variable for prompts |
| 62 | + ps1 := env.Get(ctx, "PS1") |
| 63 | + return strings.Contains(ps1, "MINGW") || strings.Contains(ps1, "MSYSTEM") |
| 64 | + } |
| 65 | + |
| 66 | + return false |
| 67 | +} |
0 commit comments