tkareine/chnode

Add Homebrew support

Closed this issue · 4 comments

Homebrew provides several versions of Node:

$ brew search node
==> Formulae
heroku/brew/heroku-node    node-sass                  nodebrew
libbitcoin-node            node@10                    nodeenv
linode-cli                 node@12                    nodenv
llnode                     node@14                    tkareine/chnode/chnode
node                       node@16                    ode
node-build                 node_exporter

When running brew install node@12 node@14 node@16 it installs the formulae into /usr/local/Cellar/node@<version> directories:

$ ls /usr/local/Cellar/node*
/usr/local/Cellar/node@12:
12.22.12_1

/usr/local/Cellar/node@14:
14.20.1

/usr/local/Cellar/node@16:
16.17.1

I would expect these .zshrc configurations to work with Chnode but they do not (the first one would be the best as we don't hardwire the Node version into the path):

CHNODE_NODES_DIR=/usr/local/Cellar/node*
source /usr/local/opt/chnode/share/chnode/chnode.sh
source /usr/local/opt/chnode/share/chnode/auto.sh
precmd_functions+=(chnode_auto)
source /usr/local/opt/chnode/share/chnode/chnode.sh
source /usr/local/opt/chnode/share/chnode/auto.sh
precmd_functions+=(chnode_auto)
CHNODE_NODES+=(/usr/local/Cellar/node@12)
CHNODE_NODES+=(/usr/local/Cellar/node@14)
CHNODE_NODES+=(/usr/local/Cellar/node@16)
source /usr/local/opt/chnode/share/chnode/chnode.sh
source /usr/local/opt/chnode/share/chnode/auto.sh
precmd_functions+=(chnode_auto)
CHNODE_NODES+=(/usr/local/Cellar/node@12,/usr/local/Cellar/node@14,/usr/local/Cellar/node@16)

Could you add support to the first configuration? And what am I doing wrong with the second and third configurations?

CHNODE_NODES_DIR=/usr/local/Cellar/node*

With Zsh:

CHNODE_NODES_DIR=/usr/local/Cellar/node*
typeset -p CHNODE_NODES_DIR

Output:

typeset CHNODE_NODES_DIR='/usr/local/Cellar/node*'

It's a path that does not exist (the shell didn't expand the star glob here). Thus chnode does find any Node.js installations under it.

I don't think chnode should expand such a path. It would be confusing.

CHNODE_NODES+=(/usr/local/Cellar/node@14)

With Zsh:

source /usr/local/opt/chnode/share/chnode/chnode.sh
CHNODE_NODES+=(/usr/local/Cellar/node@14)
chnode 14

Output:

chnode: /usr/local/Cellar/node@14/bin/node not executable

That's because /usr/local/Cellar/node@14 is not a root directory for a Node.js installation. Homebrew installs Node.js in a subdirectory there, at /usr/local/Cellar/node@14/14.20.1.

With Homebrew, it's better to use the symlinks Homebrew provides for you at /usr/local/opt/node@*:

source /usr/local/opt/chnode/share/chnode/chnode.sh
CHNODE_NODES+=(/usr/local/opt/node@14 /usr/local/opt/node@16)
chnode 14
typeset -p CHNODE_ROOT
node --version

Output:

export CHNODE_ROOT=/usr/local/opt/node@14
v14.20.1

CHNODE_NODES+=(/usr/local/Cellar/node@12,/usr/local/Cellar/node@14,/usr/local/Cellar/node@16)

Shell does not treat comma as a separator for array elements. Use the space char instead (see above).

Would the following work for you?

mkdir -p ~/.nodes
ln -s /usr/local/opt/node@14 ~/.nodes/node-14
ln -s /usr/local/opt/node@16 ~/.nodes/node-16
source /usr/local/opt/chnode/share/chnode/chnode.sh
chnode
chnode 16
typeset -p CHNODE_ROOT
node --version

Output:

   node-14
   node-16
export CHNODE_ROOT=/Users/tkareine/.nodes/node-16
v16.17.1

The symlinks you created would stay intact whenever Homebrew upgrades the Node.js installation the symlink points at.

In addition, using the ~/.nodes directory gives you control over the tool you use to install different Node.js versions. Nothing prevents you from using another tool besides Homebrew to install Node.js versions into the directory (or to symlink to installation paths elsewhere).

Thanks a lot for the detailed answer! Your CHNODE_NODES solution and your symbolic link solution both solve the Homebrew problem. I think the README deserves to be updated as Homebrew is mainstream on macOS. Homebrew does need not be mentioned specifically, but the multi-value CHNODE_NODES trick (the space separator for array items) and the symbolic link trick (versions located in the ~/.nodes default CHNODE_NODES_DIR and pointing to the root Node directories) would be a great addition.

Ok, I clarified the documentation.

Amazing, thank you very much!