Skip to content
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

Prepending PATH env var with environmentVariableCollection doesn't work on macOS #99878

Closed
DanTup opened this issue Jun 11, 2020 · 19 comments · Fixed by #171066 or #223421
Closed

Prepending PATH env var with environmentVariableCollection doesn't work on macOS #99878

DanTup opened this issue Jun 11, 2020 · 19 comments · Fixed by #171066 or #223421
Assignees
Labels
api feature-request Request for new features or functionality insiders-released Patch has been released in VS Code Insiders macos Issues with VS Code on MAC/OS X terminal-shell-integration Shell integration infrastructure, command decorations, etc. verification-needed Verification of issue is requested verified Verification succeeded
Milestone

Comments

@DanTup
Copy link
Contributor

DanTup commented Jun 11, 2020

This was covered a little bit in #94153 but that issue is locked and can't be discussed there. This feature feels pretty broken on macOS and I hope might be revisited.

The issue is on macOS prepending to PATH:

context.environmentVariableCollection.prepend("PATH", "/foo/my/path:");

This ends up being added to the end of the path, rather than the start. @Tyriar wrote up why this is in microsoft/vscode-docs@38653d4 and offered two workarounds, however neither of them are usable in my testing (as well as not really being feasible to tell all users to change):

  • "terminal.integrated.inheritEnv": false makes no difference at all, the PATH till is added to the end (this is a problem because the purpose of using prepend above is that we need to override any existing SDK on PATH with the one the user just selected)
  • "terminal.integrated.shellArgs": [] results in a completely empty PATH besides the values I've prepended, which means that pretty much everything else is missing and won't work. This might be solvable by pushing process.env.PATH into environmentVariableCollection too, however the prompt to the user would look ridiculous as it would include their entire PATH

