• Stars
    star
    1,580
  • Rank 28,437 (Top 0.6 %)
  • Language
    Shell
  • License
    ISC License
  • Created almost 14 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Virtual Environments for Node

nave

Virtual Environments for Node.

Switch out your node version and global npm install space in one command. Supports named environments. Uses subshells by default so that you can ^D or exit out of an environment quickly.

No need to edit .bashrc or .profile, just install and go.

Installation

If you want a global nave command, you could install this thing with npm. But that's not really necessary. You can run the nave.sh shell script from here, or symlink it wherever you want, or even just download the script and just put it where you want it.

curl https://raw.githubusercontent.com/isaacs/nave/main/nave.sh > /usr/local/bin/nave
chmod 0755 /usr/local/bin/nave

with npm

If you have npm, presumably you already have Node, so it's a tiny bit silly, but maybe you like installing the top-level Node some other way, and install your subshell version switcher with npm. Why is a bash program in npm anyway? It's fine. Bits don't judge.

npm install -g nave

Usage

To use a version of node, you do this:

nave use <some version>

If you want to name a virtual env, you can do this:

nave use <some name>

If that virtual env doesn't already exist, it'll prompt you to choose a version.

Both of these commands drop you into a subshell. Exit the shell with exit or ^D to go back from whence you came.

Here's the full usage statement:

Usage: nave <cmd>

COMMANDS

  install <version>     Install the version specified (ex: 12.8.0)
  install <name> <ver>  Install the version as a named env
  use <version>         Enter a subshell where <version> is being used
  use <ver> <program>   Enter a subshell, and run "<program>", then exit
  use <name> <ver>      Create a named env, using the specified version.
                        If the name already exists, but the version differs,
                        then it will update the link.
  usemain <version>     Install in /usr/local/bin (ie, use as your main nodejs)
  clean <version>       Delete the source code for <version>
  uninstall <version>   Delete the install for <version>
  ls                    List versions currently installed
  ls-remote             List remote node versions
  ls-all                List remote and local node versions
  latest                Show the most recent dist version
  cache                 Clear or view the cache
  help                  Output help information
  auto                  Find a .naverc and then be in that env
                        If no .naverc is found, then alias for 'nave exit'
  auto <dir>            cd into <dir>, then find a .naverc, and be in that env
                        If no .naverc is found, then alias for 'nave exit' in
                        the specified directory.
  auto <dir> <cmd>      cd into <dir>, then find a .naverc, and run a command
                        in that env
                        If no .naverc is found, then alias for 'nave exit <cmd>'
                        in the specified directory.
  should-auto           Exits with 1 if the nave auto env already
                        matches the config, or 0 if a change should
                        be made (ie, by calling 'nave auto')
                        An explicit call to 'nave use' or 'nave exit' will
                        tell nave that it should NOT auto.
  get <variable>        Print out various nave config values.
  exit                  Unset all the NAVE environs (use with 'exec')
  exit <cmd>            Run the specified command in a nave-free environment
                        (Note that nave will still set NAVE_EXIT=1 in order to
                        prevent 'nave should-auto' from evaluating true.)

