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

creationix commented 10 years ago

I always install by cloning from git. Then if I want to update, I simply do a git pull.

That said, why would you upgrade if it's working? Personally I've never upgraded nvm after installing it on a machine. (though my operating system install lifetimes are fairly short). If you learn about a new feature that you need, then git pull and you're done.

Remember that every feature added has a cost. Could you explain what exactly makes it more awesome? Perhaps I'm not understanding your use case.

ljharb commented 10 years ago

Duplicate of #127

ljharb commented 10 years ago

Also, you don't have to ever remove nvm - just install the newer version, and it will replace the older one.

mgol commented 10 years ago

I feel #127 shouldn't be closed now that users are not supposed to run from master but from a tagged commit. I use the following script:

#!/bin/sh

set -e

cd ~/.nvm

git fetch --tags
TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
echo "Checking out tag $TAG..."
git checkout "$TAG"

source ~/.nvm/nvm.sh
chrisspiegl commented 10 years ago

+1

pcriv commented 10 years ago

+1

dead-claudia commented 9 years ago

It appears that simply effectively re-installing over an existing nvm actually updates it. This would be a really trivial script.

dead-claudia commented 9 years ago

I believe this should do it. The $@ is optional, but mostly for debugging (Depends on either curl or wget, preferring the former.)

#!/bin/sh

download() {
  if which curl > /dev/null; then
    curl -s $@
  else
    wget -qO- $@
  fi
}

download https://raw.githubusercontent.com/creationix/nvm/v0.20.0/install.sh | /usr/bin/env bash $@

Or, if you'd prefer a giant one-liner, here it is. This one should also work with csh, although I don't have one installed to test with. It's probably the most portable. It is alias-safe if you drop the last $@, but make sure to use double-quotes.

#!/bin/sh
`which curl > /dev/null && printf 'curl -s' || printf 'wget -qO-'` https://raw.githubusercontent.com/creationix/nvm/v0.20.0/install.sh | /usr/bin/env bash $@

Both have been tested in dash and bash, and they should be fairly portable, even with older shells.

If you want to add support for using Git, it'll take bit more logic and a lot of Git "plumbing" commands, such as git ls-remote -t https://github.com/creationix/nvm.git (lists commits and tags, but former needs filtered out). Long story short, it's far from trivial.

Maybe that could be put into nvm.sh somewhere.

ljharb commented 9 years ago

It's trivial for a user, because you already know your preferred installation method.

However, nvm can be installed via curl, wget, git clone, or even simple file copying. It is in no way trivial to include in the actual product.

The only current blessed way to install and update nvm, is the ones I've mentioned - and I strongly encourage the curl command in the README on the git tag for the latest release.

dead-claudia commented 9 years ago

You could probably do something similar, just retrieving the current version first, and then the install script similarly. Mine tries the curl method first (fixed to be silent like wget).

xfq commented 9 years ago

@mzgol

Thanks for your script! I have two questions about it:

  1. Can I run this script in a shell that has run source ~/.nvm/nvm.sh before? I mean, is there any side-effect in nvm.sh (that may cause problems if nvm.sh is run more than once)?
  2. Do I have to install Node.js again after updating nvm? IIRC Node.js is installed exactly in the ~/.nvm directory.
ljharb commented 9 years ago

@xfq nvm unload will completely unload nvm from the shell, so even if it wasn't safe to re-source (it is), you could unload it first if you wanted.

xfq commented 9 years ago

@ljharb I see. Thank you. What about the second question?

ljharb commented 9 years ago

You shouldn't need to reinstall any node versions after updating nvm, no.

surfjedi commented 9 years ago

I have just tried reinstalling NVM - Lees-MacBook-Pro-2:~ leeblazek$ curl https://raw.githubusercontent.com/creationix/nvm/v0.23.0/install.sh | bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 5205 100 5205 0 0 17370 0 --:--:-- --:--:-- --:--:-- 17408 => nvm is already installed in /Users/leeblazek/.nvm, trying to update => Lees-MacBook-Pro-2:~ leeblazek$

But it just doesn't seem to do anything? I have also tried sudo, but still the same non-result

Any ideas?

ljharb commented 9 years ago

@surfjedi This was reported in https://github.com/creationix/nvm/issues/559#issuecomment-70946574 - can you try METHOD=git . install.sh and see what happens?

evenfrost commented 9 years ago