I appreciate this probably isn't VS Code's fault, but given macOS is fairly common and this behaviour seems to happen on a clean macOS install (it happens on both of mine, and I've customised almost nothing) it feels like it's worth trying to fix (maybe even if it means sending export PATH=foo:$PATH once the shell is initialised? 😄).

DanTup added a commit to Dart-Code/Dart-Code that referenced this issue Jun 11, 2020
Fixes #2209, but currently a bit doesn't currently work well because of microsoft/vscode#99878.
DanTup added a commit to Dart-Code/Dart-Code that referenced this issue Jun 11, 2020
Fixes #2209, but doesn't currently work well because of microsoft/vscode#99878.
@Tyriar
Copy link
Member

Tyriar commented Jun 11, 2020

@DanTup to see whether it's a vscode problem or otherwise you can do a trace log to see what environment the terminal is starting up with https://github.com/microsoft/vscode/wiki/Terminal-Issues#enabling-trace-logging

If the prepend is there, I don't think there's anything we can do?

@Tyriar Tyriar added the info-needed Issue requires more information from poster label Jun 11, 2020
@DanTup
Copy link
Contributor Author

DanTup commented Jun 11, 2020

@Tyriar I believe the issue is as you describe, which is the default shell startup is building its wn path (with path_helper?) and then pushing that on to the front.

I don't know the solution, but it feels broken enough that it seems worthwhile trying to solve. For example could VS Code pass its own script to the shell to execute that does the prepending? Or could it reliable send an export PATH= command after the terminal initialises? (I don't like that, but if there's no other option and it works reliably, it seems better than this feature being broken on macOS?).

@DanTup
Copy link
Contributor Author

DanTup commented Jun 11, 2020

I had tried with your samples and calling bash -l does break this in a terminal too.

I'm not saying it's VS Code's fault, I just think it's worth VS Code trying to work around in order to have this feature work well. I waited a really long time for this feature, and it sucks that it doesn't seem like I'll be able to use it 😞

@Tyriar
Copy link
Member

Tyriar commented Jun 11, 2020

Yeah this is annoying... I really don't like sending text but it does seem like a workaround is in order. How about the terminal checks on macOS for whether -l or --login is set and then sends export commands as you suggest? Making sure they work on sh, bash, zsh and fish is the bar it would need to meet (mainly just need to verify on fish).

@Tyriar Tyriar added terminal General terminal issues that don't fall under another label under-discussion Issue is under discussion for relevance, priority, approach and removed info-needed Issue requires more information from poster labels Jun 11, 2020
@Tyriar Tyriar self-assigned this Jun 11, 2020
@DanTup
Copy link
Contributor Author

DanTup commented Jun 11, 2020

How about the terminal checks on macOS for whether -l or --login is set

I guess you mean whether it's set in shellArgs (in case the user overrode that from default)? Sounds reasonable to me, though I'm not very familiar with this stuff. If you have a possible fix, I'm definitely happy to test it out on my MacBooks here (with both have this issue) :-)

@Tyriar
Copy link
Member

Tyriar commented Jun 11, 2020

Yes I mean checking the args the terminal is launched with, which will take shellArgs and any explicit args into account if an extension launched it, to be safe it might also be a good idea to make sure the executable is set to something expected too.

@Tyriar Tyriar added bug Issue identified by VS Code Team member as probable bug and removed under-discussion Issue is under discussion for relevance, priority, approach labels Jun 11, 2020
@Tyriar Tyriar added this to the June 2020 milestone Jun 11, 2020
@Tyriar Tyriar modified the milestones: June 2020, Backlog Jun 29, 2020
@hyangah
Copy link

hyangah commented Jul 28, 2020

We (vscode-go) were trying to use this API to change the PATH in terminal when a user switches the go version, and encountered the same issue.

Following the suggestion, I first tried to sendText command to each shell terminal on darwin in addition to the environmentVariableCollection.prepend call. I also registered an onDidOpenTerminal handler to send newly opened terminals the shell command. This seemed to work ok, except immediately after environmentVariableCollection.prepend was applied - The environment change indicator showed up and when the user clicked 'Relaunch terminal', the login shell was applied again. This can be confusing.

Screen Shot 2020-07-27 at 7 12 03 PM

So, I switched to completely avoid the call of envirnmentVariableCollection.prepend on darwin.
Now it's less confusing, but this approach is not ideal obviously. We had to give up another advantage of environmentVariableCollection, persisting the mutation across sessions, and had to use our own way of storing the state. Lost consistency across platforms is also sad.

hyangah added a commit to hyangah/vscode-go that referenced this issue Jul 28, 2020
… API

vscode.ExtensionContext.EnvironmentVariableCollection is available since
1.46 (May 2020 release https://code.visualstudio.com/updates/v1_46#_environment-variable-collection)
This API is specifically designed to help easy mutation of terminal
environment, so we are trying to use it now.

I hope this helps to address a couple of bugs related to the shell
detection and the correct command and path escaping discovered
during testing on Windows.

Unfortunately, this API does not work well on Mac
microsoft/vscode#99878 due to the peculiarity
described in
https://code.visualstudio.com/docs/editor/integrated-terminal#_why-are-there-duplicate-paths-in-the-terminals-path-environment-variable-andor-why-are-they-reversed

So, we use the new API only for non-darwin OSes for now. On Mac,
we send the command as done before unless users explicitly
chose to use `-l` or `--login` parameter.

And moved addGoRuntimeBaseToPATH to goEnvironmentStatus.ts
because I think this is a better place.

Updates golang#378

Change-Id: I56ada362fb422bca9c789eae30c6239cac5b4711
gopherbot pushed a commit to golang/vscode-go that referenced this issue Jul 28, 2020
… API

vscode.ExtensionContext.EnvironmentVariableCollection is available since
1.46 (May 2020 release https://code.visualstudio.com/updates/v1_46#_environment-variable-collection)
This API is specifically designed to help easy mutation of terminal
environment, so we are trying to use it now.

I hope this helps to address a couple of bugs related to the shell
detection and the correct command and path escaping discovered
during testing on Windows.

Unfortunately, this API does not work well on Mac
microsoft/vscode#99878 due to the peculiarity
described in
https://code.visualstudio.com/docs/editor/integrated-terminal#_why-are-there-duplicate-paths-in-the-terminals-path-environment-variable-andor-why-are-they-reversed

So, we use the new API only for non-darwin OSes for now. On Mac,
we send the command as done before unless users explicitly
chose to use `-l` or `--login` parameter.

And moved addGoRuntimeBaseToPATH to goEnvironmentStatus.ts
because I think this is a better place.

Updates #378

Change-Id: I56ada362fb422bca9c789eae30c6239cac5b4711
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/245127
Reviewed-by: Brayden Cloud <bcloud@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
@hyangah
Copy link

hyangah commented Aug 19, 2020

@Tyriar I probably misinterpreted your following suggesting in my implementation. Here you meant that the workaround is to send the export commands when -l or --login is set. Right?

How about the terminal checks on macOS for whether -l or --login is set and then sends export commands as you suggest? Making sure they work on sh, bash, zsh and fish is the bar it would need to meet (mainly just need to verify on fish).

@jahan01
Copy link

jahan01 commented Aug 21, 2020

@Tyriar I would also like to have this work on macOS. Any variable you set is probably overridden by the rc files.
Most importantly since this approach is being suggested as workaround for python virtual env activation in terminal (microsoft/vscode-python#11039) and few others, would like to make this work through some hacks.

How about the workaround used by Jetbrains IDEs? They seem to have define the startup order and after sourcing the .zshrc they inject whatever they are trying to insert.

Its not ideal and looks very ugly, but better than sending texts after activation. I remember you were also not a big fan sending texts to terminal - #98490 (comment)

I was trying to write an extension to set paths and variables, and they are comfortably overwritten by the startup scripts.

collection.prepend("PATH", `${pythonPath}:`);
collection.replace("JAVA_HOME", javaDir);

So replace doesn't really work and prepend actually appends to last or it's not there, depending on how rcfiles export the PATH.

gopherbot pushed a commit to golang/vscode-go that referenced this issue Sep 2, 2020
I misuderstood the comment in
microsoft/vscode#99878 (comment)
which resulted in that the PATH change does not apply
with the default shell args settings in OS X.

As noted in #544 (comment)
VS Code sets `-l` as the default shell arg.

I also attempted to run updateIntegratedTerminal after
running environmentVariableCollection.prepend. But it seems like
the onDidOpenTerminal handler is not invoked when VS Code relaunches
the terminals to apply the environmentVariableCollection changes.

Tested manually with
  "terminal.integrated.shellArgs.osx": []
and without the setting.

Fixes #544

Change-Id: Icbaaa5131893038f85e322bad1491a99f26378fd
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/251161
Reviewed-by: Suzy Mueller <suzmue@golang.org>
@DanTup
Copy link
Contributor Author

DanTup commented Oct 22, 2022

@Tyriar

We may be able to leverage the upcoming shell integration feature to set the environment variables if needed.

I'm not very familiar with how this works, but now a lot of it has shipped do you have a better idea of whether it can solve this? Judging by the issues being linked here above, it isn't only Dart that would really like this. If you think it'd work but don't plan to work on it, could you provide any pointers for if someone wanted to try and contribute it?

Thanks!

@Tyriar
Copy link
Member

Tyriar commented Oct 24, 2022

@DanTup actually had a discussion with the Python team around this so I'm guessing this will get prioritized soon. The way I'm envisioning this working is for some environment variable being set (VSCODE_ENV_CONTRIBUTION or something?) and the shell integration script checking that and re-applying it after the init scripts run

@Tyriar Tyriar modified the milestones: Backlog, On Deck Oct 24, 2022
@DanTup
Copy link
Contributor Author

DanTup commented Oct 24, 2022

Awesome, thanks! I'm definitely interested in testing this if/when there's something more concrete :-)

@Tyriar Tyriar added api terminal-shell-integration Shell integration infrastructure, command decorations, etc. and removed terminal General terminal issues that don't fall under another label labels Dec 14, 2022
@Tyriar Tyriar modified the milestones: On Deck, January 2023 Jan 6, 2023
@meganrogge meganrogge removed their assignment Jan 9, 2023
Tyriar added a commit that referenced this issue Jan 10, 2023
@vscodenpa vscodenpa added the unreleased Patch has not yet been released in VS Code Insiders label Jan 11, 2023
@Tyriar
Copy link
Member

Tyriar commented Jan 11, 2023

@DanTup the fix for this just got merged if you want to take it for a spin in tomorrow's build. What it does is on mac, when you use a login shell and shell integration is enabled, we'll add the prepended items inside the shell integration script after the profile has run. This should work for bash, zsh and fish (pwsh didn't seem to need the fix).

@vscodenpa vscodenpa added insiders-released Patch has been released in VS Code Insiders and removed unreleased Patch has not yet been released in VS Code Insiders labels Jan 11, 2023
@DanTup
Copy link
Contributor Author

DanTup commented Jan 16, 2023

@Tyriar thanks! This seems to work. However, the UI when changing it doesn't seem very clear:

Screenshot 2023-01-16 at 15 05 35

There's a yellow warning triangle here, but hovering over it or clicking on it gives no indication of the problem. There's another white warning triangle on the side, but the hover for it doesn't appear for quite a long time after you hover over it. I don't think it's very discoverable if a user has an existing session and this changes (and this is made worse by the terminal seeming to persist across reloads).

Is there anything that can be done to improve this? (I can file a new issue about it if necessary).

@Tyriar
Copy link
Member

Tyriar commented Jan 17, 2023

@DanTup we're going to remove the white one in #151160 in favor of the "tab status". Created #171498 to fix the info not showing up in the "single tab"

@DanTup
Copy link
Contributor Author

DanTup commented Jan 17, 2023

Great, thanks! :-)

@Tyriar Tyriar added the verification-needed Verification of issue is requested label Jan 23, 2023
@connor4312 connor4312 added the verified Verification succeeded label Jan 25, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Feb 27, 2023
anton-matosov added a commit to anton-matosov/vscode that referenced this issue Jul 23, 2024
…ions

microsoft#171066 introduced a fix for applying PATH prefix on macOS login shells that resolved microsoft#99878. However it had little issues for each shell implementation.
This PR contains the following fixes:

`bash` fix:
 - Add missing `:` separator in the path setter to avoid path corruption
 - Add missing quotes to avoid path interpretation

`zsh` fix:
 - Add missing `:` separator in the path setter to avoid path corruption
 - Add missing quotes to avoid path interpretation
 - Move patching outside of `.zprofile` check as clean macOS install doesn't include this file, nevertheless PATH patching should still happen

 `fish` fix:
 - use `set -gx PATH` instead of `fish_add_path` as the latter has no effect on updating the path if entries already exist in it. Which is the case for some extensions, like [`vscode-micromamba`](https://github.com/mamba-org/vscode-micromamba) which modify process environment and after login shell rc processing path entries end up in the end.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api feature-request Request for new features or functionality insiders-released Patch has been released in VS Code Insiders macos Issues with VS Code on MAC/OS X terminal-shell-integration Shell integration infrastructure, command decorations, etc. verification-needed Verification of issue is requested verified Verification succeeded
Projects
None yet
7 participants