fix(shell-env): check SHELL before PSModulePath for shell detection

On Windows, PSModulePath is always set by the system even when the
active shell is Git Bash (via SHELL env var). This caused the
non-interactive-env hook to generate PowerShell syntax ($env:VAR=val)
for bash shells, resulting in 15+ errors per command.

The fix prioritizes SHELL over PSModulePath since an explicit SHELL
variable indicates the user's chosen shell, while PSModulePath is just
a system-wide module path that doesn't indicate the active shell.

Fixes: #3338
This commit is contained in:
Qiiks
2026-04-11 16:06:42 +05:30
parent 044e1f5ab9
commit f5a95203a4
2 changed files with 24 additions and 9 deletions
+14 -3
View File
@@ -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")
})
})
+10 -6
View File
@@ -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"
}