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

Stale environment for integrated terminal #470

Open
austinbutler opened this issue Apr 22, 2023 · 3 comments
Open

Stale environment for integrated terminal #470

austinbutler opened this issue Apr 22, 2023 · 3 comments
Labels
enhancement New feature or request

Comments

@austinbutler
Copy link

I was having a problem where direnv failed loading the Nix shell due to an invalid NODE_OPTIONS flag, but only in the VS Code integrated terminal. Outside of VS Code direnv had no issue loading and NODE_OPTIONS was unset. I wasn't setting NODE_OPTIONS anywhere, such as .envrc or .env. Eventually I found reference to NODE_OPTIONS in ~/.config/Code/User/workspaceStorage/33633d8607204d6980a785c25990590d/state.vscdb.backup. It's an SQLite DB, and in the ItemTable table there's a row with key terminal.integrated.environmentVariableCollections where the value is a JSON blob and that shows the environment variable is from mkhl.direnv. Knowing that, I ran direnv: Reset and reload environment, which got rid of the NODE_OPTIONS environment variable.

It seems like somehow the direnv VS Code extension isn't properly updating the direnv environment in the integrated terminal. I had set that environment variable like 3 weeks ago to test something and then remove it and I've definitely rebooted my computer, reloaded VS Code, exited VS Code, exited the integrated terminal (typing exit to clear history), etc. I assumed re-opening VS Code would reload the environment properly.

What's interesting is that I find no logging of the direnv extension setting NODE_OPTIONS in the VS Code logs. rg --no-ignore NODE_OPTIONS -l ~/.config/Code/logs returns zero direnv results.

@mkhl
Copy link
Contributor

mkhl commented Apr 24, 2023

I was having a problem where direnv failed loading the Nix shell due to an invalid NODE_OPTIONS flag, but only in the VS Code integrated terminal. Outside of VS Code direnv had no issue loading and NODE_OPTIONS was unset. I wasn't setting NODE_OPTIONS anywhere, such as .envrc or .env. Eventually I found reference to NODE_OPTIONS in ~/.config/Code/User/workspaceStorage/33633d8607204d6980a785c25990590d/state.vscdb.backup. It's an SQLite DB, and in the ItemTable table there's a row with key terminal.integrated.environmentVariableCollections where the value is a JSON blob and that shows the environment variable is from mkhl.direnv. Knowing that, I ran direnv: Reset and reload environment, which got rid of the NODE_OPTIONS environment variable.

The direnv extension keeps a cache of the modified environment in the workspace state, that's the SQLite file you found. It's there to speed up the initial load and hopefully get the environment in place before other extensions try to use it, and has caused your issue.

What is weird is that you state the environment was only present in integrated terminals, which to me would imply that it was not present in other tasks, and the two managed environments had gotten out of sync. Is that what you meant?

It seems like somehow the direnv VS Code extension isn't properly updating the direnv environment in the integrated terminal. I had set that environment variable like 3 weeks ago to test something and then remove it and I've definitely rebooted my computer, reloaded VS Code, exited VS Code, exited the integrated terminal (typing exit to clear history), etc. I assumed re-opening VS Code would reload the environment properly.

This is leaning very heavily on assumptions and the word properly
A .envrc file can make a series of updates to a given environment, inside you can read, set and unset environment variables.
Strictly speaking, not setting an environment variables means that you don't care about its value, and if you needed a variable to be unset you'd need to, well, unset it.
Removing a definition somewhere doesn't automatically unset a variable because there's no notion of where the variable came from, that's just not part of what environment variables are.

That said, I agree that matching your intuition would be valuable, i.e. if this extension worked more like a shell that starts from a well-known environment and only loads changes to it from known sources.
The problem there is that starting from a cache, then undoing its changes and running direnv from a clean environment, and then determining whether that led to changes from the cached environment is much harder than what we currently do.
I'm planning to try this at some point (or accept patches for it!) but to me that would be an enhancement, not a bugfix.

What's interesting is that I find no logging of the direnv extension setting NODE_OPTIONS in the VS Code logs. rg --no-ignore NODE_OPTIONS -l ~/.config/Code/logs returns zero direnv results.

I'd be very curious what you expected to find there, or how often you've managed to find something valuable there already?

I believe that files there would be generated by a LogOutputChannel, which is a quite recent feature and not yet present in the VS Code version we require. Instead we log to an OutputChannel which I don't think is persisted in a file, and I haven't gotten around to checking out the new API yet.

@mkhl mkhl added the enhancement New feature or request label Apr 24, 2023
@austinbutler
Copy link
Author

What is weird is that you state the environment was only present in integrated terminals, which to me would imply that it was not present in other tasks, and the two managed environments had gotten out of sync. Is that what you meant?

Sorry, should have been more clear here. I meant my terminal outside of VS Code (Alacritty). I couldn't yarn start with the VS Code integrated terminal, but I could with Alacritty. I entirely restarted VS Code several times, and the only thing that helped was explicitly running direnv: Reset and reload environment.

Strictly speaking, not setting an environment variables means that you don't care about its value, and if you needed a variable to be unset you'd need to, well, unset it.

What I mean here is if I add an env var to .env and load that via dotenv_if_exists, then remove it from .env and direnv reload I expect the env var to be gone.

I'm planning to try this at some point (or accept patches for it!) but to me that would be an enhancement, not a bugfix.

If it's not a bug, how is this supposed to work? The user needs to be aware of when the env changes and manually run direnv: Reset and reload environment or click the icons?

I'd be very curious what you expected to find there, or how often you've managed to find something valuable there already?

Looking for the added: <some_var> logs. They are there, for example:

❯ rg --no-ignore 'added: PGUSER' -l ~/.config/Code/logs
/home/austin/.config/Code/logs/20230424T100806/window2/exthost/output_logging_20230424T122404/2-direnv.log

@mkhl
Copy link
Contributor

mkhl commented Apr 26, 2023

If it's not a bug, how is this supposed to work?

Like I said, if a variable needs to be unset then one should unset it.

Also like I said: What you're expecting would be obviously strictly better.

Looking for the added: <some_var> logs. They are there, for example:

Oh all outputs get persisted there, nice. TIL, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

2 participants