VERSION STRINGS

  Any command that calls for a version can be provided any of the
  following "version-ish" identifies:

  - x.y.z       A specific SemVer tuple
  - x.y         Major and minor version number
  - x           Just a major version number
  - lts         The most recent LTS (long-term support) node version
  - lts/<name>  The latest in a named LTS set. (argon, boron, etc.)
  - lts/*       Same as just "lts"
  - latest      The most recent (non-LTS) version
  - stable      Backwards-compatible alias for "lts".

  To exit a nave subshell, type 'exit' or press ^D.
  To run nave *without* a subshell, do 'exec nave use <version>'.
  To clear the settings from a nave env, use 'exec nave exit'

ENVIRONMENT VARIABLES

  The following environment variables can be set to change nave's behavior.

  NAVE_DIR        Root directory for nave to operate in.  Defaults to
                  $XDG_CONFIG_HOME/nave if set (eg, ~/.config/nave), or
                  ~/.nave otherwise.
  NAVE_NPX        Set this to '1' to add node_modules/.bin to the PATH
  NAVE_DEBUG      Set this to '1' to run in debug mode.
  NAVE_CACHE_DUR  Duration in seconds to cache version information (86400)
  NAVEUA          User-agent header to send when fetching version information
  NAVE_SRC_ONLY   Set to '1' to *only* build node from source, and never use
                  binary distributions.  (This is much slower!)
  NAVE_JOBS       Set to the number of JOBS to use when building node.
                  Defaults to the number of CPUs on the system.
  NODEDIST        The distribution server to fetch node from.  Defaults to
                  https://nodejs.org/dist
  NAVE_CONFIG     Arguments to pass to ./configure when building from source.

  Nave sets the following environment variables when in use:

  NAVE            A descriptive string of the nave setting in use.
  NAVENAME        The name, in named subshells, otherwise $NAVEVERSION
  NAVEVERSION     The version of node in use.
  NAVELVL         The number of subshells currently in use (like bash $SHLVL)
  NAVE_LOGIN      '1' in interactive nave subshells, '0' otherwise.
  NAVE_ROOT       Location of nave installed environments
  NAVE_SRC        Location of downloaded Node.js source
  NAVE_AUTO_RC    The .naverc file used by 'nave auto'
  NAVE_AUTO_CFG   The contents of the .naverc file used by 'nave auto'

CONFIGURATION FILES

  Nave subshells will source the same .bashrc, .bash_profile, .zprofile, etc.
  configuration files as normal shells, based on whether it is being run as a
  login shell, or to run a specific command.

  In addition, the following files are sourced in all nave subshells if found,
  after the normal shell profile files, in the following order, based on the
  resulting environment variables described above. When run in a subdirectory,
  nave will walk up the directory tree looking for any of these that it finds,
  but will not walk up further than any folder containing a '.git' entry.

    .nave_profile_${NAVE}
    .nave_profile_${NAVENAME}, if a named environment
    .nave_profile_${NAVEVERSION}, eg .nave_profile_16.19.0
    .nave_profile_${NAVEVERSION major.minor}, eg .nave_profile_16.19
    .nave_profile_${NAVEVERSION major}, eg .nave_profile_16
    .nave_profile

  Finally, it will always source ${NAVEDIR}/../.naverc if present.
  (eg, ~/.config/.naverc)

  These may be used to set project-specific confirations, env variables, or
  other behavior based on the Nave environment in use, without the use of
  configuration files in the home directory.

  The 'nave auto' command will walk up the directory tree looking for a
  '.naverc' or '.nvmrc' file, and use the contents as arguments to 'nave use'.

Subshell-free operation

If you prefer to not enter a subshell, just run nave with exec

exec nave use lts/argon

You could even add something like this to your .bashrc file to save on typing:

n () {
  exec nave "$@"
}

Running shell script with specific version of Node.js

If there is need to run a shell script with version of node.js provided by nave following snippet can be inserted into script:

[ "${IN_SUBSHELL}" != "$0" ] && exec env IN_SUBSHELL="$0" nave use 5.0.0 bash "$0" "$@" || :

AUTOMAGICAL!

You can put a .naverc file in the root of your project (or anywhere). This file should contain the version that you want to use. It can be something like lts/boron or 16 or latest

echo lts/boron > ~/projects/my-project/.naverc

Then you can run nave auto to load the appropriate environment.

BUT THAT'S NOT NEARLY MAGICAL OR AUTO ENOUGH FOR ME THOUGH

If you want to get even more absurd/automated, put this in your bash settings (like ~/.bashrc or whatever)

alias cd='exec nave auto'

and then every time you cd into a different folder, it'll automatically load the correct nave settings, or exit nave-land if no automatic stuff could be found.

Note that doing this will also cause it to exit the nave environment when you cd to a directory that doesn't have a nave setting, so it can interfere with "normal" nave operation.

Also, aliasing cd is a very all-consuming type of change to make to one's system. You might wish to give it some other name, so that you can switch directories without affecting environment variables as a potentially surprising side effect, or even just run exec nave auto as an explicit action whenever you want this behavior to happen.

Bottom line, it's your shell, and I hope that this helps you enjoy it more :)

NO THAT'S TOO MAGICAL, BE JUST SLIGHTLY LESS MAGICAL THAN THAT

Ok, put this snippet in a PROMPT_COMMAND export in your bash profile (.bashrc or .bash_profile or whatever you use for that).

export PROMPT_COMMAND='nave should-auto && exec nave auto'

Now you'll always be in the configured nave environment in any project with a .naverc (or .nvmrc), and always not in a nave environment in your main shell in any folder that isn't set up for nave auto.

This has no effect on the normal nave subshells you get from nave use.

The output of your PROMPT_COMMAND is used for the main bash prompt, so you can also do some fancy stuff like this:

__prompt () {
  if nave should-auto; then
    exec nave auto
  if
  # Show the nave version in white-on-blue, but the "normal" node
  # version in green
  if [ "$NAVE" != "" ]; then
    echo -ne " \033[44;37mnode@$NAVE\033[0m"
  else
    echo -ne " \033[32mnode@$(node -p 'process.version.slice(1)' 2>/dev/null)\033[0m"
  fi
}
PS1="\\$ "
export PROMPT_COMMAND='__prompt'

env vars

  • $NAVE The current shell. Either a version, or a name and version.
  • $NAVE_NPX Set to "1" to add node_modules/.bin to the $PATH in all nave shells (including the main shell when exec nave auto is used).
  • $NAVE_AUTO_RC The .naverc file found by nave auto.
  • $NAVE_AUTO_CFG The contents of the .naverc file that was read when entering the nave auto environment.
  • $NAVENAME The name of the current shell. Equal to $NAVEVERSION in unnammed environments.
  • $NAVEVERSION The version of node that the current shell is pointing to. (This should comply with node -v.)
  • $NAVELVL The level of nesting in the subshell.
  • $NAVE_DEBUG Set to 1 to run nave in bash -x style.
  • $NAVE_DIR Set to the location where you'd like nave to do its business. Defaults to ~/.nave.
  • $NAVE_CONFIG Set this to an array of arguments to pass to ./configure. Defaults to ("--debug"). (Note that parens are required to supply multiple arguments. I use ("--debug" "--without-npm") on my own system, since I'm usually using nave to test npm, so installing it in the subshell doesn't help much.) This can be set in the ~/.naverc file, or in your normal ~/.bash{rc,_profile} files.
  • $NAVE_JOBS If set, this will be the number of jobs to run when building node. If this isn't set, it'll use the $JOBS env, then try to guess a reasonable value based on the number of CPUs, then fall back on 2 if sysctl -n hw.ncpu fails.
  • $NAVE_SRC_ONLY Set to "1" to only build from source, rather than fetching binaries.

Contributing

Patches welcome! Before spending too much time on a patch or feature request, please post an issue to see if it's something that's going to be accepted or have unforeseen consequences.

Patches will usually not be accepted if they break tests or cause coverage to drop below 100%. You can run tests with:

npm test
# or...
bash test/run.sh

And you can check coverage with:

npm run cov
# or...
COV=1 bash test/run.sh && open coverage-all/kcov-merged/nave.sh.*.html

The latest coverage report can be found at https://isaacs.github.io/nave/kcov-merged/index.html

Compatibility

Nave is a bash program. It can still do most of its functionality if you use zsh or fish as your shell, as long as you have bash somewhere, but some of the magical stuff won't work (since obviously that has to run inline in your shell with exec).

Nave requires bash. It will probably never work on Windows, or other systems lack a native Bourne Again Shell. Sorry. (Patches welcome if you can get it to work properly on Windows that do have bash, like WSL and Cygwin.)

Nave logins work with any shell, but executing a command in the nave environment (ie, nave use 12 node program.js) requires that your shell support the -c argument. (Bash, sh, zsh, and fish all work fine.)

Configuration

Nave will source ~/.naverc on initialization of a new subshell, if it exists and is readable.

You may control the place where nave puts things by setting the NAVE_DIR environment variable. However, note that this must be set somewhere other than ~/.naverc, since it needs to be set in the parent shell where the nave command is invoked.

By default, nave puts its stuff in ~/.nave/. If this directory does not exist and cannot be created, then it will attempt to use the location of the nave.sh bash script itself. If it cannot write to this location, then it will exit with an error.

Credits

nave borrows concepts, inspiration, and code from Tim Caswell's "nvm" and Kris Kowal's "sea" programs.

Sea is really nice, but is very tied to Narwhal. Also, it's a require.paths manager, which nave is not.

Nvm is also really nice, but has to be sourced rather than being run, and thus is a little bit wonky for some use cases. But it doesn't involve subshells, which makes it better for some others.

More Repositories

1

node-glob

glob functionality for node.js
TypeScript
8,123
star
2

rimraf

A `rm -rf` util for nodejs
JavaScript
5,309
star
3

node-lru-cache

A fast cache that automatically deletes the least recently used items
TypeScript
4,844
star
4

minimatch

a glob matcher in javascript
JavaScript
3,074
star
5

github

Just a place to track issues and feature requests that I have for github
2,196
star
6

node-graceful-fs

fs with incremental backoff on EMFILE
JavaScript
1,254
star
7

sax-js

A sax style parser for JS
JavaScript
1,046
star
8

node-tar

tar for node
JavaScript
755
star
9

tshy

JavaScript
653
star
10

st

A node module for serving static files. Does etags, caching, etc.
JavaScript
376
star
11

inherits

Easy simple tiny inheritance in JavaScript
JavaScript
352
star
12

cluster-master

Take advantage of node built-in cluster module behavior
JavaScript
276
star
13

minipass

A stream implementation that does more by doing less
TypeScript
237
star
14

once

Run a function exactly one time
JavaScript
216
star
15

yallist

Yet Another Linked List
JavaScript
198
star
16

server-destroy

When close() is just not enough
JavaScript
184
star
17

semicolons

When you require("semicolons"), THEY ARE REQUIRED.
JavaScript
145
star
18

slide-flow-control

A flow control library that fits in a slideshow
JavaScript
134
star
19

treeverse

Walk any kind of tree structure depth- or breadth-first. Supports promises and advanced map-reduce operations with a very small API.
JavaScript
126
star
20

multipart-js

JavaScript
123
star
21

reading-list

a list of books I recommend
121
star
22

node-touch

touch(1) for node
JavaScript
121
star
23

async-cache

Cache your async lookups and don't fetch the same thing more than necessary.
JavaScript
119
star
24

catcher

TypeScript
116
star
25

ttlcache

TypeScript
116
star
26

core-util-is

The util.is* functions from Node core
JavaScript
98
star
27

dezalgo

Contain async insanity so that the dark pony lord doesn't eat souls
JavaScript
89
star
28

github-flavored-markdown

Deprecated. Use marked instead.
JavaScript
79
star
29

node-bench

JavaScript
71
star
30

free-as-in-hugs-license

A (Not OSI-Approved) software license you may use if you wish
70
star
31

sigmund

Quick and dirty psychoanalysis for objects
JavaScript
67
star
32

minizlib

A smaller, faster, zlib stream built on http://npm.im/minipass and Node.js's zlib binding.
JavaScript
66
star
33

inflight

Add callbacks to requests in flight to avoid async duplication
JavaScript
66
star
34

fast-list

A fast O(1) push/pop/shift/unshift thing
JavaScript
66
star
35

gist-cli

A gist cli client written in Node
JavaScript
64
star
36

dotfiles

My Dot Files
Shell
63
star
37

wrappy

Callback wrapping utility
JavaScript
56
star
38

block-stream

A stream of fixed-size blocks
JavaScript
52
star
39

isexe

Minimal module to check if a file is executable.
TypeScript
48
star
40

.vim

My vim settings
Vim Script
47
star
41

char-spinner

Put a little spinner on process.stderr, as unobtrusively as possible.
JavaScript
43
star
42

st-example

an example of serving static files easily in node using the st module
JavaScript
40
star
43

jackspeak

A very strict and proper argument parser.
TypeScript
38
star
44

templar

A lightweight template thing for node http servers
JavaScript
37
star
45

nosync

Prevent sync functions in your node programs after first tick
JavaScript
37
star
46

use-strict

Makes all subsequent modules in Node get loaded in strict mode.
JavaScript
37
star
47

ssh-key-decrypt

Decrypt and encrypted ssh private keys
JavaScript
35
star
48

ejsgi

Like JSGI, but using streams.
JavaScript
35
star
49

node-eliza

A Robotic Rogerian Therapist, on IRC
JavaScript
34
star
50

natives

Do stuff with Node.js's native JavaScript modules
JavaScript
31
star
51

goosh

Front-end old-style terminal interface, for web services like those provided by Google and Yahoo.
JavaScript
31
star
52

simple-node-server

A simple fast node http server toolkit.
JavaScript
30
star
53

util-extend

Node's internal object extension function, for you!
JavaScript
30
star
54

chownr

Like `chown -R`
JavaScript
28
star
55

csrf-lite

CSRF protection utility for framework-free node sites.
JavaScript
28
star
56

chmodr

Like `chmod -R` in node
JavaScript
28
star
57

path-scurry

TypeScript
27
star
58

node-hexedit

hexadecimal editor in node
JavaScript
27
star
59

back-to-markdown.css

Turns any markdown editor into a WYSIWYG editor
CSS
26
star
60

node-async-simple

Multiply two numbers, slowly, on the thread pool.
C++
26
star
61

node-strict

Makes your Node programs strict about stuff when loaded
JavaScript
25
star
62

json-stringify-nice

Stringify an object sorting scalars before objects, and defaulting to 2-space indent
JavaScript
25
star
63

promise-all-reject-late

Like Promise.all, but save rejections until all promises are resolved
JavaScript
24
star
64

promise-call-limit

Call an array of promise-returning functions, restricting concurrency to a specified limit.
TypeScript
24
star
65

fs.realpath

Use node's fs.realpath, but fall back to the JS implementation if the native one fails
JavaScript
24
star
66

node6-module-system-change

A demonstration of what changed in node 6's module loading logic
JavaScript
24
star
67

color-support

A module which will endeavor to guess your terminal's level of color support.
JavaScript
24
star
68

polite-json

TypeScript
23
star
69

ircretary

A note-taking IRC bot
JavaScript
23
star
70

yamlish

A parser for the yamlish format
JavaScript
22
star
71

sock-daemon

TypeScript
21
star
72

pseudomap

Like `new Map` but for older JavaScripts
JavaScript
21
star
73

node-fuse

Fuse bindings for nodejs
21
star
74

slocket

A locking socket alternative to file-system mutex locks
JavaScript
21
star
75

proto-list

A list of objects bound by prototype chain
JavaScript
20
star
76

retry-until

A function that will keep running a function you give it as long as it throws for a period of time
JavaScript
20
star
77

node-srand

srand bindings for node - Seedable predictable pseudorandom number generator
C++
20
star
78

mutate-fs

Mutate the Node.js filesystem behavior for tests.
JavaScript
20
star
79

ryp

Featureless npm-package bundling.
Shell
19
star
80

filewatcherthing

a thing to watch a file and then run a command
JavaScript
19
star
81

gatsby-remark-tumble-media

A plugin for gatsby-transformer-remark to support photosets, video, and audio in markdown frontmatter.
JavaScript
19
star
82

sodn

SOcial DNodes
JavaScript
19
star
83

joyent-node-on-smart-example

A blog post.
JavaScript
18
star
84

error-page

Easily send errors in Node.js HTTP servers. Think like the `ErrorDocument` declarations in Apache config files.
JavaScript
17
star
85

_ify

an itty bitty curry utility
JavaScript
17
star
86

url-parse-as-address

Parse a URL assuming that it's http/https, even if protocol or // isn't present
JavaScript
17
star
87

http-https

A wrapper that chooses http or https for requests
JavaScript
17
star
88

perfalize

TypeScript
16
star
89

cssmin

A cross-platform regular-expression based minifier for CSS
16
star
90

duplex-passthrough

like a passthrough, but in both directions
JavaScript
16
star
91

mintee

a tiny module for piping an input to multiple output streams
JavaScript
16
star
92

tap-assert

An assert module that outputs tap result objects
JavaScript
16
star
93

create-isaacs

An npm init module to create modules like I do
JavaScript
16
star
94

domain-http-server

A module thingie to use domains in Express or Restify or just regular HTTP servers
JavaScript
15
star
95

canonical-host

Node module to redirect users to the canonical hostname for your site.
JavaScript
15
star
96

fs-readstream-seek

A fs.ReadStream that supports seeking to arbtrary locations within a file.
JavaScript
15
star
97

hardhttps

Slightly hardened https for node
JavaScript
14
star
98

exit-code

`process.exitCode` behavior back-ported from io.js and Node.js 0.12+
JavaScript
14
star
99

mcouch

Put your CouchDB in Manta, attachments and docs and all
JavaScript
14
star
100

emcee

A bridge between the M and C bits of MVC
JavaScript
13
star