fix: more reliably detect windows drive (#2273)

Andrey Nering created

Change summary

internal/agent/tools/bash.go    |  9 ++-------
internal/fsext/drive_other.go   | 16 ++++++++++++++++
internal/fsext/drive_windows.go | 26 ++++++++++++++++++++++++++
3 files changed, 44 insertions(+), 7 deletions(-)

Detailed changes

internal/agent/tools/bash.go 🔗

@@ -7,7 +7,6 @@ import (
 	_ "embed"
 	"fmt"
 	"html/template"
-	"os"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -15,6 +14,7 @@ import (
 
 	"charm.land/fantasy"
 	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/fsext"
 	"github.com/charmbracelet/crush/internal/permission"
 	"github.com/charmbracelet/crush/internal/shell"
 )
@@ -431,12 +431,7 @@ func countLines(s string) int {
 
 func normalizeWorkingDir(path string) string {
 	if runtime.GOOS == "windows" {
-		cwd, err := os.Getwd()
-		if err != nil {
-			cwd = "C:"
-		}
-		path = strings.ReplaceAll(path, filepath.VolumeName(cwd), "")
+		path = strings.ReplaceAll(path, fsext.WindowsWorkingDirDrive(), "")
 	}
-
 	return filepath.ToSlash(path)
 }

internal/fsext/drive_other.go 🔗

@@ -0,0 +1,16 @@
+//go:build !windows
+
+package fsext
+
+// WindowsWorkingDirDrive returns the drive letter of the current working
+// directory, e.g. "C:".
+// Falls back to the system drive if the current working directory cannot be
+// determined.
+func WindowsWorkingDirDrive() string {
+	panic("cannot call fsext.WindowsWorkingDirDrive() on non-Windows OS")
+}
+
+// WindowsSystemDrive returns the drive letter of the system drive, e.g. "C:".
+func WindowsSystemDrive() string {
+	panic("cannot call fsext.WindowsSystemDrive() on non-Windows OS")
+}

internal/fsext/drive_windows.go 🔗

@@ -0,0 +1,26 @@
+//go:build windows
+
+package fsext
+
+import (
+	"cmp"
+	"os"
+	"path/filepath"
+)
+
+// WindowsWorkingDirDrive returns the drive letter of the current working
+// directory, e.g. "C:".
+// Falls back to the system drive if the current working directory cannot be
+// determined.
+func WindowsWorkingDirDrive() string {
+	if cwd, err := os.Getwd(); err == nil {
+		return filepath.VolumeName(cwd)
+	}
+	return WindowsSystemDrive()
+}
+
+// WindowsSystemDrive returns the drive letter of the system drive, e.g. "C:".
+func WindowsSystemDrive() string {
+	systemRoot := cmp.Or(os.Getenv("SYSTEMROOT"), os.Getenv("WINDIR"))
+	return filepath.VolumeName(systemRoot)
+}