From 34f1ff0595e09fe64d8f81c26463e2bdfff9a697 Mon Sep 17 00:00:00 2001 From: Dylan Ravel Date: Fri, 27 Mar 2026 21:27:48 -0700 Subject: [PATCH] Avoid printing newlines on legacy Windows CMD --- cmd/utilities/version.go | 9 +++--- internal/shell/shell.go | 17 ++++++++++ internal/shell/shell_test.go | 60 ++++++++++++++++++++++++++++++++++++ internal/ui/ui.go | 6 +++- 4 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 internal/shell/shell.go create mode 100644 internal/shell/shell_test.go diff --git a/cmd/utilities/version.go b/cmd/utilities/version.go index b60aba6..da680b1 100644 --- a/cmd/utilities/version.go +++ b/cmd/utilities/version.go @@ -34,14 +34,15 @@ func VersionCmd() *cobra.Command { } func DisplayVersionWithUpdateCheck() { - fmt.Print(GetVersionOutput()) + fmt.Println(GetVersionOutput()) checkForUpdates() + ui.NewlineBelow() } func GetVersionOutput() string { versionLine := fmt.Sprintf("tmpo version %s %s", ui.Success(Version), ui.Muted(GetFormattedDate(Date))) changelogLine := ui.Muted(GetChangelogUrl(Version)) - return fmt.Sprintf("\n%s\n%s\n\n", versionLine, changelogLine) + return fmt.Sprintf("\n%s\n%s", versionLine, changelogLine) } func GetFormattedDate(inputDate string) string { @@ -76,8 +77,8 @@ func checkForUpdates() { } if updateInfo.HasUpdate { - fmt.Printf("%s %s\n", ui.Info("New Update Available:"), ui.Bold(strings.TrimPrefix(updateInfo.LatestVersion, "v"))) - fmt.Printf("%s\n\n", ui.Muted(updateInfo.UpdateURL)) + fmt.Printf("\n%s %s\n", ui.Info("New Update Available:"), ui.Bold(strings.TrimPrefix(updateInfo.LatestVersion, "v"))) + fmt.Printf("%s", ui.Muted(updateInfo.UpdateURL)) } } diff --git a/internal/shell/shell.go b/internal/shell/shell.go new file mode 100644 index 0000000..53f3ecd --- /dev/null +++ b/internal/shell/shell.go @@ -0,0 +1,17 @@ +package shell + +import ( + "os" + "runtime" +) + +func IsLegacyWindowsCMD() bool { + if runtime.GOOS != "windows" { + return false + } + + isCMD := os.Getenv("PROMPT") != "" + isUnixLike := os.Getenv("TERM") != "" + + return isCMD && !isUnixLike +} diff --git a/internal/shell/shell_test.go b/internal/shell/shell_test.go new file mode 100644 index 0000000..0c3ede8 --- /dev/null +++ b/internal/shell/shell_test.go @@ -0,0 +1,60 @@ +package shell + +import ( + "runtime" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsLegacyWindowsCMD(t *testing.T) { + if runtime.GOOS != "windows" { + t.Run("returns false on non-Windows platforms", func(t *testing.T) { + result := IsLegacyWindowsCMD() + assert.False(t, result) + }) + return + } + + tests := []struct { + name string + prompt string + term string + expected bool + }{ + { + name: "legacy CMD with PROMPT set and no TERM", + prompt: "$P$G", + term: "", + expected: true, + }, + { + name: "not CMD because PROMPT is not set", + prompt: "", + term: "", + expected: false, + }, + { + name: "Unix-like shell overrides PROMPT", + prompt: "$P$G", + term: "xterm-256color", + expected: false, + }, + { + name: "neither PROMPT nor TERM set", + prompt: "", + term: "xterm-256color", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Setenv("PROMPT", tt.prompt) + t.Setenv("TERM", tt.term) + + result := IsLegacyWindowsCMD() + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/internal/ui/ui.go b/internal/ui/ui.go index e10b9d0..ccbbd3e 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -4,6 +4,8 @@ import ( "fmt" "os" "time" + + "github.com/DylanDevelops/tmpo/internal/shell" ) // ANSI Color Constants @@ -141,7 +143,9 @@ func NewlineAbove() { } func NewlineBelow() { - fmt.Println() + if !shell.IsLegacyWindowsCMD() { + fmt.Println() + } } func FormatDuration(d time.Duration) string {