nvm-sh / nvm

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

Add `prune` support to nvm #1195

Open jbergstroem opened 8 years ago

jbergstroem commented 8 years ago

I was exploring setting up a machine that would continuously test against different versions of node. Seeing how nvm is very easy to use for installing (think nightly nvm i 6 etc) my next concern was removing older versions of node. A nvm prune suggestively should remove all older versions of each major; for instance:

$ nvm ls
        v0.12.7
         v6.3.0
->       v6.3.1
default -> 6.3 (-> v6.3.1)
node -> stable (-> v6.3.1) (default)
stable -> 6.3 (-> v6.3.1) (default)
iojs -> N/A (default)
lts/* -> lts/argon (-> N/A)
lts/argon -> v4.4.7 (-> N/A)

$ nvm prune
# Cleaning older versions of node:
# - Uninstalled node v6.3.0
# - did x.y.z
$ nvm ls
        v0.12.7
->       v6.3.1
default -> 6.3 (-> v6.3.1)
node -> stable (-> v6.3.1) (default)
stable -> 6.3 (-> v6.3.1) (default)
iojs -> N/A (default)
lts/* -> lts/argon (-> N/A)
lts/argon -> v4.4.7 (-> N/A)

If passed a major (6, 0.12, etc), only clean that major (6.3.0 && 6.3.1 -> 6.3.1)

ljharb commented 8 years ago

So the idea is that nvm prune would uninstall all but the latest node, nvm prune X would prune everything under that X that wasn't the latest, etc?

What happens if you're on 6.3.0, and you run nvm prune or nvm prune 6?

jbergstroem commented 8 years ago

@ljharb said: So the idea is that nvm prune would uninstall all but the latest node, nvm prune X would prune everything under that X that wasn't the latest, etc?

Yes. Similar to how other package managers provide cleanup functions. The difference here is that nvm obviously should allow 6.3.0 and 6.3.1 installed simultaneously whereas other package managers might choose to replace versions.

@ljharb said: What happens if you're on 6.3.0, and you run nvm prune or nvm prune 6?

Nothing. nvm prune should be considered safe, meaning it will only remove versions from 'majors' that has more than one version installed. Also, if one version is set as default, this should also be seen as sticky.

ljharb commented 8 years ago

I mean if you have 6.3.0 and 6.3.1 and 6.2.9 installed, and you're on 6.3.0, and you run nvm prune

ljharb commented 8 years ago

What about .nvmrc versions, which are PWD-sensitive? Shouldn't those be sticky too?

jbergstroem commented 8 years ago

I suggest prune calling uninstall, meaning whatever barriers being in place there should be applied as well.

ljharb commented 8 years ago

OK, so: nvm prune: 1) get all versions (nvm_ls), filter out nvm current and nvm version node ("whatever the latest is in that list") 2) call nvm uninstall on each one

nvm prune X: 1) get all versions filtered (nvm_ls X), filter out nvm current and "whatever the latest is in that list" 2) call nvm uninstall on each one

jbergstroem commented 8 years ago

Sounds about right. Regarding error-handling I think we should follow the current decision-making. Do you always exit on first error? I think that would be a good idea.

ljharb commented 8 years ago

With nvm uninstall, it checks permissions first, and only proceeds if it thinks it'll be able to completely remove everything. Since this is a "batch" argument, there's no precedent for how to handle an error in one job.

jbergstroem commented 8 years ago

I still think that bailing early is the best path here but I don't have a strong opinion; happy to do whatever consensus would be.

ljharb commented 8 years ago

I am concerned that this feature could be unnecessarily destructive, especially if the default is "everything" - i'd certainly prefer nvm prune to require a numeric version filter.

jbergstroem commented 8 years ago

I'd be ok with that. Majors would likely be known in a test environment.

bjfisher-cbg commented 4 years ago

+1

relnetops commented 3 years ago

Ping. What's the status of this request?

ljharb commented 3 years ago

@relnetops There's been no PR, and I'm still concerned about the destructiveness.

Farenheith commented 1 year ago

I locally use a simple script to get rid of old node versions from nvm:

#!/usr/bin/bash
a=$(nvm ls | grep -Pzo '\sv\d+\.\d+\.\d+')
b=(`echo $a | tr ' ' ' '`)
lastVersion=''
lastVersionComplete=''
for element in "${b[@]}"; do
 currentVersion=$(echo "$element" | grep -Pzo '(?<=v)\d+')
 echo 'checking '$currentVersion', '$element
 if [[ ! -z $element ]]; then
  if [ "$currentVersion" = "$lastVersion" ]; then
    if [ ! -z $lastVersionComplete ]; then
      echo 'uninstalling '$lastVersionComplete
      nvm uninstall "$lastVersionComplete"
    fi
  else
    lastVersion=$currentVersion
  fi
 fi
 lastVersionComplete=$element
done

Take a look:

Before image

Running the script: Run it as . ~/prune_nvm.sh, so you use your current env image

After it: image

With this script, I preserve different major versions but delete old minor or patch ones. I also use a script that automatically installs (or sets) the node version specified in .nvmrc as soon as I access its folder:

loadnvmrc() {
  local node_version="$(nvm version)"
  local nvmrc_path="$(nvm_find_nvmrc  )"

  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")

    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$node_version" ]; then
      nvm use
    fi
  elif [ "$node_version" != "$(nvm version default)" ]; then
    echo "Reverting to nvm default version"
    nvm use default
  fi
}
loadnvmrc
cd() {
  builtin cd "$1"
  loadnvmrc
}