Skip to content

Commit 657c184

Browse files
committed
Detect Git Bash shells on Windows
1 parent 06f98ca commit 657c184

File tree

2 files changed

+61
-46
lines changed

2 files changed

+61
-46
lines changed

src/utils/__tests__/shell.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// npx jest src/utils/__tests__/shell.test.ts
2+
13
import * as vscode from "vscode"
24
import { userInfo } from "os"
35
import { getShell } from "../shell"
@@ -90,6 +92,20 @@ describe("Shell Detection Tests", () => {
9092
expect(getShell()).toBe("/bin/bash")
9193
})
9294

95+
it("uses Git Bash when profile indicates Git Bash source", () => {
96+
mockVsCodeConfig("windows", "Git Bash", {
97+
"Git Bash": { source: "Git Bash" },
98+
})
99+
expect(getShell()).toBe("/usr/bin/bash")
100+
})
101+
102+
it("uses Git Bash when profile name includes 'git bash'", () => {
103+
mockVsCodeConfig("windows", "MinGW Git Bash", {
104+
"MinGW Git Bash": {},
105+
})
106+
expect(getShell()).toBe("/usr/bin/bash")
107+
})
108+
93109
it("defaults to cmd.exe if no special profile is matched", () => {
94110
mockVsCodeConfig("windows", "CommandPrompt", {
95111
CommandPrompt: {},

src/utils/shell.ts

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const SHELL_PATHS = {
77
POWERSHELL_LEGACY: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
88
CMD: "C:\\Windows\\System32\\cmd.exe",
99
WSL_BASH: "/bin/bash",
10+
GIT_BASH: "/usr/bin/bash",
1011
// Unix paths
1112
MAC_DEFAULT: "/bin/zsh",
1213
LINUX_DEFAULT: "/bin/bash",
@@ -28,7 +29,7 @@ type MacTerminalProfiles = Record<string, MacTerminalProfile>
2829

2930
interface WindowsTerminalProfile {
3031
path?: string
31-
source?: "PowerShell" | "WSL"
32+
source?: "PowerShell" | "WSL" | "Git Bash"
3233
}
3334

3435
type WindowsTerminalProfiles = Record<string, WindowsTerminalProfile>
@@ -48,6 +49,9 @@ function getWindowsTerminalConfig() {
4849
const config = vscode.workspace.getConfiguration("terminal.integrated")
4950
const defaultProfileName = config.get<string>("defaultProfile.windows")
5051
const profiles = config.get<WindowsTerminalProfiles>("profiles.windows") || {}
52+
console.log(`getWindowsTerminalConfig.defaultProfileName = ${defaultProfileName}`)
53+
console.log(profiles["Git Bash"])
54+
console.log(process.env)
5155
return { defaultProfileName, profiles }
5256
} catch {
5357
return { defaultProfileName: null, profiles: {} as WindowsTerminalProfiles }
@@ -114,6 +118,10 @@ function getWindowsShellFromVSCode(): string | null {
114118
return SHELL_PATHS.WSL_BASH
115119
}
116120

121+
if (profile?.source === "Git Bash" || defaultProfileName.toLowerCase().includes("git bash")) {
122+
return SHELL_PATHS.GIT_BASH
123+
}
124+
117125
// If nothing special detected, we assume cmd
118126
return SHELL_PATHS.CMD
119127
}
@@ -162,66 +170,57 @@ function getShellFromEnv(): string | null {
162170
const { env } = process
163171

164172
if (process.platform === "win32") {
165-
// On Windows, COMSPEC typically holds cmd.exe
166-
return env.COMSPEC || "C:\\Windows\\System32\\cmd.exe"
173+
// On Windows, COMSPEC typically holds cmd.exe.
174+
return env.SHELL || env.COMSPEC || "C:\\Windows\\System32\\cmd.exe"
167175
}
168176

169177
if (process.platform === "darwin") {
170-
// On macOS/Linux, SHELL is commonly the environment variable
178+
// On macOS/Linux, SHELL is commonly the environment variable.
171179
return env.SHELL || "/bin/zsh"
172180
}
173181

174182
if (process.platform === "linux") {
175-
// On Linux, SHELL is commonly the environment variable
183+
// On Linux, SHELL is commonly the environment variable.
176184
return env.SHELL || "/bin/bash"
177185
}
186+
178187
return null
179188
}
180189

181-
// -----------------------------------------------------
182-
// 4) Publicly Exposed Shell Getter
183-
// -----------------------------------------------------
184-
185-
export function getShell(): string {
186-
// 1. Check VS Code config first.
190+
function fallbackShell() {
191+
// On Windows, if we got here, we have no config, no COMSPEC, and one
192+
// very messed up operating system. Use CMD as a last resort.
187193
if (process.platform === "win32") {
188-
// Special logic for Windows
189-
const windowsShell = getWindowsShellFromVSCode()
190-
if (windowsShell) {
191-
return windowsShell
192-
}
193-
} else if (process.platform === "darwin") {
194-
// macOS from VS Code
195-
const macShell = getMacShellFromVSCode()
196-
if (macShell) {
197-
return macShell
198-
}
199-
} else if (process.platform === "linux") {
200-
// Linux from VS Code
201-
const linuxShell = getLinuxShellFromVSCode()
202-
if (linuxShell) {
203-
return linuxShell
204-
}
194+
return SHELL_PATHS.CMD
205195
}
206196

207-
// 2. If no shell from VS Code, try userInfo()
208-
const userInfoShell = getShellFromUserInfo()
209-
if (userInfoShell) {
210-
return userInfoShell
211-
}
197+
// On macOS/Linux, fallback to a POSIX shell - This is the behavior of our
198+
// old shell detection method.
199+
return SHELL_PATHS.FALLBACK
200+
}
212201

213-
// 3. If still nothing, try environment variable
214-
const envShell = getShellFromEnv()
215-
if (envShell) {
216-
return envShell
217-
}
202+
// -----------------------------------------------------
203+
// 4) Publicly Exposed Shell Getter
204+
// -----------------------------------------------------
218205

219-
// 4. Finally, fall back to a default
220-
if (process.platform === "win32") {
221-
// On Windows, if we got here, we have no config, no COMSPEC, and one very messed up operating system.
222-
// Use CMD as a last resort
223-
return SHELL_PATHS.CMD
224-
}
225-
// On macOS/Linux, fallback to a POSIX shell - This is the behavior of our old shell detection method.
226-
return SHELL_PATHS.FALLBACK
206+
export function getShell() {
207+
// 1. Check VS Code config first.
208+
// 2. If no shell from VS Code, try userInfo().
209+
// 3. If still nothing, try environment variable.
210+
// 4. Finally, fall back to a default.
211+
let vsCodeShell: string | null = null
212+
213+
switch (process.platform) {
214+
case "win32":
215+
vsCodeShell = getWindowsShellFromVSCode()
216+
break
217+
case "darwin":
218+
vsCodeShell = getMacShellFromVSCode()
219+
break
220+
case "linux":
221+
vsCodeShell = getLinuxShellFromVSCode()
222+
break
223+
}
224+
225+
return vsCodeShell || getShellFromUserInfo() || getShellFromEnv() || fallbackShell()
227226
}

0 commit comments

Comments
 (0)