Je prends l'exemple de nodejs, car c'était mon besoin, mais ça pourrait fonctionner avec beaucoup de logiciels/outils/plateformes différent·e·s.

Avant de foncer tête baissée vers mes techniques, je vous recommande de tester en priorité des outils plus avancés et plus pratique comme nvm ou nvm-windows ou nodist ou un autre outil de ce genre (par exemple pour le monde jvm : sdkman). Dans mon cas je n'ai pas réussi à utiliser ces outils à cause d'un combo : proxy trop filtrant et/ou verrou sur la machine trop fort et/ou droits utilisateurs un peu trop bizarre et/ou Windows…

Mes exemples ont été testés sous Windows avec git bash, mais tout doit fonctionner parfaitement sous Linux, Mac ou un WSL 1/2

Un système de lien

Ma première idée a été de mettre en place la même architecture que ce que font pas mal d'outil : avoir plusieurs versions installées à partir de zip et faire un lien vers le dossier.

Pour ça il faut télécharger les versions qu'on veut (dans mon cas nodejs 14 et 16) quelque part, dans mon cas dans le dossier C:\Apps (j'ai donc deux dossiers C:\Apps\nodejs-v14-win-x86_64 et C:\Apps\nodejs-v14-win-x86_64). Ensuite on va ajouter quelques lignes dans le .bashrc :

function use_node14() {
    rm -f /c/Apps/nodejs-current
    ln -s /c/Apps/nodejs-v14-win-x86_64 /c/Apps/nodejs-current
}

function use_node16() {
    rm -f /c/Apps/nodejs-current
    ln -s /c/Apps/nodejs-v16-win-x86_64 /c/Apps/nodejs-current
}

use_node16
export PATH=/c/Apps/nodejs-current:$PATH

Quand on appelle une des deux fonctions, on supprime le lien actuel pour directement le recréer en pointant vers le bon dossier. Par défaut on appelle la fonction use_node16 pour configurer pour node 16. Et à la fin on édite le PATH pour que le système aille chercher node dans /c/Apps/nodejs-current en premier.

J'aime bien cette solution qui évite de toucher à la variable PATH en continue, mais chez moi ça n'a pas fonctionné. J'ai déjà fait fonctionner quelque chose de similaire sous Linux, donc je suis plutôt convaincu que c'est censé fonctionner, mais j'avais des erreurs m'indiquant l'impossibilité de résoudre le lien vers le programme, alors que via l'explorer je pouvais accéder au bon dossier via le lien… la magie de windows j'ai envie de dire…

Jouer sur la priorité du PATH

Je me suis rabattue sur une solution plus simple et sans lien : modifier le PATH directement.

En gardant les mêmes dossiers d'installation pour les différentes version de node, j'ai modifié les fonctions comme ça :

function use_node14() {
    export PATH=/c/Apps/nodejs-v14-win-x86_64:$PATH
}

function use_node16() {
    export PATH=/c/Apps/nodejs-v16-win-x86_64:$PATH
}

use_node16

Cette méthode fonctionne sur le principe de priorité de résolution. En gros : quand on tape une commande, par exemple node --version, le système va parcourir les entrées de la variable $PATH pour voir s'il trouve un programme node dans le dossier, si oui il exécute ce programme, sinon il passe l'entrée suivante. Donc comme on ajoute le chemin de la version qu'on veut en premier, il va commencer par cette version.

Bien que parfaitement fonctionnelle, cette méthode peut créer une pollution du PATH, car le système devra tenter de résoudre chaque commande potentiellement plusieurs fois dans chaque dossier de nodejs avant de trouver le bon chemin (c'est surtout vrai si dans la même console on alterne plusieurs fois entre node 14 et node 16). En soi ce parcours n'est pas très long, mais ça peut le devenir si comme dans mon cas vous avez un antivirus qui analyse chaque entrée/sortie sur le disque. Après dans la pratique, je sais que je vais peu alterner entre différente version dans une seule console donc aucun souci.

Conclusion

Il y a des outils qui simplifient la vie, mais parfois on peut obtenir le fonctionnement minimum de ces outils simplement en comprenant comment le système fonctionne. C'est le cas ici, et c'est assez plaisant comme c'est simple de faire fonctionner le tout 😎