Add test and fix failures around loading shell environment on Windows#21621
Add test and fix failures around loading shell environment on Windows#21621niik merged 7 commits intodevelopmentfrom
Conversation
Add "cwd": "${workspaceFolder}" and change the test globals and env file to relative paths (./app/test/globals.mts and .test.env). This makes the VSCode test launch configuration more portable and ensures paths resolve correctly when running tests from the integrated terminal while keeping ${relativeFile} for targeting the current test file.
So turns out the Git resolved via PATH might point to the ming64 version which is fine but we need to deal with it. Dealt with that. Second, that unearthed a bug that findGitBashInRegistry returns the path to the git-bash.exe, not bash.exe which we need. Deal with that too
Prevent Node from messing up our perfectly quoted args
This was introduced in #8150 but it's causing our get-shell-env tests to fail because powershell v1 requires USERPROFILE to be set. I don't know what local gitconfig values were being overridden that caused this to be a problem in the first place but I think we should remove these and find out and fix it some other way if it's still a problem
| "--import", | ||
| "tsx", | ||
| "--import", | ||
| "${workspaceFolder}/app/test/globals.mts", |
There was a problem hiding this comment.
The debug current test file script was broken in Windows because absolute pats need to be specified with the file:// scheme and I don't know how to do that so instead I made all paths relative and set the cwd
| cwd?: string, | ||
| shellKind?: SupportedHooksEnvShell | ||
| shellKind?: SupportedHooksEnvShell, | ||
| printenvzPath?: string |
There was a problem hiding this comment.
This just lets us override the path in tests
app/src/lib/hooks/get-shell.ts
Outdated
| let bashPath = null | ||
| if (gitPath.toLowerCase().endsWith('\\cmd\\git.exe')) { | ||
| bashPath = join(gitPath, '../../usr/bin/bash.exe') | ||
| } else if (gitPath.toLowerCase().endsWith('\\mingw64\\bin\\git.exe')) { |
There was a problem hiding this comment.
So on my VM which(git) resolved to the mingw64 path. Don't know why it didn't do that when I was testing this out previously but now we handle that scenario as well
| } else if (gitPath.toLowerCase().endsWith('\\mingw64\\bin\\git.exe')) { | ||
| bashPath = join(gitPath, '../../../usr/bin/bash.exe') | ||
| } else { | ||
| const HKLM = HKEY.HKEY_LOCAL_MACHINE |
There was a problem hiding this comment.
Previously we were using findGitBashInRegisty but that resolves the git-bash.exe which will always launch a window vs bash.exe which is what we want to invoke so I rolled my own here
| COMSPEC && /^(?:.*\\)?cmd(?:\.exe)?$/i.test(COMSPEC) ? COMSPEC : 'cmd.exe' | ||
| const { args, quoteCommand } = cmd | ||
| return { shell, args, quoteCommand } | ||
| return { shell, args, quoteCommand, windowsVerbatimArguments: true } |
There was a problem hiding this comment.
This is the default behavior for node when spawning with shell: true and shell resolving to cmd.exe. We need it here as well or else node will re-quote our already quoted arg
| GIT_COMMITTER_NAME = 'Joe Bloggs' | ||
| GIT_COMMITTER_EMAIL = 'joe.bloggs@somewhere.com' | ||
| TEST_ENV = '1' | ||
| HOME = '' |
There was a problem hiding this comment.
This was introduced in #8150 but it's causing our get-shell-env tests to fail because powershell v1 requires USERPROFILE to be set. I don't know what local gitconfig values were being overridden that caused this to be a problem in the first place but I think we should remove these and find out and fix it some other way if it's still a problem
There was a problem hiding this comment.
Pull request overview
Adds unit coverage for getShellEnv and adjusts Windows shell/env loading behavior to address failures when spawning shells to read environment variables.
Changes:
- Added a unit test validating that
getShellEnvreturns an environment containingPATH. - Updated Windows shell resolution (Git Bash discovery +
cmd.exespawn options) and madegetShellEnvaccept an optionalprintenvzpath for tests. - Tweaked VS Code test debugging configuration and simplified
.test.env.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| app/test/unit/get-shell-env-test.ts | New unit test exercising getShellEnv across shells (Windows) / default shell (non-Windows). |
| app/src/lib/hooks/get-shell.ts | Adjusts Git Bash discovery logic and cmd.exe spawn settings for Windows. |
| app/src/lib/hooks/get-shell-env.ts | Adds optional printenvzPath parameter to support unit testing. |
| .vscode/launch.json | Makes debug test launch paths relative to workspace root. |
| .test.env | Removes some environment overrides previously set for test debugging. |
app/src/lib/hooks/get-shell.ts
Outdated
| if (gitPath.toLowerCase().endsWith('\\cmd\\git.exe')) { | ||
| bashPath = join(gitPath, '../../usr/bin/bash.exe') | ||
| } else if (gitPath.toLowerCase().endsWith('\\mingw64\\bin\\git.exe')) { | ||
| bashPath = join(gitPath, '../../../usr/bin/bash.exe') |
There was a problem hiding this comment.
I'm always confused by this: some paths use \\ some other /. Is this correct? or should we use join(gitPath, '..', '..', '..', 'usr', 'bin', 'bash.exe') ?
There was a problem hiding this comment.
Yeah, this is safe because Node runs normalize on the path after joining so those / will become \. See https://nodejs.org/docs/latest/api/path.html#pathjoinpaths
joins all given path segments together using the platform-specific separator as a delimiter, then normalizes the resulting path
And https://nodejs.org/docs/latest/api/path.html#pathnormalizepath
Since Windows recognizes multiple path separators, both separators will be replaced by instances of the Windows preferred separator ():
path.win32.normalize('C:////temp\\\\/\\/\\/foo/bar'); // Returns: 'C:\\temp\\foo\\bar'
Add an explicit TypeScript type for bashPath in app/src/lib/hooks/get-shell.ts (string | null) to improve type safety and satisfy strict typing rules. This is a non-functional change — no runtime behavior is altered.
Closes #[issue number]
Description
This started out as a PR to just add a get-shell-env test but ended up causing a few changes after problems discovered. I'll try to document these in the diff
Screenshots
Release notes
Notes: