a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
package progress
|
|
|
|
import (
|
|
"os"
|
|
"runtime"
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
)
|
|
|
|
// glyphSet is the small set of display glyphs that differ between a UTF-8
|
|
// terminal and a legacy OEM / ASCII one: the success / failure markers, the
|
|
// status dot, the mid-dot separator, and the box-drawing charset. Gortex
|
|
// renders more box-drawing than a check/cross-only CLI (the rounded card
|
|
// border), so the ASCII fallback has to cover the whole border too. The
|
|
// live tracker adds the progress-bar cells, the pending marker, and the
|
|
// busy / ready status dots to the same fallback contract.
|
|
type glyphSet struct {
|
|
OK string
|
|
Fail string
|
|
Dot string
|
|
DotDim string
|
|
Pending string
|
|
Sep string
|
|
Dash string
|
|
Ellipsis string
|
|
BarFull string
|
|
BarEmpty string
|
|
StatusBusy string
|
|
StatusReady string
|
|
Border lipgloss.Border
|
|
}
|
|
|
|
var (
|
|
unicodeGlyphs = glyphSet{
|
|
OK: "✓",
|
|
Fail: "✗",
|
|
Dot: "●",
|
|
DotDim: "●",
|
|
Pending: "·",
|
|
Sep: "·",
|
|
Dash: "—",
|
|
Ellipsis: "…",
|
|
BarFull: "█",
|
|
BarEmpty: "░",
|
|
StatusBusy: "◐",
|
|
StatusReady: "●",
|
|
Border: lipgloss.RoundedBorder(),
|
|
}
|
|
asciiGlyphs = glyphSet{
|
|
OK: "+",
|
|
Fail: "x",
|
|
Dot: "*",
|
|
DotDim: "o",
|
|
Pending: ".",
|
|
Sep: "-",
|
|
Dash: "-",
|
|
Ellipsis: "...",
|
|
BarFull: "#",
|
|
BarEmpty: "-",
|
|
StatusBusy: "o",
|
|
StatusReady: "*",
|
|
Border: lipgloss.ASCIIBorder(),
|
|
}
|
|
|
|
brailleSpin = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
|
|
asciiSpin = []string{"|", "/", "-", "\\"}
|
|
)
|
|
|
|
// activeGlyphs returns the glyph set appropriate to the current terminal:
|
|
// UTF-8 box-drawing / check glyphs when it can render them, ASCII otherwise.
|
|
// Resolved per call so a runtime override (or a test) takes effect immediately;
|
|
// the cost is a couple of env reads plus, on Windows only, one cheap codepage
|
|
// syscall.
|
|
func activeGlyphs() glyphSet {
|
|
if supportsUnicode() {
|
|
return unicodeGlyphs
|
|
}
|
|
return asciiGlyphs
|
|
}
|
|
|
|
// spinFrames returns the animated-spinner frame cycle. Braille frames need
|
|
// font coverage that the check / box-drawing glyphs don't: legacy conhost
|
|
// fonts (Consolas on a CP65001 console) render ✓ and █ but draw braille as
|
|
// boxes, so on Windows the braille cycle is reserved for terminals that
|
|
// declare themselves modern (Windows Terminal, ConEmu, an inherited TERM).
|
|
// Everything else animates with the four-frame ASCII cycle.
|
|
func spinFrames() []string {
|
|
if !supportsUnicode() {
|
|
return asciiSpin
|
|
}
|
|
if runtime.GOOS == "windows" && !windowsModernTerminal() {
|
|
return asciiSpin
|
|
}
|
|
return brailleSpin
|
|
}
|
|
|
|
// windowsModernTerminal reports whether the process runs under a Windows
|
|
// terminal with full glyph coverage: Windows Terminal (WT_SESSION), ConEmu
|
|
// (ConEmuANSI=ON), or an environment that carries a unix-style TERM (mintty,
|
|
// msys, ssh sessions).
|
|
func windowsModernTerminal() bool {
|
|
if os.Getenv("WT_SESSION") != "" {
|
|
return true
|
|
}
|
|
if os.Getenv("ConEmuANSI") == "ON" {
|
|
return true
|
|
}
|
|
return os.Getenv("TERM") != ""
|
|
}
|
|
|
|
// supportsUnicode reports whether the active terminal can render the UTF-8
|
|
// box-drawing / check glyphs. Explicit env overrides win (GORTEX_ASCII opt-out,
|
|
// GORTEX_UNICODE opt-in); a linux virtual console (TERM=linux, CP437-ish) and a
|
|
// non-UTF-8 Windows console codepage both fall back to ASCII. Every other
|
|
// terminal is assumed UTF-8-capable, the modern default.
|
|
func supportsUnicode() bool {
|
|
if envFlag("GORTEX_ASCII") {
|
|
return false
|
|
}
|
|
if envFlag("GORTEX_UNICODE") {
|
|
return true
|
|
}
|
|
if os.Getenv("TERM") == "linux" {
|
|
return false
|
|
}
|
|
if runtime.GOOS == "windows" {
|
|
return windowsConsoleUTF8()
|
|
}
|
|
return true
|
|
}
|
|
|
|
// envFlag reports whether the named env var is set to a truthy value.
|
|
func envFlag(name string) bool {
|
|
switch os.Getenv(name) {
|
|
case "1", "true", "TRUE", "yes", "on":
|
|
return true
|
|
}
|
|
return false
|
|
}
|