You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.6 KiB

6 years ago
<h1 align="center">
Fast Node Manager (<code>fnm</code>)
<img alt="Amount of downloads" src="https://img.shields.io/github/downloads/Schniz/fnm/total.svg?style=flat" />
5 years ago
<a href="https://dev.azure.com/Schniz/fnm/_build/latest?definitionId=1?branchName=master"><img alt="Build Status" src="https://dev.azure.com/Schniz/fnm/_apis/build/status/Schniz.fnm?branchName=master" /></a>
6 years ago
</h1>
6 years ago
> :rocket: Fast and simple Node.js version manager, built in native ReasonML
6 years ago
6 years ago
<div align="center">
<img src="./docs/fnm.svg" alt="Blazing fast!">
6 years ago
</div>
6 years ago
6 years ago
## Features
:sparkles: Single file, easy installation, instant startup
:rocket: Built with speed in mind
:thinking: Works with `.nvmrc` and `.node-version` files
6 years ago
6 years ago
## Installation
6 years ago
### Using Homebrew (OSX)
```bash
brew install Schniz/tap/fnm
```
[This is a custom tap I'm maintaining](https://github.com/Schniz/homebrew-tap), and will be used until fnm will move to the official one.
### Using a script
For `bash`, `zsh` and `fish` shells, there's an [automatic installation script](./.ci/install.sh):
```bash
curl -fsSL https://github.com/Schniz/fnm/raw/master/.ci/install.sh | bash
```
### Upgrade
Upgrading `fnm` is almost the same as installing it. To prevent duplication in your shell config file add `--skip-shell` to install command.
Parameterize the install script for relative install of fnm (#48) What are your thoughts on parameterizing the install script for local install? I know this seems weird but it means that I don't have to rely on developers having any tools already installed except bash and some way to edit the files. Here is an actual example script setup I would use. Here is an example local install script `installLocal.sh` ```bash #!/usr/bin/env bash DESIRED_NODE_VERSION=v$(cat package.json | grep -Ei "\"node\"" | grep -Eoi "[0-9]+\.[0-9]+\.[0-9]+") export FNM_DIR="$(pwd)/.fnm" if [ ! -d "$FNM_DIR" ]; then curl 'https://raw.githubusercontent.com/Schniz/fnm/master/.ci/install.sh' | INSTALL_DIR=`pwd` bash fi set -e NODE_DIR="$FNM_DIR/node-versions/$DESIRED_NODE_VERSION/installation/bin" export PATH=$FNM_DIR:$NODE_DIR:$PATH #TODO: support fish eval `fnm env --multi` if [ ! -f "$NODE_DIR/node" ]; then fnm install $DESIRED_NODE_VERSION fi sumOfPackageJson() { cat package.json | md5sum | cut -d' ' -f1 } if [ ! -f ".packageRevision" ] || [ "$(cat .packageRevision)" != "$(sumOfPackageJson)" ]; then sumOfPackageJson > .packageRevision npm install fi ``` then in script called `nodew` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh node "$@" ``` and `npmw` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh npm "$@" ``` and for completeness sake I usually go one step further and do an `appw` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh node ./app/index.js "$@" ```
6 years ago
#### Parameters
`--install-dir`
Set a custom directory for fnm to be installed. The default is `$HOME/.fnm`.
`--skip-shell`
Skip appending shell specific loader to shell config file, based on the current user shell, defined in `$SHELL`. e.g. for Bash, `$HOME/.bashrc`. `$HOME/.zshrc` for Zsh. For Fish - `$HOME/.config/fish/config.fish`
`--force-install`
MacOS installations using the installation script are deprecated in favor of the Homebrew formula, but this forces the script to install using it anyway.
6 years ago
Example:
Parameterize the install script for relative install of fnm (#48) What are your thoughts on parameterizing the install script for local install? I know this seems weird but it means that I don't have to rely on developers having any tools already installed except bash and some way to edit the files. Here is an actual example script setup I would use. Here is an example local install script `installLocal.sh` ```bash #!/usr/bin/env bash DESIRED_NODE_VERSION=v$(cat package.json | grep -Ei "\"node\"" | grep -Eoi "[0-9]+\.[0-9]+\.[0-9]+") export FNM_DIR="$(pwd)/.fnm" if [ ! -d "$FNM_DIR" ]; then curl 'https://raw.githubusercontent.com/Schniz/fnm/master/.ci/install.sh' | INSTALL_DIR=`pwd` bash fi set -e NODE_DIR="$FNM_DIR/node-versions/$DESIRED_NODE_VERSION/installation/bin" export PATH=$FNM_DIR:$NODE_DIR:$PATH #TODO: support fish eval `fnm env --multi` if [ ! -f "$NODE_DIR/node" ]; then fnm install $DESIRED_NODE_VERSION fi sumOfPackageJson() { cat package.json | md5sum | cut -d' ' -f1 } if [ ! -f ".packageRevision" ] || [ "$(cat .packageRevision)" != "$(sumOfPackageJson)" ]; then sumOfPackageJson > .packageRevision npm install fi ``` then in script called `nodew` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh node "$@" ``` and `npmw` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh npm "$@" ``` and for completeness sake I usually go one step further and do an `appw` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh node ./app/index.js "$@" ```
6 years ago
```bash
curl -fsSL https://github.com/Schniz/fnm/raw/master/.ci/install.sh | bash -s -- --install-dir "./.fnm" --skip-shell
Parameterize the install script for relative install of fnm (#48) What are your thoughts on parameterizing the install script for local install? I know this seems weird but it means that I don't have to rely on developers having any tools already installed except bash and some way to edit the files. Here is an actual example script setup I would use. Here is an example local install script `installLocal.sh` ```bash #!/usr/bin/env bash DESIRED_NODE_VERSION=v$(cat package.json | grep -Ei "\"node\"" | grep -Eoi "[0-9]+\.[0-9]+\.[0-9]+") export FNM_DIR="$(pwd)/.fnm" if [ ! -d "$FNM_DIR" ]; then curl 'https://raw.githubusercontent.com/Schniz/fnm/master/.ci/install.sh' | INSTALL_DIR=`pwd` bash fi set -e NODE_DIR="$FNM_DIR/node-versions/$DESIRED_NODE_VERSION/installation/bin" export PATH=$FNM_DIR:$NODE_DIR:$PATH #TODO: support fish eval `fnm env --multi` if [ ! -f "$NODE_DIR/node" ]; then fnm install $DESIRED_NODE_VERSION fi sumOfPackageJson() { cat package.json | md5sum | cut -d' ' -f1 } if [ ! -f ".packageRevision" ] || [ "$(cat .packageRevision)" != "$(sumOfPackageJson)" ]; then sumOfPackageJson > .packageRevision npm install fi ``` then in script called `nodew` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh node "$@" ``` and `npmw` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh npm "$@" ``` and for completeness sake I usually go one step further and do an `appw` ```bash #!/usr/bin/env bash cd "$( dirname "${BASH_SOURCE[0]}" )" source ./installLocal.sh node ./app/index.js "$@" ```
6 years ago
```
### Manually
- Download the [latest release binary](https://github.com/Schniz/fnm/releases) for your system
- Make it available globally on `$PATH`
- Add the following line to your `.bashrc`/`.zshrc` file:
6 years ago
```bash
eval "`fnm env --multi`"
6 years ago
```
If you are using [fish shell](https://fishshell.com/), add this line to your `config.fish` file:
```fish
fnm env --multi | source
```
6 years ago
## Usage
You can always use `fnm --help` to read the docs:
### `fnm install [VERSION]`
Installs `[VERSION]`. If no version provided, it will install the version specified in the `.nvmrc` file located in the current working directory.
### `fnm use [VERSION]`
Activates `[VERSION]` as the current Node version. If no version provided, it will activate the version specified in the `.nvmrc` or `.node-version` file located in the current working directory.
### `fnm ls`
Lists the installed Node versions.
### `fnm ls-remote`
Lists the Node versions available to download remotely.
### `fnm alias [VERSION] [NAME]`
Aliases a Node version to a given name.
### `fnm default [VERSION]`
Aliases a Node version as default. Uses `fnm alias` underneath.
### `fnm env [--multi] [--shell=fish|bash|zsh] [--node-dist-mirror=URI] [--use-on-cd] [--fnm-dir=DIR] [--log-level=quiet|error|all]`
Prints the required shell commands in order to configure your shell, Bash compliant by default.
- Providing `--multi` will output the multishell support, allowing a different current Node version per shell
- Providing `--shell=fish` will output the Fish-compliant version. Omitting it and `fnm` will try to infer the current shell based on the process tree
- Providing `--node-dist-mirror="https://npm.taobao.org/dist"` will use the Chinese mirror of Node.js
- Providing `--use-on-cd` will also output a script that will automatically change the node version if a `.nvmrc`/`.node-version` file is found
- Providing `--fnm-dir="/tmp/fnm"` will install and use versions in `/tmp/fnm` directory
## Future Plans
6 years ago
- [ ] Feature: `fnm use --install`
6 years ago
- [ ] Linux: Replace `tar` with a statically linked library too (for ungzip + untar)
- [ ] Windows Support? @ulrikstrid has worked hard to make it compile on Windows, but it will probably need to have different code paths and logic. We can probably make another program and share feature tests with it, instead of relying on Windows for this very-unixy binary.
6 years ago
## Contributing
PRs welcome :tada:
### Developing:
6 years ago
```
npm install -g esy
git clone https://github.com/Schniz/fnm.git
cd fnm/
6 years ago
esy install
esy bootstrap
6 years ago
esy build
```
### Running Binary:
6 years ago
After building the project, you can run the main binary that is produced.
```
esy x fnm.exe
6 years ago
```
### Running Tests:
6 years ago
```
6 years ago
# Runs some smoke-unity test
6 years ago
esy test
6 years ago
# Runs the feature tests
feature_tests/run.sh
6 years ago
```