Repository navigation
fix(vscode): pick the print environment command by shell #6091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tripleaceme
wants to merge
3
commits into
SQLMesh:main
Choose a base branch
from
tripleaceme:fix/shell-aware-print-env
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import { describe, it, expect } from 'vitest' | ||
| import { detectShellFamily, printEnvironmentCommand } from './shellCommand' | ||
|
|
||
| const POWERSHELL_COMMAND = | ||
| "Get-ChildItem Env: | Sort-Object Name | ForEach-Object { '{0}={1}' -f $_.Name, $_.Value }" | ||
|
|
||
| describe('detectShellFamily', () => { | ||
| it('should detect fish', () => { | ||
| expect(detectShellFamily('/usr/bin/fish', false)).toBe('fish') | ||
| expect(detectShellFamily('/opt/homebrew/bin/fish', false)).toBe('fish') | ||
| }) | ||
|
|
||
| it('should detect POSIX shells', () => { | ||
| expect(detectShellFamily('/bin/bash', false)).toBe('posix') | ||
| expect(detectShellFamily('/bin/zsh', false)).toBe('posix') | ||
| expect(detectShellFamily('/bin/sh', false)).toBe('posix') | ||
| expect(detectShellFamily('/usr/bin/dash', false)).toBe('posix') | ||
| expect(detectShellFamily('/usr/bin/ksh', false)).toBe('posix') | ||
| }) | ||
|
|
||
| it('should detect Windows shells, ignoring the executable extension', () => { | ||
| expect(detectShellFamily('C:\\Windows\\System32\\cmd.exe', true)).toBe( | ||
| 'cmd', | ||
| ) | ||
| expect( | ||
| detectShellFamily( | ||
| 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', | ||
| true, | ||
| ), | ||
| ).toBe('powershell') | ||
| expect( | ||
| detectShellFamily('C:\\Program Files\\PowerShell\\7\\pwsh.exe', true), | ||
| ).toBe('powershell') | ||
| }) | ||
|
|
||
| it('should detect a POSIX shell installed on Windows', () => { | ||
| expect( | ||
| detectShellFamily('C:\\Program Files\\Git\\bin\\bash.exe', true), | ||
| ).toBe('posix') | ||
| }) | ||
|
|
||
| it('should accept a bare shell name without a path', () => { | ||
| expect(detectShellFamily('fish', false)).toBe('fish') | ||
| expect(detectShellFamily('pwsh', false)).toBe('powershell') | ||
| }) | ||
|
|
||
| it('should ignore the case of the shell name', () => { | ||
| expect(detectShellFamily('/usr/bin/FISH', false)).toBe('fish') | ||
| expect(detectShellFamily('C:\\WINDOWS\\SYSTEM32\\CMD.EXE', true)).toBe( | ||
| 'cmd', | ||
| ) | ||
| }) | ||
|
|
||
| it('should fall back on the platform for an unknown shell', () => { | ||
| expect(detectShellFamily('/usr/bin/elvish', false)).toBe('posix') | ||
| expect(detectShellFamily('C:\\tools\\elvish.exe', true)).toBe('cmd') | ||
| }) | ||
|
|
||
| it('should fall back on the platform when no shell is reported', () => { | ||
| expect(detectShellFamily('', false)).toBe('posix') | ||
| expect(detectShellFamily('', true)).toBe('cmd') | ||
| expect(detectShellFamily(undefined, false)).toBe('posix') | ||
| expect(detectShellFamily(undefined, true)).toBe('cmd') | ||
| }) | ||
| }) | ||
|
|
||
| describe('printEnvironmentCommand', () => { | ||
| it('should use the exported-only set in fish', () => { | ||
| expect(printEnvironmentCommand('/usr/bin/fish', false)).toBe('set -x') | ||
| }) | ||
|
|
||
| it('should use env | sort in POSIX shells', () => { | ||
| expect(printEnvironmentCommand('/bin/bash', false)).toBe('env | sort') | ||
| expect(printEnvironmentCommand('/bin/zsh', false)).toBe('env | sort') | ||
| expect(printEnvironmentCommand('/bin/sh', false)).toBe('env | sort') | ||
| }) | ||
|
|
||
| it('should use set in cmd', () => { | ||
| expect( | ||
| printEnvironmentCommand('C:\\Windows\\System32\\cmd.exe', true), | ||
| ).toBe('set') | ||
| }) | ||
|
|
||
| it('should not use set in PowerShell, where it prompts for a variable name', () => { | ||
| expect( | ||
| printEnvironmentCommand( | ||
| 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', | ||
| true, | ||
| ), | ||
| ).toBe(POWERSHELL_COMMAND) | ||
| }) | ||
|
|
||
| it('should use the PowerShell command for pwsh off Windows', () => { | ||
| expect(printEnvironmentCommand('/usr/local/bin/pwsh', false)).toBe( | ||
| POWERSHELL_COMMAND, | ||
| ) | ||
| expect(printEnvironmentCommand('pwsh', false)).toBe(POWERSHELL_COMMAND) | ||
| }) | ||
|
|
||
| it('should keep the previous behaviour when the shell is unknown', () => { | ||
| expect(printEnvironmentCommand(undefined, false)).toBe('env | sort') | ||
| expect(printEnvironmentCommand(undefined, true)).toBe('set') | ||
| }) | ||
| }) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| /** | ||
| * The shell families we know how to print environment variables in. | ||
| */ | ||
| export type ShellFamily = 'fish' | 'powershell' | 'cmd' | 'posix' | ||
|
|
||
| /** | ||
| * Commands that list the environment variables of the current shell, one per | ||
| * shell family. | ||
| * | ||
| * `set -x` is fish's exported-only listing, which matches what the other | ||
| * families print; a bare `set` would also include shell-local variables. | ||
| * PowerShell formats each variable itself because the default table view | ||
| * truncates values at the console width. | ||
| */ | ||
| const PRINT_ENVIRONMENT_COMMANDS: Record<ShellFamily, string> = { | ||
| fish: 'set -x', | ||
| powershell: | ||
| "Get-ChildItem Env: | Sort-Object Name | ForEach-Object { '{0}={1}' -f $_.Name, $_.Value }", | ||
| cmd: 'set', | ||
| posix: 'env | sort', | ||
| } | ||
|
|
||
| const SHELL_FAMILIES_BY_NAME: Record<string, ShellFamily> = { | ||
| fish: 'fish', | ||
| powershell: 'powershell', | ||
| pwsh: 'powershell', | ||
| cmd: 'cmd', | ||
| bash: 'posix', | ||
| zsh: 'posix', | ||
| sh: 'posix', | ||
| dash: 'posix', | ||
| ksh: 'posix', | ||
| ash: 'posix', | ||
| } | ||
|
|
||
| /** | ||
| * Extracts the executable name from a shell path, which may use either | ||
| * separator and may carry a Windows executable extension. | ||
| */ | ||
| const shellName = (shellPath: string): string => { | ||
| const base = shellPath.split(/[\\/]/).pop() ?? '' | ||
| return base.toLowerCase().replace(/\.exe$/, '') | ||
| } | ||
|
|
||
| /** | ||
| * Resolves a shell path to the family whose syntax it accepts. | ||
| * | ||
| * Unrecognized shells fall back on the platform default, which keeps POSIX | ||
| * shells we have not listed working. | ||
| * | ||
| * @param shellPath The path reported by `vscode.env.shell`, which is empty in | ||
| * environments without a shell | ||
| * @param isWindows Whether the extension host runs on Windows | ||
| */ | ||
| export const detectShellFamily = ( | ||
| shellPath: string | undefined, | ||
| isWindows: boolean, | ||
| ): ShellFamily => { | ||
| const family = shellPath | ||
| ? SHELL_FAMILIES_BY_NAME[shellName(shellPath)] | ||
| : undefined | ||
| if (family) { | ||
| return family | ||
| } | ||
| return isWindows ? 'cmd' : 'posix' | ||
| } | ||
|
|
||
| /** | ||
| * Returns the command that prints all environment variables in the given | ||
| * shell. | ||
| * | ||
| * @param shellPath The path reported by `vscode.env.shell`, which is empty in | ||
| * environments without a shell | ||
| * @param isWindows Whether the extension host runs on Windows | ||
| */ | ||
| export const printEnvironmentCommand = ( | ||
| shellPath: string | undefined, | ||
| isWindows: boolean, | ||
| ): string => PRINT_ENVIRONMENT_COMMANDS[detectShellFamily(shellPath, isWindows)] |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add in another test to that if we have
pwshandisWindowsfalse, it still returns the powershell command correctlyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in d239db3 as
should use the PowerShell command for pwsh off Windows, covering both/usr/local/bin/pwshand a barepwsh.I checked it isn't a test that passes no matter what. The regression it guards is PowerShell being treated as Windows-only, so I gated the lookup behind
!(family === 'powershell' && !isWindows)and confirmed the new test fails, then restored it and confirmed all 14 pass. Worth noting the command-layer coverage was the gap —detectShellFamily('pwsh', false)was already asserted, but nothing checked that the command came back right off Windows.