nvm-sh / nvm

Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
MIT License
79.75k stars 7.98k forks source link

How to update nvm #400

Open Pana opened 10 years ago

Pana commented 10 years ago

If nvm has a command that will update himself, it will be more awesome. Now the method i know is remove nvm and reinstall, but this will set all my node reinstall

ljharb commented 1 year ago

It's not "annoying", it's "safe". Inconvenience is irrelevant compared to safety.

ljharb commented 1 year ago

@whyboris yes, it is rude and spam.

andrew-aladev commented 1 year ago

@ljharb, I don't know what you mean unsafe.

I have a good source code, covered with unit tests and more complex tests. I want now to prepare the next version of container with nvm, node:lts and test it in automatic mode. If it will fail I will dive into container and fix it. My Dockerfile wants script for installation of latest nvm. I am opening nvm readme and I can't find this command.

I can't move to fnm because I am using nvm install "$(cat .nvmrc)" --reinstall-packages-from="$(nvm current)" and I like it.

I am sure that its an issue. I see no reason why readme has no command for installation of latest version. Your command for installation of fixed version may be first one and installation of the latest version mey be the second one.

ljharb commented 1 year ago

It's unsafe because it's not reasonable to assume that anyone - let alone everyone - has tests covering usage of nvm commands which are often typed by devs, or in CI/build scripts that aren't themselves tested.

andrew-aladev commented 1 year ago

