volta
volta copied to clipboard
Recreate symlink on `volta install`
I was using volta from Homebrew (brew install volta), but now I'm just using the volta binary at ~/.volta/bin/volta. When I made this switch, all my previously installed packages stopped to work.
I found out that their symlinks were still pointing to the old Homebrew's volta which I uninstalled.
So, my first attempt was to volta install npm and expected that it would recreate the symlink. But it seems that volta skips the creation of it, if it is detected there already.
It could more smarter, by either recreating the symlink even when it already exists, or by checking if the symlink is pointing to the correct volta-shim.
Thanks for the report. This is definitely an interesting case. We try really hard to avoid having Volta do unnecessary work (especially unnecessary I/O), so we’d have to think a fair bit about this. That said, it’s in a flow where we’re already doing a bunch of other I/O which would very much overwhelm the check for symlink targets.
The other (and indeed the main) reason I would be hesitant to implement that kind of checking is: having symlinks pointing to the “wrong” place like this could be a signal that you have multiple conflicting installations or otherwise are in a semi-broken state, and trying to fix it could just make things worse. 🤔
It seems that Volta installed via Homebrew is generally not well supported, am I right? I just updated Volta installed via brew from version 1.0.5 to 1.0.6 and all symlinks in .volta/bin were broken, still pointing to /opt/homebrew/Cellar/volta/1.0.5. However I just learned about the volta-migrate command, which seems to fix broken installations? Anyway, I did not find any reference to the volta-migrate command in the documentation. Maybe volta-migrate should be called in the Homebrew formula?
We have seen the same issue as @svenjacobs.
I think running volta setup works around this problem, but the user has to do it. I don't think this step is one that can go into the Homebrew formula.
I think the problem is that Volta is canonicalizing the path to volta-shim when linking it into ~/.volta/bin. For example, ~/.volta/bin/node is a symlink to /usr/local/Cellar/volta/1.0.6/bin/volta-shim. When Volta's version changes this symlink breaks, as Sven noted. Perhaps if it was a symlink to /usr/local/bin/volta-shim instead (or some other non-versioned path) it wouldn't break when Volta is upgraded.
A relative symlink instead of an absolute one would prevent such issues. Example:
# This is how it's being done
❯ ls -la node
lrwxrwxrwx 1 felipecrs felipecrs 37 Feb 28 13:39 node -> /home/felipecrs/.volta/bin/volta-shim
# This is how it could be done
❯ ln -svf volta-shim node
'node' -> 'volta-shim'
❯ ls -la node
lrwxrwxrwx 1 felipecrs felipecrs 10 Apr 6 12:35 node -> volta-shim
In the latter example, node would always point to a volta-shim in the same directory of itself.
I just stumbled upon this again after updating from version 1.0.6 to 1.0.7 via brew. I had to manually call volta-migrate to fix my installation. Is this the intended behaviour?
Same issue here. Updated from 1.0.7 to 1.0.8, breaking prettier and npm. Symlinks where not updated. @svenjacobs suggestion seems reasonable. If calling volta-migrate solves this issue, then why is not already included on the formulae?
A temporal solution would be to add a Caveat message. Eg: Run volta-migrate to finish upgrade
The suggestion of running volta-migrate directly as part of the formula makes sense to me! I know there was some concern when the formula was first being created around directly running volta setup, which can modify your profile scripts and so goes against the philosophy of Homebrew installations. However, volta-migrate should only modify the .volta directory used by Volta itself, and so should be safe to run (I believe).
@filipekiss Who I believe contributed the Homebrew formula: Is it possible to modify the formula to run volta-migrate after an upgrade? I'll admit to not knowing much about how Homebrew formulae work.
The symlinks that break on upgrade are per-user, in each user's home directory. On a multiuser system, each user could even have a different VOLTA_HOME, defined by whatever shell they prefer, or in whatever IDE (for example) in which they invoke Volta. There is no general way to address this.
Right now, for me:
$ ls -l $VOLTA_HOME/bin
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 node -> /usr/local/Cellar/volta/1.0.8/bin/volta-shim
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 npm -> /usr/local/Cellar/volta/1.0.8/bin/volta-shim
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 npx -> /usr/local/Cellar/volta/1.0.8/bin/volta-shim
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 yarn -> /usr/local/Cellar/volta/1.0.8/bin/volta-shim
This is because volta setup is canonicalizing the following symlink into the versioned path to which it points:
$ ls -l /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin admin 36 2 Jun 10:41 /usr/local/bin/volta-shim -> ../Cellar/volta/1.0.8/bin/volta-shim
Supposing volta setup did not canonicalize that volta-shim symlink, my $VOLTA_HOME/bin would look like this:
$ ls -l $VOLTA_HOME/bin
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 node -> /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 npm -> /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 npx -> /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin staff 44 2 Jun 15:12 yarn -> /usr/local/bin/volta-shim
and there would be no need to run volta setup or volta-migrate again.
I've just discovered that we can achieve this with VOLTA_INSTALL_DIR:
$ VOLTA_INSTALL_DIR=/usr/local/bin volta setup
success: Setup complete. Open a new terminal to start using Volta!
$ ls -l $VOLTA_HOME/bin
lrwxr-xr-x 1 gavin staff 25 9 Jun 18:12 node -> /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin staff 25 9 Jun 18:12 npm -> /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin staff 25 9 Jun 18:12 npx -> /usr/local/bin/volta-shim
lrwxr-xr-x 1 gavin staff 25 9 Jun 18:12 yarn -> /usr/local/bin/volta-shim
Hence, one workaround could be to run VOLTA_INSTALL_DIR=$(dirname "$(type -P volta-shim)") volta setup (command for Bash) a single time and then I think you'll be okay... until something else runs volta setup or volta-migrate.
@charlespierce I'll check to see if we can update the formula to run volta-migrate. Would there be an issue if the command ran after the first installation? I don't think it would be simple (or even correct) to have to validate this in the brew formula.
@filipekiss @charlespierce Just checking in on this since I once again fell into this trap after updating Volta via brew. Did you make any progress regarding calling volta-migrate in the Homebrew formula?
This is being looked at from the Homebrew side in https://github.com/orgs/Homebrew/discussions/4169#discussioncomment-4866773.
@MatthiasPortzel I'm not talking about the current
'volta-shim' should not be called directly
problem with Volta 1.1.1 installed via brew if that is what you mean.
The second issue was created by an unsuccessful attempt to fix this issue.
Regardless, both issues are now fixed.