@ljharb I faced same problem as @surfjedi, and running METHOD=git . install.sh helped, thanks.

reggi commented 9 years ago

What does this even mean?!?!?!! gahhh

$ curl https://raw.githubusercontent.com/creationix/nvm/v0.23.3/install.sh | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5226  100  5226    0     0  18866      0 --:--:-- --:--:-- --:--:-- 18934
=> nvm is already installed in /Users/thomas/.nvm, trying to update using git
=> 
=> Appending source string to /Users/thomas/.bashrc
=> Close and reopen your terminal to start using nvm
ljharb commented 9 years ago

@reggi it means it's installed? Is something confusing about that?

reggi commented 9 years ago

Sorry I was super confused on how to update nvm.

I didn't find any information on this:

/Users/thomas/.nvm, trying to update using git

I did this and it worked:

cd /Users/thomas/.nvm
git pull origin master
mgol commented 9 years ago

@reggi That message was correct, what was the problem?

On the other hand, via your last command you updated to master, i.e. an unstable version that may just not work.

reggi commented 9 years ago

Hey @mzgol and @ljharb

Sorry about my first message in this issue. It wasn't helpful to the community or beneficial to this issue.

I had done some searching for how to update nvm, very confusingly updated with npm by accident npm install nvm -g. Then I remembered that nvm isn't on npm, yet at least. So I had to npm uninstall nvm -g.

Then I ran nvm unload without any clue what that would do (not the best of ideas). It messed up nvm and I had no clue how to reload it.

Then I ran git pull origin master and because I had run nvm unload the nvm command wasn't working. I don't also know where the actual nvm binary is stored, which is also confusing.

I ended up moving /Users/thomas/.nvm to /Users/thomas/.oldnvm and reinstalling, and I'm unsure if there's anything in there that I needed like global modules, or where those live or if those live on a node-level basis.

There's surprisingly no documentation on how to update nvm itself and was pretty frustrating. I still don't know the proper way and would love to see something in the README.md about it.

For something so simple as updating I shouldn't have gone through such a hassle.

ljharb commented 9 years ago

fwiw, nvm unload just uninstalls it from the current shell - open a new shell, nvm will be fine.

The nvm that's on npm will be replaced once nvm hits v1.0 - which will include providing an nvm update.

The reality, though, is that the curl command in the README will always install the proper version of nvm, and like all software, will replace any existing installations. In other words, the way to update any software is always, by default, "install the new version in place".

animedbz16 commented 9 years ago

How about something like:

git fetch -p
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
source ~/.nvm/nvm.sh

This will ensure that the repo is updated, checkout the latest tag and re-source the shell script.

Per the nvm documentation (https://github.com/creationix/nvm#manual-install), it seems indicate using the following command:

git checkout `git describe --abbrev=0 --tags`

but as shown below, this does not actually point to the correct version after updating the repo.

[user@server .nvm]$ nvm --version
v0.23.3
[user@server .nvm]$ git fetch -p
remote: Counting objects: 145, done.
remote: Compressing objects: 100% (43/43), done.
remote: Total 145 (delta 43), reused 28 (delta 27), pack-reused 75
Receiving objects: 100% (145/145), 41.70 KiB, done.
Resolving deltas: 100% (73/73), done.
From https://github.com/creationix/nvm
   f0d81e2..70370a8  master     -> origin/master
From https://github.com/creationix/nvm
 * [new tag]         v0.24.0    -> v0.24.0
[user@server .nvm]$ git rev-list --tags --max-count=1
5802ac3ea751bdd66cba75302b3b322109be90f8
[user@server .nvm]$ git describe --tags 5802ac3ea751bdd66cba75302b3b322109be90f8
v0.24.0
[user@server .nvm]$ git describe --abbrev=0 --tags
v0.23.3
[user@server .nvm]$ git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
Previous HEAD position was 0f1f3ed... v0.23.3
HEAD is now at 5802ac3... v0.24.0
[user@server .nvm]$ source ~/.nvm/nvm.sh
[user@server .nvm]$ nvm --version
0.24.0

Then maybe all that would be necessary is including a nvm update command to run these commands to update nvm. But likely using the NVM_DIR variable in the event that nvm isn't installed in the default ~/.nvm location.

ljharb commented 9 years ago

@animedbz16 What version of git are you using? On my machine git describe --abbrev=0 --tags definitely returns v0.24.0, but I do have the config setting tag.sort set to version:refname, which may affect this.

Also, please remember that nvm can currently be installed without having git installed, so that's not necessarily a reliable update mechanism, although it may end up being the simplest.

animedbz16 commented 9 years ago

@ljharb

Currently using git version 1.7.1 on RHEL server. The only things in my git config are user.name, user.email, color.ui=auto, and push.default=current

I would think that most users/systems that are using nvm would have git installed on their system and thus could use this method to perform a nvm update.

For those systems that don't have access to git, a nvm update command could just indicate to the user that it could not detect git and provide some links/information to github repo on how to update via curl/wget via the script.

Maybe at a later point a more sophisticated update script could also automate the curl/wget nvm updating, by curling the github repository for the latest version and then downloading the correct installation/update script/procedures.

ljharb commented 9 years ago

That version of git is old and has security issues - you should upgrade to 2.2 or 2.3 immediately. The install script doesn't work with that old a version of git either. nvm already has an internal nvm_get_latest function that uses curl to determine the latest version of nvm.

I do like the idea that nvm update would require git, but that the normal installation procedure could work without it - however, there'd need to be an easy way to upgrade $NVM_DIR to a git repo without affecting the node/io.js installations underneath it.

jokeyrhyme commented 9 years ago

To install, I git clone to ~/.nvm. To upgrade, I run sh ~/.nvm/install.sh Is this a good way to do this?

ljharb commented 9 years ago

@jokeyrhyme Perfect, except for one step - after the clone/fetch, before running the install script, you'll want to check out the latest tagged release - either git checkout v0.26.1 manually, or, the command referenced in https://github.com/creationix/nvm/issues/400#issuecomment-85047457

jokeyrhyme commented 9 years ago

@ljharb ah, so it's possible that the master version of install.sh could be broken, so use a tagged install.sh to update to the latest tagged nvm?

ljharb commented 9 years ago

Yes, exactly

animedbz16 commented 9 years ago

Just ran across this issue again wanting to update nvm.

I've added the following to my ~/.bashrc, so I can have my own alias to do update nvm.

alias nvm_update="echo 'About to update NVM:'; cd $NVM_DIR; git fetch -p; git checkout \$(git describe --tags \`git rev-list --tags --max-count=1\`); source $NVM_DIR/nvm.sh; cd $OLDPWD"

Obviously this may only work with bash shell, but I would still advocate for a method included directly from within nvm to do this though.

fresheneesz commented 9 years ago

If updating is as easy as re-running the install script, why not just say that in the docs? That seems like the easiest way. The messages that script gives are a bit confusing, if updating, the message should say "Close and reopen your terminal to use the updated version of nvm" rather than "... to start using nvm"

schlegel11 commented 9 years ago

I wrote a modified version of the install.sh script for update my nvm or make a fresh install with the latest version. It updates/installs the nvm only over the git command:

~/nvm-dir/update-nvm.sh

#!/bin/bash
NVM_DIR="$(pwd)/nvm-scripts"

nvm_latest_version() {
  echo $(latest_tag)
}

nvm_source() {
  echo "https://github.com/creationix/nvm.git"
}

nvm_installed_version() {
  source "$NVM_DIR/nvm.sh"
  echo "$(nvm --version)"
}

latest_tag() {
# Source: https://github.com/svnpenn/a/blob/master/misc/git-describe-remote.awk
awk -F: 'BEGIN {
  FS = "[ /^]+"
  while ("git ls-remote ""'$(nvm_source)'""| sort -Vk2" | getline) {
    tag = $3
  }
  print tag
}'
}

install_nvm_from_git() {
  if [ -d "$NVM_DIR/.git" ]; then
    echo "=> nvm is already installed in $NVM_DIR, trying to update using git"
    printf "\r=> "
    cd "$NVM_DIR" && (command git fetch 2> /dev/null || {
      echo >&2 "Failed to update nvm, run 'git fetch' in $NVM_DIR yourself." && exit 1
    })
  else
    # Cloning to $NVM_DIR
    echo "=> Downloading nvm from git to '$NVM_DIR'"
    printf "\r=> "
    mkdir -p "$NVM_DIR"
    command git clone "$(nvm_source git)" "$NVM_DIR"
  fi
  cd "$NVM_DIR" && command git checkout --quiet $(nvm_latest_version)
  if [ ! -z "$(cd "$NVM_DIR" && git show-ref refs/heads/master)" ]; then
    if git branch --quiet 2>/dev/null; then
      cd "$NVM_DIR" && command git branch --quiet -D master >/dev/null 2>&1
    else
      echo >&2 "Your version of git is out of date. Please update it!"
      cd "$NVM_DIR" && command git branch -D master >/dev/null 2>&1
    fi
  fi
  return
}

