jorgebucaran / nvm.fish

The Node.js version manager you'll adore, crafted just for Fish
https://git.io/nvm.fish
MIT License
2.06k stars 69 forks source link

macOS / brew: After "nvm use default", still node from brew is on path #210

Closed StefanLobbenmeierObjego closed 5 months ago

StefanLobbenmeierObjego commented 1 year ago

I have a strange issue with nvm, that whenever I run

fish --command 'nvm use v16.16.0' 
Now using Node v20.1.0 (npm 9.6.4) /opt/homebrew/Cellar/node/20.1.0/bin/node

It still points to the brew node version. Not sure how / why. My workaround is to first call nvm use system, and then nvm use v16.16.0 to switch back, which seems to do the trick.

fish --command 'nvm use system; nvm use v16.16.0;'
Now using Node v20.1.0 (npm 9.6.4) /opt/homebrew/Cellar/node/20.1.0/bin/node
Now using Node v16.16.0 (npm 8.11.0) ~/.local/share/nvm/v16.16.0/bin/node

Any idea what this could be caused by?

StefanLobbenmeierObjego commented 1 year ago

I read in another issue that I should set the default version, but that seems to not make a difference:

fish --command 'echo $nvm_default_version'
16

even setting it twice leaves it at system:

fish --command 'nvm use default; nvm use default;'
Now using Node v20.1.0 (npm 9.6.4) /opt/homebrew/Cellar/node/20.1.0/bin/node
Now using Node v20.1.0 (npm 9.6.4) /opt/homebrew/Cellar/node/20.1.0/bin/node

but the same workaround works:

fish --command 'nvm use system; nvm use default;' 
Now using Node v20.1.0 (npm 9.6.4) /opt/homebrew/Cellar/node/20.1.0/bin/node
Now using Node v16.16.0 (npm 8.11.0) ~/.local/share/nvm/v16.16.0/bin/node
StefanLobbenmeierObjego commented 1 year ago

Probably related, it already thinks that it is using the right version, but it is not:

fish --command 'nvm current; node --version; which node;'
v16.16.0
v20.1.0
/opt/homebrew/bin/node
tuephan-hi commented 1 year ago

I have the same problem, it seems like nvm binary path is loaded before homebrew/bin, causing the node in homebrew/bin to be active. I think nvm use currently does not reload to have correct order if it already exists in $PATH. It would be great if we have nvm use --force to make sure the node path from nvm is the last one so that it trumps the one in homebrew. @jorgebucaran is this assumption correct?

My fish config: https://github.com/icyrainz/.dotfiles/blob/master/fish/config.fish

ujwal-setlur commented 9 months ago

Yes, I have the same problem when node is installed as a dependency of some homebrew formula (typescript-language-server in my case). An initial login shell has the correct path:

/Users/ujwal/Library/pnpm /Users/ujwal/.local/share/nvm/v18.13.0/bin /opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin /opt/homebrew/opt/postgresql@15/bin /opt/homebrew/sbin /Users/ujwal/Library/Android/sdk/platform-tools /opt/homebrew/bin /usr/local/bin /System/Cryptexes/App/usr/bin /usr/bin /bin /usr/sbin /sbin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin /Library/Apple/usr/bin /Applications/VMware Fusion.app/Contents/Public /Applications/iTerm.app/Contents/Resources/utilities /Users/ujwal/.krew/bin

But any sub shell of fish or VS Code terminal will have the wrong path:

/Users/ujwal/Library/pnpm /opt/homebrew/opt/postgresql@15/bin /opt/homebrew/sbin /Users/ujwal/Library/Android/sdk/platform-tools /opt/homebrew/bin /usr/local/bin /System/Cryptexes/App/usr/bin /usr/bin /bin /usr/sbin /sbin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin /Library/Apple/usr/bin /Applications/VMware Fusion.app/Contents/Public /Users/ujwal/Library/pnpm /Users/ujwal/.local/share/nvm/v18.13.0/bin /opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin /Users/ujwal/.krew/bin /Users/ujwal/.krew/bin
jorgebucaran commented 9 months ago

How did you install nvm.fish and Fisher? I'm asking because I've seen people install these tools in unconventional ways, often leading to problems.

Also, I noticed you're using:

fish --command 'nvm use v16.16.0'

This will not affect the Node version since it runs in a subshell. It's surprising you're doing this, as the documentation doesn't suggest using nvm like that. You should simply use:

nvm use v16.16.0

Finally, this tool doesn't depend on nvm.sh; it's a standalone Node version manager for Fish.

If you're still having trouble, I suggest printing out the $PATH to see what's included. If the order is incorrect, nvm.fish may not be adding Node to the $PATH properly, which could be a bug. If you can provide evidence of this or instructions on how to replicate the issue, I'd be glad to investigate.

StefanLobbenmeierObjego commented 9 months ago

This will not affect the Node version since it runs in a subshell. It's surprising you're doing this, as the documentation doesn't suggest using nvm like that. You should simply use:

Yeah I am aware, I wanted to show that this happens in a fresh fish shell.

But I also have some good news, something fixed this in the meantime. Not sure what exactly, but I could no longer reproduce just now. Let me see if I can restore the issue by going to an older version.

Edit: there was no update since april. Not sure what caused it to be fixed

StefanLobbenmeierObjego commented 9 months ago

How did you install nvm.fish and Fisher? I'm asking because I've seen people install these tools in unconventional ways, often leading to problems.

According to my shell history:

curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher

fisher install jorgebucaran/nvm.fish

StefanLobbenmeierObjego commented 9 months ago

Found a way to reproduce this, that might also be the reason for writing the fish commands like I did. I still have this issue when I open up a fresh tmux session:

image

ujwal-setlur commented 9 months ago

Here is my reproduction:

Screenshot 2023-11-10 at 8 13 33 AM

This is how I installed fisher and nvm.sh

curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher

fisher install jorgebucaran/nvm.fish
jorgebucaran commented 9 months ago

@ujwal-setlur Your issue seems to stem from changes to the PATH made by you or your software after nvm has already configured Node. This might not necessarily be a bug.

dmohns commented 9 months ago

The behaviour for @ujwal-setlur stems from a standard way of installing Brew. For example, the last line in my fish_variables file is:

SETUVAR fish_user_paths:/opt/homebrew/bin

Looking at this thread it looks like everyone encountering the issue is indeed using Brew on MacOS. So the question becomes: Is (or should be) nvm.fish compatible with Brew?

If yes, then this is a bug and we need to find a way to make it working albeit brew messing with PATH. But I think this might be an extremely hard task.

If no, then Brew users might need to find a different tool that suits their needs.

jorgebucaran commented 9 months ago

Thanks for the info. Can you clarify the issue with Brew? I use Brew on my Mac and haven't had problems, even when installing Node through it, just to check if it works with nvm.fish.

Does the problem happen when installing a program that needs Node as a dependency? I didn't know that could happen. I've never used brew to install something that comes with Node as part of it. How does that work? Does it install Node only for that specific package or does it install it globally, like a normal Brew Node installation?

StefanLobbenmeierObjego commented 9 months ago

Does the problem happen when installing a program that needs Node as a dependency? I didn't know that could happen. I've never used brew to install something that comes with Node as part of it. How does that work? Does it install Node only for that specific package or does it install it globally, like a normal Brew Node installation?

In my case node was installed as a dependency of the firebase-cli:

brew uses --recursive --installed node
firebase-cli

So actually I will go for the workaround of removing it and installing it from npm instead for now

brew uninstal firebase-cli
brew autoremove
jorgebucaran commented 9 months ago

If I brew install firebase-cli, that will also install Node in a way that interferes with setting the default version with nvm.fish, correct? I can try that out.

dmohns commented 9 months ago

If I brew install firebase-cli, that will also install Node in a way that interferes with setting the default version with nvm.fish, correct? I can try that out.

Yeah, that is the hypothesis here. In my case the package is markdownlint-cli2.

markdownlint-cli2
└── node
    ├── brotli
    ├── c-ares
    ├── icu4c
    ├── libnghttp2
    ├── libuv
    └── openssl@3
        └── ca-certificates

so anything that has node as a dependency should trigger the issue.

ujwal-setlur commented 9 months ago

Correct, as I said in an earlier comment, my brew node installation came as a dependency of typescript-language-server. You can also install node directly with brew to recreate the problem.

ujwal-setlur commented 9 months ago

For now, I have removed typescript-language-server and its node dependency

ujwal-setlur commented 9 months ago

Thanks for the info. Can you clarify the issue with Brew? I use Brew on my Mac and haven't had problems, even when installing Node through it, just to check if it works with nvm.fish.

