(
params: {
platform?: NodeJS.Platform;
env?: NodeJS.ProcessEnv;
execSyncFn?: (command: string, options: ExecSyncOptionsWithStringEncoding) => string;
existsSyncFn?: (path: string) => boolean;
nowFn?: () => number;
} = {}
)
| 229 | * @throws Error if Git Bash cannot be found on Windows |
| 230 | */ |
| 231 | export function getBashPath( |
| 232 | params: { |
| 233 | platform?: NodeJS.Platform; |
| 234 | env?: NodeJS.ProcessEnv; |
| 235 | execSyncFn?: (command: string, options: ExecSyncOptionsWithStringEncoding) => string; |
| 236 | existsSyncFn?: (path: string) => boolean; |
| 237 | nowFn?: () => number; |
| 238 | } = {} |
| 239 | ): string { |
| 240 | const platform = params.platform ?? process.platform; |
| 241 | |
| 242 | // On Unix/Linux/macOS, bash is in PATH |
| 243 | if (platform !== "win32") { |
| 244 | return "bash"; |
| 245 | } |
| 246 | |
| 247 | // Use cached path if available |
| 248 | if (cachedBashPath !== null) { |
| 249 | return cachedBashPath; |
| 250 | } |
| 251 | |
| 252 | const nowFn = params.nowFn ?? Date.now; |
| 253 | const now = nowFn(); |
| 254 | if ( |
| 255 | cachedBashPathError && |
| 256 | now - cachedBashPathError.lastCheckedMs < BASH_PATH_ERROR_COOLDOWN_MS |
| 257 | ) { |
| 258 | throw new Error(cachedBashPathError.message); |
| 259 | } |
| 260 | |
| 261 | try { |
| 262 | cachedBashPath = getBashPathForPlatform({ |
| 263 | platform, |
| 264 | env: params.env, |
| 265 | execSyncFn: params.execSyncFn, |
| 266 | existsSyncFn: params.existsSyncFn, |
| 267 | }); |
| 268 | cachedBashPathError = null; |
| 269 | return cachedBashPath; |
| 270 | } catch (error) { |
| 271 | const message = getErrorMessage(error); |
| 272 | cachedBashPathError = { message, lastCheckedMs: now }; |
| 273 | throw error; |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | /** Reset cached bash path (used by tests). */ |
| 278 | export function resetBashPathCache(): void { |
no test coverage detected