nvm_install() {
  install_nvm_from_git
  echo 
  echo "nvm $(nvm_installed_version) is installed."
  nvm_reset
}

nvm_reset() {
  unset -f nvm_reset nvm_latest_version \
        nvm_source install_nvm_from_git \
    nvm_installed_version latest_tag \
    nvm_install
}

nvm_install
kinzhao commented 7 years ago

I upgrade nvm with brew:

$ brew update
$ brew install nvm
$ brew upgrade nvm
ljharb commented 7 years ago

@kinzhao nvm is not supported with homebrew whatsoever, so you shouldn't be installing, using, or upgrading it with brew.

d4nyll commented 6 years ago

Would it be worth adding a https://raw.githubusercontent.com/creationix/nvm/latest/install.sh script? You can add a hook that looks out for new tags and automatically copies the latest version as latest.

This way, when I add some instructions on a README.md, I can use the https://raw.githubusercontent.com/creationix/nvm/latest/install.sh URL instead of a version-specific one.

ljharb commented 6 years ago

@d4nyll no, that's just as dangerous as depending on * in your package.json - you should always only install from a hardcoded version number.

jkwuc89 commented 6 years ago

Seconding @fresheneesz comment above: Simply rerunning

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

upgraded nvm. That seems like the easiest and most straightforward way to do this.

PeterDaveHello commented 6 years ago

This patch: #1211 could also help with nvm self-upgrade

GitTom commented 6 years ago

I think that the issue of how to upgrade nvm (or not to) should be addressed in the main readme doc.

ljharb commented 6 years ago

@GitTom for all software that doesn’t mention an upgrade method, the upgrade method is “install the newer version in-place”. I’m not sure why that needs a separate callout.

whyboris commented 6 years ago

What's wrong with just using this method documented in README.md? curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

mockturtl commented 6 years ago

I think that the issue of how to upgrade nvm (or not to) should be addressed in the main readme doc.

It's addressed: 49f2c9501346

for all software that doesn’t mention an upgrade method, the upgrade method is “install the newer version in-place”. I’m not sure why that needs a separate callout.

Not all software is well-behaved. I remember Nvidia drivers in Windows being especially difficult. It's probably best to be explicit.

ktomk commented 3 years ago

When using git(1) to version control nvm, a one-liner updating to the latest available git tag within the current shell while working with $NVM_DIR variable (defaults here to "$HOME/.nvm"), YMMV:

nvm --version | sed 's/^/nvm update: from version: /' && (test -d "${NVM_DIR=$HOME/.nvm}" && cd "$NVM_DIR" && git fetch "$(git remote | head -1)" 'refs/tags/v*:refs/tags/v*' && git describe --always HEAD && git -c advice.detachedHead=false checkout -q "$(git tag -l --sort=-v:refname 'v*' | head -1)";) | sed 's/^/nvm update: from git revision: /' && . "$NVM_DIR"/nvm.sh && nvm --version | sed 's/^/nvm update: to version: /'

Example output:

nvm update: from version: 0.37.2
nvm update: from git revision: v0.37.2-9-gf3fa157
nvm update: to version: 0.38.0

HTH

BEE-JN commented 1 year ago

For windows: visit: NVM release Then you can download the 'nvm-update.exe' and update NVM.

ljharb commented 1 year ago

@BEE-JN false. that's an entirely different project.

andrew-aladev commented 1 year ago

You can update your nvm using the following command:

curl -s -w '%header{location}' "https://github.com/nvm-sh/nvm/releases/latest/download/install.sh" | sed -e 's/\/\/github.com/\/\/raw.githubusercontent.com/' -e 's/\/releases\/download//' | xargs curl -o- | bash
whyboris commented 1 year ago

Hope it's not rude to share another open source project that performs a similar function: fnm 🙇

https://github.com/Schniz/fnm

Fast and simple Node.js version manager, built in Rust

Respects the .nvmrc and is faster than nvm (I switched half a year ago and have been very happy) ❤️

andrew-aladev commented 1 year ago

fnm is a good example: it has installation script for latest version in readme without annoying fixed version.