Does the problem happen when installing a program that needs Node as a dependency? I didn't know that could happen. I've never used brew to install something that comes with Node as part of it. How does that work? Does it install Node only for that specific package or does it install it globally, like a normal Brew Node installation?

@jorgebucaran The node dependency is installed "globally", so not hidden by the package. Not even sure that's possible with brew.

kunickiaj commented 7 months ago

Homebrew has you add the following to your ~/.config/fish/config.fish:

eval "$(/opt/homebrew/bin/brew shellenv)"

one of the things it does is place itself first in the path with

! set -q PATH; and set PATH ''; set -gx PATH "/opt/homebrew/bin" "/opt/homebrew/sbin" $PATH;

likely the source of issues here.

A workaround might be to put the contents of shellenv in your config.fish manually adding nvm in the right spot in the path. basically forking the script generated by that command :-/

StefanLobbenmeierObjego commented 7 months ago

In my case, this was not there (I think I might have edited it)

But I had put this here instead, which I also had the same effect: fish_add_path /opt/homebrew/bin

jorgebucaran commented 7 months ago

That's how I use brew myself as well @StefanLobbenmeierObjego.

kunickiaj commented 6 months ago

In my case, this was not there (I think I might have edited it)

But I had put this here instead, which I also had the same effect: fish_add_path /opt/homebrew/bin

the full script does a few other things, i "forked" it by calling the contents instead but modifying the order of the path changes:

set -gx HOMEBREW_PREFIX "/opt/homebrew";
set -gx HOMEBREW_CELLAR "/opt/homebrew/Cellar";
set -gx HOMEBREW_REPOSITORY "/opt/homebrew";
# changed to not puth the homebrew path first
! set -q PATH; and set PATH ''; set -gx PATH $PATH "/opt/homebrew/bin" "/opt/homebrew/sbin";
! set -q MANPATH; and set MANPATH ''; set -gx MANPATH "/opt/homebrew/share/man" $MANPATH;
! set -q INFOPATH; and set INFOPATH ''; set -gx INFOPATH "/opt/homebrew/share/info" $INFOPATH;
jorgebucaran commented 6 months ago

You most likely don't need to set the PATH in your config.fish file; instead, use Fish's fish_add_path.

jakubdonovan commented 5 months ago

You most likely don't need to set the PATH in your config.fish file; instead, use Fish's fish_add_path.

Mine is also broken.

brew uninstall node node@20 node@16
brew install fisher
fisher install jorgebucaran/nvm.fish
node -v (v16.15.0)
nvm install 20
node -v (v20.11.1)

after restarting terminal...

node -v (v16.15.0)
nvm use lts (Now using Node v20.11.1 (npm 10.2.4) ~/.local/share/nvm/v20.11.1/bin/node)

again after restarting terminal... node -v (v16.15.0) Is there a solution?

jorgebucaran commented 5 months ago

See https://github.com/jorgebucaran/nvm.fish#nvm_default_version

jakubdonovan commented 5 months ago

See https://github.com/jorgebucaran/nvm.fish?tab=readme-ov-file#nvm_default_version

I attempted to get it to work with the standard curl installation which also led to the same issue. Trying to uninstall this installation of fisher with fisher self-uninstall results in" fisher: Unknown command: "self-uninstall"" and I can't find the fisher installation in my .config to rm -rf. How do I take care of this before attempting a homebrew installation with the stuff in the link above?

EDIT: I managed to remove it with fisher remove jorgebucaran/fisher EDIT2: set --universal nvm_default_version lts worked with a brew installation of fish and fisher.

jorgebucaran commented 5 months ago

There is no self-install command anymore, although there used to be one way back. Fisher is just a plugin, you can uninstall it through Fisher itself using the remove command. Simply enter fisher remove, press tab to select your Fisher installation, and hit enter.

As for setting a default Node version with nvm.fish, you need to understand that nvm.fish does NOT automatically persist your Node version across different shell sessions. Instead, you can set the $nvm_default_version variable to your preferred Node version, then nvm will try to set it at the start of a new shell session.

Now, I advise against installing Fisher or nvm.fish via brew. I did not create those formulas. Follow the instructions provided in the documentation to use Fisher and nvm.fish correctly. I try to make sure the docs are always up-to-date with all the necessary information for using the software effectively. If you get stuck again, you are welcome to create a new issue describing the problem, and I will see to it accordingly.