So your plan is the following:

  1. CI/build scripts includes abandoned version of nvm.
  2. Script launches install lts/* but it can't install the most recent lts version, it installs some lts version.
  3. Script won't fail, but project won't receive the recent version of lts node.
  4. Script is more important that project.
ljharb commented 1 year ago

I'm not following your logic. If ANY nvm command would stop working, then it's an unsafe update to receive blindly. This is the same reason why a node project should never use * or latest or >= or >, only a semver range using ^ or ~ or =, to depend on a package.

andrew-aladev commented 1 year ago

If ANY nvm command would stop working, then it's an unsafe update to receive blindly.

Ok, you are talking now with this developer, that wants to update system somehow. I am implementing Dockerfile.staging with some blind or not blind update. Dockerfile may include fixed version, but Dockerfile.staging will include recent version of nvm. Dockerfile.staging won't be included in release.

Can you please include a line into readme with installation of recent version of nvm for such developers?

ljharb commented 1 year ago

The line is the one with the explicit version. You're expected to copy and paste the line any time you want to install the latest version, and be aware of the caveats yourself.

andrew-aladev commented 1 year ago

I am using yarn npm-check-updates --upgrade that updates every package to the latest version. If upgrade process fails that I am diving into and updating each package version one-by-one to detect what package should be a focus for me right now.

If nvm upgrades it provides the following warning: nvm is already installed in /home/app/.config/nvm, trying to update using git. You have already attracted developer attension, your conscience is clear. Developer knows what he is doing.

andrew-aladev commented 1 year ago

The most safe way for any project life is maintenance. Maintenance means constant everyday upgrades. Developer can migrate code to the next major/minor/patch package version with ease because he won't drown in api changes.

Lets remember a project without constant maintanance from real life. We had a customer saying "I have an issue, can you please find a way to fix it?". I've opened project and found it has never been updated since 2018 year. The issue was connected with abandoned ancient version of react-select.

My resolution was the following:

  1. I can upgrade react-select from version to version one-by-one simulating missing project maintenance but it will cost too much for you, because it is hard.
  2. I can rewrite components that depends on react-select from scratch and it will cost less money, but still too much.
  3. I can provide a fix for your issue by patching ancient and abandoned version of react-select. It is not safe and I can't provide any guarantee that patched version won't receive other issues in future. But cost is low enough.

Customer selected variant 3. Later he came and said "I had an issue with another package". I have provided another low price fix for ancient and abandoned package version. These solutions finally led to project source code death and customer finally paid new project rewrite from scratch.

Your politic with fixed version of nvm provokes same issue.

ljharb commented 1 year ago

None the less, the decision stands.

rdeforest commented 1 year ago

I understand this discussion is closed, but I'd like to summarize it to make sure I understood it and for the sake of anyone else coming here looking for answers to these questions.

ljharb commented 1 year ago

@rdeforest accurate. also, to make it clear, i do not intend to ever make breaking changes to nvm use or nvm install, so ideally bullet point 2.2 wouldn't ever happen.

arnonuem commented 1 year ago

@mgol Could you please open a pullrequest and put your script in a convenient file like update-nvm.sh or so? Would be nice if this would be always already shipped with the application.

mgol commented 1 year ago

@arnonuem It's up to the maintainer how they want to approach this. I am not sure if the Git upgrade method has some holes in it, all I know is it worked for me. I'd only recommend changing the ~/.nvm references to "$NVM_DIR" to make this more generic.

I also don't use nvm on my local machine anymore so I am not in a position to dive deeper here. Feel free to use my script, though.

ProbstDJakob commented 9 months ago

If someone is interested, until there is a proper upgrade command, if ever, I use the following:

curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/$(curl -s https://api.github.com/repos/nvm-sh/nvm/releases/latest | jq -r '.tag_name')/install.sh" | bash

This fetches the latest release and its tag via the GitHub API and then upgrades the installation as described in the README.md.

ljharb commented 9 months ago

@ProbstDJakob i'm going to hide this, because doing that blindly will incur breaking changes without you realizing.

ProbstDJakob commented 9 months ago

Ok, but this is the case for all software you upgrade especially when using package managers like the ones from linux distros or macOS's homebrew. There you do not have the luxury of a version constraint and thus always have to take care when upgrading, but in 99% of the cases this is not an issue. Same would go with upgrading nvm via script, but if you want to add an extra step for the user to be on the safe side maybe the following is more what you are looking for (just a quick and dirty soloution).

#!/usr/bin/env sh
set -eu

getMajorVersion() {
  jq --null-input --arg version "$1" -r '$version | ltrimstr("v") | split(".") | first // ""'
}

latestTag="$(curl -s https://api.github.com/repos/nvm-sh/nvm/releases/latest | jq -r '.tag_name')"
currentTag="$(git -C .nvm tag --points-at=HEAD --sort=-version:refname | jq -R | jq --slurp -r first)"

if [ "$latestTag" = "$currentTag" ]; then
  printf 'Nvm is already on the latest version %s.\n' "$latestTag" >&2
  exit 0
fi

if [ "$(getMajorVersion "$latestTag")" != "$(getMajorVersion "$currentTag")" ] && [ "$1" != "--upgrade-breaking" ]; then
  printf 'The upcoming release contains a breaking change. To upgrade pass the option "--upgrade-breaking".\n' >&2
  exit 1
fi

printf 'Upgrading nvm from %s to %s...\n\n' "$currentTag" "$latestTag" >&2

curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/$latestTag/install.sh" | bash

Since the project currently has not reached version 1.0.0 I assume breaking changes take place in the minor version. If that is the case the function getMajorVersion must be adapted to (also) inspect the minor version or a second one should be added.

ljharb commented 9 months ago

@ProbstDJakob it's not the case for the npm ecosystem, in which virtually everything uses semver and ^ ranges. That a lot of ecosystems don't follow good practices in this regard doesn't mean it's wise to recommend that nvm users do as well.

Yes, you're correct that breaking changes are in the X in vX.Y.Z, v0.X.Y, and v0.0.X.

It's far simpler for a user to just go to the readme and copy the new installation command, than to have a brittle script in place, imo.

nbro10 commented 8 months ago

Bump.

What's the status? Is there an easy way to self-update nvm?

ljharb commented 8 months ago

@nbro10 the easy way is to rerun the install script.

nbro10 commented 8 months ago

@ljharb So, to be clear, I've once used the following command to install nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

If I use (currently, the last version)

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

What's going to happen exactly? Will this new nvm replace the old one automatically? Or will I have 2 nvms? What happens to the node versions that I installed with version nvm v0.39.5?

ljharb commented 8 months ago

The new one will replace the old one automatically, and all node versions will persist.