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:
@@ -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
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user