Skip to content

shell: write a literal line into a PowerShell profile - #23996

Merged
MikeMcQuaid merged 1 commit into
Homebrew:mainfrom
rawsun007:fix/pwsh-profile-lines
Sep 16, 2026
Merged

MikeMcQuaid merged 1 commit into
Homebrew:mainfrom
rawsun007:fix/pwsh-profile-lines

Conversation

@rawsun007

Copy link
Copy Markdown
Contributor

  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include brew benchmark results.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output; I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

Utils::Shell.set_variable_in_profile and prepend_path_in_profile build a command the user is told to paste. Every branch wraps the profile line in echo '...' except the PowerShell one, which redirects the assignment itself:

"$env:#{variable}='#{value}' >> #{profile}"
"$env:PATH = '#{path}' + \":${env:PATH}\" >> #{profile}"

>> binds to the pipeline, so PowerShell parses those as $env:X = ('y' >> profile). The assignment gets the redirection's result, which is null, and the profile receives the bare value.

Against PowerShell 7.4.6 on macOS, running what brew currently prints:

PS> $env:HOMEBREW_FOO = 'bar' >> ./prof.ps1
PS> $env:HOMEBREW_FOO
                                  # empty
PS> Get-Content ./prof.ps1
bar

The PATH one is worse, because it also blanks $env:PATH in the running session and writes the expanded path as a bare line. Sourcing the profile afterwards gives:

The term '/opt/homebrew/bin:/usr/bin:…' is not recognized as a name of a cmdlet,
function, script file, or executable program.

So a PowerShell user following brew's own advice ends up with a profile that errors on every start and never sets the variable.

To reproduce from brew: with SHELL=/usr/bin/pwsh, brew link on a keg-only formula prints the prepend_path_in_profile command, and brew --env/brew doctor paths print the set_variable_in_profile one.

The fix emits the line as a quoted string, matching what the other branches do with echo. pwsh_quote sits alongside sh_quote and csh_quote; PowerShell single-quoted strings only treat ' specially (doubled), so $, " and backticks need nothing. After the fix, the same session:

PS> '$env:HOMEBREW_FOO = ''bar''''s "x" $y''' >> ./prof.ps1
PS> . ./prof.ps1
PS> $env:HOMEBREW_FOO
bar's "x" $y

Not touched: Utils::Shell.export_value still has no pwsh branch and returns nil there, so brew --env --shell=pwsh and the caveats blocks print nothing for PowerShell users. That is a missing feature rather than a wrong command, and cmd/shellenv.sh already handles pwsh separately, so it looked like its own change.

brew lgtm is green, and reverting only utils/shell.rb fails exactly the three new examples.

AI disclosure: the diff, the tests and the PowerShell verification above were produced by Claude Opus 5 in Claude Code on my machine. I have not yet read the diff line by line myself, so the last box stays unticked until I have; I answer review comments myself, and no commit here is attributed to an AI.

`>>` binds to the pipeline, so `$env:X='y' >> profile` redirects the
assignment's value instead of appending the line: the variable is left
null and the profile receives a bare `y`, which errors on next start.
The PATH variant empties `$env:PATH` and appends the expanded path.

Emit the line as a quoted string, as every other branch does with echo.

@MikeMcQuaid MikeMcQuaid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@MikeMcQuaid
MikeMcQuaid added this pull request to the merge queue Sep 16, 2026
Merged via the queue into Homebrew:main with commit b9ca292 Sep 16, 2026
52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants