diff --git a/src/shared/shell-env.test.ts b/src/shared/shell-env.test.ts index c0e53306f..60a4aaba4 100644 --- a/src/shared/shell-env.test.ts +++ b/src/shared/shell-env.test.ts @@ -45,7 +45,8 @@ describe("shell-env", () => { expect(result).toBe("unix") }) - test("#given PSModulePath is set #when detectShellType is called #then returns powershell", () => { + test("#given PSModulePath is set without SHELL #when detectShellType is called #then returns powershell", () => { + delete process.env.SHELL process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules" Object.defineProperty(process, "platform", { value: "win32" }) @@ -74,14 +75,24 @@ describe("shell-env", () => { expect(result).toBe("unix") }) - test("#given PSModulePath takes priority over SHELL #when both are set #then returns powershell", () => { + test("#given SHELL takes priority over PSModulePath #when both are set #then returns unix", () => { process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules" process.env.SHELL = "/bin/bash" Object.defineProperty(process, "platform", { value: "win32" }) const result = detectShellType() - expect(result).toBe("powershell") + expect(result).toBe("unix") + }) + + test("#given SHELL set to Git Bash on Windows with PSModulePath #when detectShellType is called #then returns unix", () => { + process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules" + process.env.SHELL = "C:\\Program Files\\Git\\bin\\bash.exe" + Object.defineProperty(process, "platform", { value: "win32" }) + + const result = detectShellType() + + expect(result).toBe("unix") }) }) diff --git a/src/shared/shell-env.ts b/src/shared/shell-env.ts index 2ffa59ac2..d34ee3254 100644 --- a/src/shared/shell-env.ts +++ b/src/shared/shell-env.ts @@ -4,15 +4,15 @@ export type ShellType = "unix" | "powershell" | "cmd" | "csh" * Detect the current shell type based on environment variables. * * Detection priority: - * 1. PSModulePath → PowerShell - * 2. SHELL env var → Unix shell + * 1. SHELL env var → Unix shell (explicit user choice takes precedence) + * 2. PSModulePath → PowerShell * 3. Platform fallback → win32: cmd, others: unix + * + * Note: SHELL is checked before PSModulePath because on Windows, PSModulePath + * is always set by the system even when the active shell is Git Bash or WSL. + * An explicit SHELL variable indicates the user's chosen shell overrides that. */ export function detectShellType(): ShellType { - if (process.env.PSModulePath) { - return "powershell" - } - if (process.env.SHELL) { const shell = process.env.SHELL if (shell.includes("csh") || shell.includes("tcsh")) { @@ -21,6 +21,10 @@ export function detectShellType(): ShellType { return "unix" } + if (process.env.PSModulePath) { + return "powershell" + } + return process.platform === "win32" ? "cmd" : "unix" }