Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
abejfehr committed Feb 13, 2022
0 parents commit a8ac788
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"deno.enable": true,
"deno.lint": true
}
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Fast NVM Switcher

This repository provides an alternative shell configuration (specifically for zsh) switches node versions on directory change, but in a _significantly_ faster way than the default configuration provided in nvm's setup.

## How to use


Begin by installing [nvm](https://github.com/nvm-sh/nvm) using the download script from their README.

If you already have nvm installed, remove anything nvm-related you might already have from your local .zshrc file.

Next, run the following script to download the `resolve_node_version` binary to your machine:

```sh
curl -O --output-dir $HOME/.nvm URL_ONCE_I_HAVE_IT
```

Add the following lines to your .zshrc

```sh
export NVM_DIR="${HOME}/.nvm"

# Lazy loads nvm when running any nvm command
nvm() {
[[ -s "${NVM_DIR}/nvm.sh" ]] && \. "${NVM_DIR}/nvm.sh"
nvm $@
}

# Resolves node version based on nearest nvmrc and adds its directory to the PATH
load-nvmrc() {
NODE_PATH=$(${NVM_DIR}/resolve_node_version)
PATH="$PATH:$NODE_PATH"
}

autoload -U add-zsh-hook
add-zsh-hook chpwd load-nvmrc
load-nvmrc
```

## Limitations

- This script only supports the 'default' alias, it won't work with lts, etc.
- The install script assumes that you're using the default `$NVM_DIR` of `$HOME/.nvm`
3 changes: 3 additions & 0 deletions build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

deno compile --allow-read --allow-env --output ./bin/resolve_node_version ./resolve_node_version.ts
61 changes: 61 additions & 0 deletions resolve_node_version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { dirname, fromFileUrl, join } from "https://deno.land/std/path/mod.ts";
import { existsSync } from "https://deno.land/std/fs/mod.ts";
import * as semver from "https://deno.land/x/semver/mod.ts";

// this program's whole purpose is to just output to stdout the path to the node version to the shell can put it on the path

const getNpmrcPath = () => {
let pwd = dirname(fromFileUrl(import.meta.url));

while (pwd !== '/') {
pwd = dirname(pwd); // goes up one

const nvmrcPath = join(pwd, '.nvmrc');

if (existsSync(nvmrcPath)) {
return nvmrcPath;
}
}
}

const getNodePath = async (version: string) => {
const versions: string[] = [];

const isFuzzyVersion = !semver.valid(version, { loose: true })

for await (const dirEntry of Deno.readDir(`${Deno.env.get('NVM_DIR')}/versions/node/`)) {
if (dirEntry.isDirectory) {
versions.push(dirEntry.name);
}
}

const resolvedVersion = semver.maxSatisfying(versions, `${isFuzzyVersion ? '^' : ''}${version}`);

if (!resolvedVersion) {
console.error("Unable to find node version that matches, please run 'nvm install'");
Deno.exit(1);
}

return `${Deno.env.get('NVM_DIR')}/versions/node/${resolvedVersion}/bin`;
}

const main = async () => {
const npmrcPath = getNpmrcPath();

let version: string | undefined;

if (npmrcPath) {
version = await Deno.readTextFile(npmrcPath);
}

if (!version) {
// Get the nvm "default" alias
version = await Deno.readTextFile(`${Deno.env.get('NVM_DIR')}/alias/default`)
}

const nodePath = await getNodePath(version);

console.log(nodePath)
}

main();

0 comments on commit a8ac788

Please sign in to comment.