Commit 8cfdd964 authored by David Dollar's avatar David Dollar

init

parents
#!/usr/bin/env bash
# bin/compile <build-dir> <cache-dir>
# fail fast
set -e
# config
NODE_VERSION="0.4.4"
NPM_VERSION="1.0.3"
# parse and derive params
BUILD_DIR=$1
CACHE_DIR=$2
LP_DIR=`cd $(dirname $0); cd ..; pwd`
CACHE_STORE_DIR=$CACHE_DIR"/node_modules/$NPM_VERSION"
CACHE_TARGET_DIR=$BUILD_DIR"/node_modules"
# vendor directories
VENDORED_NODE="$LP_DIR/vendor/node/node-$NODE_VERSION"
VENDORED_NPM="$LP_DIR/vendor/npm/npm-$NPM_VERSION"
# vendor node
PATH="$BUILD_DIR/bin:$PATH"
echo "-----> Vendoring node $NODE_VERSION"
mkdir -p "$BUILD_DIR/bin"
cp "$VENDORED_NODE" "$BUILD_DIR/bin/node"
# unpack existing cache
rm -rf $CACHE_TARGET_DIR
if [ -d $CACHE_STORE_DIR ]; then
cp -a $CACHE_STORE_DIR $CACHE_TARGET_DIR
fi
# install dependencies with npm
echo "-----> Installing dependencies with npm $NPM_VERSION"
cd $BUILD_DIR
HOME="$BUILD_DIR" $VENDORED_NODE $VENDORED_NPM/cli.js install 2>&1 | sed -u 's/^/ /'
if [ "${PIPESTATUS[*]}" != "0 0" ]; then
echo " ! Failed to install dependencies with npm"
exit 1
else
echo " Dependencies installed"
fi
# repack cache with new assets
rm -rf $CACHE_STORE_DIR
mkdir -p $(dirname $CACHE_STORE_DIR)
cp -a $CACHE_TARGET_DIR $CACHE_STORE_DIR
#!/usr/bin/env bash
# bin/use <build-dir>
if [ -f $1/package.json ]; then
echo "Node" && exit 0
else
echo "no" && exit 1
fi
#!/usr/bin/env bash
# bin/release <build-dir>
cat <<EOF
---
config_vars:
PATH: bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin
EOF
*.swp
test/bin
test/output.log
test/packages/*/node_modules
test/packages/npm-test-depends-on-spark/which-spark.log
test/packages/test-package/random-data.txt
test/root
node_modules/ronn
node_modules/node-uuid
node_modules/.bin
npm-debug.log
[submodule "node_modules/semver"]
path = node_modules/semver
url = git://github.com/isaacs/node-semver.git
[submodule "node_modules/abbrev"]
path = node_modules/abbrev
url = git://github.com/isaacs/abbrev-js.git
[submodule "node_modules/nopt"]
path = node_modules/nopt
url = git://github.com/isaacs/nopt.git
# Authors ordered by first contribution.
Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)
Steve Steiner <ssteinerX@gmail.com> (http://websaucesoftware.com/blog/)
Mikeal Rogers <mikeal.rogers@gmail.com> (http://www.mikealrogers.com/)
Aaron Blohowiak <aaron.blohowiak@gmail.com> (http://aaronblohowiak.com/)
Martyn Smith <martyn@dollyfish.net.nz> (http://dollyfish.net.nz/)
Mathias Pettersson <mape@mape.me> (http://mape.me/)
Brian Hammond <brian@fictorial.com> (http://fictorial.com/)
Charlie Robbins <charlie.robbins@gmail.com> (http://www.charlierobbins.com/)
Francisco Treacy <francisco.treacy@gmail.com> (http://franciscotreacy.com/)
Cliffano Subagio <cliffano@gmail.com> (http://blog.cliffano.com/)
Christian Eager <christian.eager@nokia.com> (http://perpenduum.com)
Dav Glass <davglass@gmail.com> (http://blog.davglass.com)
Alex K. Wolfe <alexkwolfe@gmail.com>
James Sanders <jimmyjazz14@gmail.com> (http://james-sanders.com/)
Reid Burke <me@reidburke.com> (http://reidburke.com/)
Arlo Breault <arlolra@gmail.com> (http://thoughtherder.com/)
Timo Derstappen <teemow@gmail.com> (http://teemow.com)
Bradley Meck <bradley.meck@gmail.com>
Bart Teeuwisse <bart.teeuwisse@thecodemill.biz> (http://thecodemill.biz/)
Ben Noordhuis <info@bnoordhuis.nl> (http://bnoordhuis.nl/)
Tor Valamo <tor.valamo@gmail.com> (http://www.magnimedia.no/)
Whyme.Lyu <5longluna@gmail.com> (http://whyme.kuantu.com/)
Olivier Melcher <olivier.melcher@gmail.com>
Tomaž Muraus <kami@k5-storitve.net> (http://www.tomaz-muraus.info)
Evan Meagher <evan.meagher@gmail.com> (http://evanmeagher.net/)
Orlando Vazquez <ovazquez@gmail.com> (http://2wycked.net/)
George Miroshnykov <gmiroshnykov@lohika.com>
Geoff Flarity (http://ca.linkedin.com/pub/geoff-flarity/a/536/43a)
Pete Kruckenberg <pete@kruckenberg.com>
Chris Wong <chris@chriswongstudio.com>
doc/changelog.md
\ No newline at end of file
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
"Node.js" and "node" trademark Joyent, Inc. npm is not officially
part of the Node.js project, and is neither owned by nor
officially affiliated with Joyent, Inc.
Packages published in the npm registry are not part of npm
itself, and are the sole property of their respective
maintainers.
SHELL = bash
docs = $(shell find doc -name '*.md' \
|sed 's|.md|.1|g' \
|sed 's|doc/|man1/|g' )
doc_subfolders = $(shell find doc -type d \
|sed 's|doc/|man1/|g' )
# This is the default make target.
# Since 'make' typically does non-installation build stuff,
# it seems appropriate.
submodules:
! [ -d .git ] || git submodule update --init
latest: submodules
@echo "Installing latest published npm"
@echo "Use 'make install' or 'make link' to install the code"
@echo "in this folder that you're looking at right now."
node cli.js install
install: submodules
node cli.js install -g -f
# backwards compat
dev: install
link: uninstall
node cli.js link -f
clean: uninstall
uninstall: submodules
node cli.js cache clean
node cli.js rm npm -g -f --loglevel error
man: man1
man1: $(doc_subfolders)
[ -d man1 ] || mkdir -p man1
doc: man1 $(docs)
# use `npm install ronn` for this to work.
man1/%.1: doc/%.md
@[ -x ./node_modules/.bin/ronn ] || node cli.js install ronn
./node_modules/.bin/ronn --roff $< > $@
man1/%/: doc/%/
@[ -d $@ ] || mkdir -p $@
test: submodules
node cli.js test
version: link
git add package.json &&\
git ci -m v$(shell npm -v)
publish: link
git tag -s -m v$(shell npm -v) v$(shell npm -v) &&\
git push origin master &&\
npm publish
.PHONY: latest install dev link doc clean uninstall test man
# npm
This is just enough info to get you up and running.
Much more info available via `npm help` once it's installed.
## IMPORTANT
**You need node v0.4 or higher to run this program.**
To install an old **and unsupported** version of npm that works on node 0.3
and prior:
git clone git://github.com/isaacs/npm.git ./npm
cd npm
git checkout origin/0.2
make dev
## Simple Install
To install npm with one command, do this:
curl http://npmjs.org/install.sh | sh
To skip the npm 0.x cleanup, do this:
curl http://npmjs.org/install.sh | clean=no sh
To say "yes" to the 0.x cleanup, but skip the prompt:
curl http://npmjs.org/install.sh | clean=yes sh
If that fails, try this:
git clone http://github.com/isaacs/npm.git
cd npm
sudo make install
If you're sitting in the code folder reading this document in your
terminal, then you've already got the code. Just do:
sudo make install
and npm will install itself.
If you don't have make, and don't have curl or git, and ALL you have is
this code and node, you can probably do this:
sudo node ./cli.js install -g
However, note that github tarballs **do not contain submodules**, so
those won't work. You'll have to also fetch the appropriate submodules
listed in the .gitmodules file.
## Permissions
**tl;dr**
* Use `sudo` for greater safety. Or don't, if you prefer not to.
* npm will downgrade permissions if it's root before running any build
scripts that package authors specified.
### More details...
As of version 0.3, it is recommended to run npm as root.
This allows npm to change the user identifier to the `nobody` user prior
to running any package build or test commands.
If you are not the root user, or if you are on a platform that does not
support uid switching, then npm will not attempt to change the userid.
If you would like to ensure that npm **always** runs scripts as the
"nobody" user, and have it fail if it cannot downgrade permissions, then
set the following configuration param:
npm config set unsafe-perm false
to prevent it from ever running in unsafe mode, even as non-root users.
## Uninstalling
So sad to see you go.
sudo npm uninstall npm -g
Or, if that fails,
sudo make uninstall
## More Severe Uninstalling
Usually, the above instructions are sufficient. That will remove
npm, but leave behind anything you've installed.
If you would like to remove all the packages that you have installed,
then you can use the `npm ls` command to find them, and then `npm rm` to
remove them.
To remove cruft left behind by npm 0.x, you can use the included
`clean-old.sh` script file. You can run it conveniently like this:
npm explore npm -g -- sh scripts/clean-old.sh
## Using npm Programmatically
If you would like to use npm programmatically, you can do that.
It's not very well documented, but it IS rather simple.
var npm = require("npm")
npm.load(myConfigObject, function (er) {
if (er) return handlError(er)
npm.commands.install(["some", "args"], function (er, data) {
if (er) return commandFailed(er)
// command succeeded, and data might have some info
})
npm.on("log", function (message) { .... })
})
See `./bin/npm.js` for an example of pulling config values off of the
command line arguments using nopt. You may also want to check out `npm
help config` to learn about all the options you can set there.
## More Docs
Check out the [docs](http://github.com/isaacs/npm/blob/master/doc/),
especially the
[faq](http://github.com/isaacs/npm/blob/master/doc/faq.md#readme).
You can use the `npm help` command to read any of them.
If you're a developer, and you want to use npm to publish your program,
you should
[read this](http://github.com/isaacs/npm/blob/master/doc/developers.md#readme)
## Legal Stuff
"npm" and "the npm registry" are owned by Isaac Z. Schlueter. All
rights not explicitly granted in the MIT license are reserved. See the
included LICENSE file for more details.
"Node.js" and "node" are trademarks owned by Joyent, Inc. npm is not
officially part of the Node.js project, and is neither owned by nor
officially affiliated with Joyent, Inc.
The packages in the npm registry are not part of npm itself, and are the
sole property of their respective maintainers. While every effort is
made to ensure accountability, there is absolutely no guarantee,
warrantee, or assertion made as to the quality, fitness for a specific
purpose, or lack of malice in any given npm package. Modules
published on the npm registry are not affiliated with or endorsed by
Joyent, Inc., Isaac Z. Schlueter, Ryan Dahl, or the Node.js project.
If you have a complaint about a package in the npm registry, and cannot
resolve it with the package owner, please express your concerns to
Isaac Z. Schlueter at <i@izs.me>.
### In plain english
This is mine; not my employer's, not Node's, not Joyent's, not Ryan
Dahl's.
If you publish something, it's yours, and you are solely accountable
for it. Not me, not Node, not Joyent, not Ryan Dahl.
If other people publish something, it's theirs. Not mine, not Node's,
not Joyent's, not Ryan Dahl's.
Yes, you can publish something evil. It will be removed promptly if
reported, and we'll lose respect for you. But there is no vetting
process for published modules.
If this concerns you, inspect the source before using packages.
var argv = process.argv.slice(2)
, user = argv[0] || process.getuid()
, group = argv[1] || process.getgid()
if (!isNaN(user)) user = +user
if (!isNaN(group)) group = +group
console.error([user, group])
try {
process.setgid(group)
process.setuid(user)
console.log(JSON.stringify({uid:+process.getuid(), gid:+process.getgid()}))
} catch (ex) {
console.log(JSON.stringify({error:ex.message,errno:ex.errno}))
}
#!/usr/bin/env node
;(function () { // wrapper in case we're in module_context mode
var log = require("../lib/utils/log")
log.waitForConfig()
log.info("ok", "it worked if it ends with")
var fs = require("../lib/utils/graceful-fs")
, path = require("path")
, sys = require("../lib/utils/sys")
, npm = require("../npm")
, ini = require("../lib/utils/ini")
, rm = require("../lib/utils/rm-rf")
, errorHandler = require("../lib/utils/error-handler")
, configDefs = require("../lib/utils/config-defs")
, shorthands = configDefs.shorthands
, types = configDefs.types
, nopt = require("nopt")
log.verbose(process.argv, "cli")
var conf = nopt(types, shorthands)
npm.argv = conf.argv.remain
if (npm.deref(npm.argv[0])) npm.command = npm.argv.shift()
else conf.usage = true
if (conf.version) {
console.log(npm.version)
return
} else log("npm@"+npm.version, "using")
log("node@"+process.version, "using")
// make sure that this version of node works with this version of npm.
var semver = require("semver")
, nodeVer = process.version
, reqVer = npm.nodeVersionRequired
if (reqVer && !semver.satisfies(nodeVer, reqVer)) {
return errorHandler(new Error(
"npm doesn't work with node " + nodeVer
+ "\nRequired: node@" + reqVer), true)
}
process.on("uncaughtException", errorHandler)
if (conf.usage && npm.command !== "help") {
npm.argv.unshift(npm.command)
npm.command = "help"
}
// now actually fire up npm and run the command.
// this is how to use npm programmatically:
conf._exit = true
npm.load(conf, function (er) {
if (er) return errorHandler(er)
npm.commands[npm.command](npm.argv, errorHandler)
})
})()
var argv = process.argv
if (argv.length < 3) {
console.error("Usage: read-package.json <file> [<fields> ...]")
process.exit(1)
}
var fs = require("fs")
, file = argv[2]
, readJson = require("../lib/utils/read-json")
readJson(file, function (er, data) {
if (er) throw er
if (argv.length === 3) console.log(data)
else argv.slice(3).forEach(function (field) {
field = field.split(".")
var val = data
field.forEach(function (f) {
val = val[f]
})
console.log(val)
})
})
#!/usr/bin/env node
require("./bin/npm.js")
#!/bin/bash
# this is a wicked hack, but whatever.
CONFIGS=()
i=0
while [ $# -gt 0 ]; do
conf="$1"
case $conf in
--help)
echo "./config --param=value ..."
exit 0
;;
--*)
CONFIGS[$i]="${conf:2}"
;;
*)
CONFIGS[$i]="$conf"
;;
esac
let i++
shift
done
for c in "${CONFIGS[@]}"; do
echo '+node ./bin/npm.js config set "'"$c"'"'
node ./bin/npm.js config set "$c"
done
echo
echo +node ./bin/npm.js config ls
echo
node ./bin/npm.js config ls
npm-adduser(1) -- Add a registry user account
=============================================
## SYNOPSIS
npm adduser
## DESCRIPTION
Create or verify a user named `<username>` in the npm registry, and
save the credentials to the `.npmrc` file.
The username, password, and email are read in from prompts.
You may use this command to change your email address, but not username
or password.
To reset your password, go to <http://admin.npmjs.org/>
You may use this command multiple times with the same user account to
authorize on a new machine.
## CONFIGURATION
### registry
Default: http://registry.npmjs.org/
The base URL of the npm package registry.
owner.md
\ No newline at end of file
npm-bin(1) -- Display npm bin folder
====================================
## SYNOPSIS
npm bin
## DESCRIPTION
Print the folder where npm will install executables.
npm-build(1) -- Build a package
===============================
## SYNOPSIS
npm build <package-folder>
* `<package-folder>`:
A folder containing a `package.json` file in its root.
## DESCRIPTION
This is the plumbing command called by `npm link` and `npm install`.
It should generally not be called directly.
## SEE ALSO
* npm-install(1)
* npm-link(1)
* npm-scripts(1)
* npm-json(1)
npm-cache(1) -- install a package
===================================
## SYNOPSIS
npm cache add <tarball file>
npm cache add <folder>
npm cache add <tarball url>
npm cache add <name>@<version>
npm cache ls [<path>]
npm cache clean [<path>]
## DESCRIPTION
* add:
Add the specified package to the local cache. This command is primarily
intended to be used internally by npm, but it can provide a way to
add data to the local installation cache explicitly.
* ls:
Show the data in the cache. Argument is a path to show in the cache
folder. Works a bit like the `find` program, but limited by the
`depth` config.
* clean:
Delete data out of the cache folder. If an argument is provided, then
it specifies a subpath to delete. If no argument is provided, then
the entire cache is cleared.
## DETAILS
npm stores cache data in `$HOME/.npm`. For each package that is added
to the cache, three pieces of information are stored in
`{cache}/{name}/{version}`:
* .../package/:
A folder containing the package contents as they appear in the tarball.
* .../package.json:
The package.json file, as npm sees it, with overlays applied and a _id attribute.
* .../package.tgz:
The tarball for that version.
Additionally, whenever a registry request is made, a `.cache.json` file
is placed at the corresponding URI, to store the ETag and the requested
data.
Commands that make non-essential registry requests (such as `search` and
`view`, or the completion scripts) generally specify a minimum timeout.
If the `.cache.json` file is younger than the specified timeout, then
they do not make an HTTP request to the registry.
## CONFIGURATION
### cache
Default: `$HOME/.npm` on Posix, or `$HOME/npm-cache` on Windows.
The root cache folder.
npm-changelog(1) -- Changes
===========================
## HISTORY
* 0.0
Lots of sketches and false starts. Abandoned a few times.
Core functionality established.
* 0.1
push to beta, and announce
Solaris and Cygwin support
* 0.2
First allegedly "stable" release.
Most functionality implemented.
Used shim files and `name@version` symlinks
Feature explosion
Kind of a mess.
* 0.3
More correct permission/uid handling when running as root
Require node 0.4.0
Reduce featureset
Packages without "main" modules don't export modules.
Remove support for invalid JSON (since node doesn't support it)
* 1.0
Simplify folder structure greatly.
Install locally (bundle by default)
Drastic rearchitecture
npm-coding-style(1) -- npm's "funny" coding style
=================================================
## DESCRIPTION
npm's coding style is a bit unconventional. It is not different for
difference's sake, but rather a carefully crafted style that is
designed to reduce visual clutter and make bugs more apparent.
If you want to contribute to npm (which is very encouraged), you should
make your code conform to npm's style.
## Line Length
Keep lines shorter than 80 characters. It's better for lines to be
too short than to be too long. Break up long lists, objects, and other
statements onto multiple lines.
## Indentation
Two-spaces. Tabs are better, but they look like hell in web browsers
(and on github), and node uses 2 spaces, so that's that.
Configure your editor appropriately.
## Curly braces
Curly braces belong on the same line as the thing that necessitates them.
Bad:
function ()
{
Good:
function () {
If a block needs to wrap to the next line, use a curly brace. Don't
use it if it doesn't.
Bad:
if (foo) { bar() }
while (foo)
bar()
Good:
if (foo) bar()
while (foo) {
bar()
}
## Semicolons
Don't use them except in four situations:
* `for (;;)` loops. They're actually required.
* null loops like: `while (something) ;` (But you'd better have a good
reason for doing that.)
* case "foo": doSomething(); break
* In front of a leading ( or [ at the start of the line.
This prevents the expression from being interpreted
as a function call or property access, respectively.
Some examples of good semicolon usage:
;(x || y).doSomething()
;[a, b, c].forEach(doSomething)
for (var i = 0; i < 10; i ++) {
switch (state) {
case "begin": start(); continue
case "end": finish(); break
default: throw new Error("unknown state")
}
end()
}
Note that starting lines with `-` and `+` also should be prefixed
with a semicolon, but this is much less common.
## Comma First
If there is a list of things separated by commas, and it wraps
across multiple lines, put the comma at the start of the next
line, directly below the token that starts the list. Put the
final token in the list on a line by itself. For example:
var magicWords = [ "abracadabra"
, "gesundheit"
, "ventrilo"
]
, spells = { "fireball" : function () { setOnFire() }
, "water" : function () { putOut() }
}
, a = 1
, b = "abc"
, etc
, somethingElse
## Whitespace
Put a single space in front of ( for anything other than a function call.
Also use a single space wherever it makes things more readable.
Don't leave trailing whitespace at the end of lines. Don't indent empty
lines. Don't use more spaces than are helpful.
## Functions
Use named functions. They make stack traces a lot easier to read.
## Callbacks, Sync/async Style
Use the asynchronous/non-blocking versions of things as much as possible.
It might make more sense for npm to use the synchronous fs APIs, but this
way, the fs and http and child process stuff all uses the same callback-passing
methodology.
The callback should always be the last argument in the list. Its first
argument is the Error or null.
Be very careful never to ever ever throw anything. It's worse than useless.
Just send the error message back as the first argument to the callback.
## Errors
Always create a new Error object with your message. Don't just return a
string message to the callback. Stack traces are handy.
Use the `require("./utils/log").er` function. It takes a callback and an
error message, and returns an object that will report the message in the
event of a failure. It's quite handy.
function myThing (args, cb) {
getData(args, function (er, data) {
if (er) return log.er(cb, "Couldn't get data")(er)
doSomethingElse(data, cb)
})
}
function justHasToWork (cb) {
doSomething(log.er(cb, "the doSomething failed."))
}
## Logging
Please clean up logs when they are no longer helpful. In particular,
logging the same object over and over again is not helpful. Logs should
report what's happening so that it's easier to track down where a fault
occurs.
Use appropriate log levels. The default log() function logs at the
"info" level. See `npm help config` and search for "loglevel".
## Case, naming, etc.
Use lowerCamelCase for multiword identifiers when they refer to objects,
functions, methods, members, or anything not specified in this section.
Use UpperCamelCase for class names (things that you'd pass to "new").
Use all-lower-hyphen-css-case for multiword filenames and config keys.
Use named functions. They make stack traces easier to follow.
Use CAPS_SNAKE_CASE for constants, things that should never change
and are rarely used.
Use a single uppercase letter for function names where the function
would normally be anonymous, but needs to call itself recursively. It
makes it clear that it's a "throwaway" function.
## null, undefined, false, 0
Boolean variables and functions should always be either `true` or
`false`. Don't set it to 0 unless it's supposed to be a number.
When something is intentionally missing or removed, set it to `null`.
Don't set things to `undefined`. Reserve that value to mean "not yet
set to anything."
Boolean objects are verboten.
npm-completion(1) -- Tab Completion for npm
===========================================
## SYNOPSIS
npm completion >> ~/.bashrc
npm completion >> ~/.zshrc
## DESCRIPTION
Sets up a function that enables tab-completion in all npm commands.
You may of course also pipe the relevant script to a file such as
`/usr/local/etc/bash_completion.d/npm` if you have a system that will
read that file for you.
When `COMP_CWORD`, `COMP_LINE`, and `COMP_POINT` are defined in the
environment, `npm completion` acts in "plumbing mode", and outputs
completions based on the arguments.
This diff is collapsed.
npm-deprecate(1) -- Deprecate a version of a package
====================================================
## SYNOPSIS
npm deprecate <name>[@<version>] <message>
## DESCRIPTION
This command will update the npm registry entry for a package, providing
a deprecation warning to all who attempt to install it.
It works on version ranges as well as specific versions, so you can do
something like this:
npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3"
Note that you must be the package owner to deprecate something. See the
`owner` and `adduser` help topics.
npm-developers(1) -- Developer Guide
====================================
## DESCRIPTION
So, you've decided to use npm to develop (and maybe publish/deploy)
your project.
Fantastic!
There are a few things that you need to do above the simple steps
that your users will do to install your program.
## About These Documents
These are man pages. If you install npm, you should be able to
then do `man npm-thing` to get the documentation on a particular
topic.
Any time you see "see npm-whatever(1)", you can do `man npm-whatever`
or `npm help whatever` to get at the docs.
## What is a `package`
A package is:
* a) a folder containing a program described by a package.json file
* b) a gzipped tarball containing (a)
* c) a url that resolves to (b)
* d) a `<name>@<version>` that is published on the registry with (c)
* e) a `<name>@<tag>` that points to (d)
* f) a `<name>` that has a "latest" tag satisfying (e)
Even if you never publish your package, you can still get a lot of
benefits of using npm if you just want to write a node program (a), and
perhaps if you also want to be able to easily install it elsewhere
after packing it up into a tarball (b).
## The package.json File
You need to have a `package.json` file in the root of your project to do
much of anything with npm. That is basically the whole interface.
See npm-json(1) for details about what goes in that file. At the very
least, you need:
* name:
This should be a string that identifies your project. Please do not
use the name to specify that it runs on node, or is in JavaScript.
You can use the "engines" field to explicitly state the versions of
node (or whatever else) that your program requires, and it's pretty
well assumed that it's javascript.
It does not necessarily need to match your github repository name.
So, `node-foo` and `bar-js` are bad names. `foo` or `bar` are better.
* version:
A semver-compatible version.
* engines:
Specify the versions of node (or whatever else) that your program
runs on. The node API changes a lot, and there may be bugs or new
functionality that you depend on. Be explicit.
* author:
Take some credit.
* scripts:
If you have a special compilation or installation script, then you
should put it in the `scripts` hash. You should definitely have at
least a basic smoke-test command as the "scripts.test" field.
See npm-scripts(1).
* main:
If you have a single module that serves as the entry point to your
program (like what the "foo" package gives you at require("foo")),
then you need to specify that in the "main" field.
* directories:
This is a hash of folders. The best ones to include are "lib" and
"doc", but if you specify a folder full of man pages in "man", then
they'll get installed just like these ones.
You can use `npm init` in the root of your package in order to get you
started with a pretty basic package.json file. See `npm-init(1)` for
more info.
## Keeping files *out* of your package
Use a `.npmignore` file to keep stuff out of your package. If there's
no .npmignore file, but there *is* a .gitignore file, then npm will
ignore the stuff matched by the .gitignore file. If you *want* to
include something that is excluded by your .gitignore file, you can
create an empty .npmignore file to override it.
## Link Packages
`npm link` is designed to install a development package and see the
changes in real time without having to keep re-installing it. (You do
need to either re-link or `npm rebuild -g` to update compiled packages,
of course.)
More info at `npm-link(1)`.
## Before Publishing: Make Sure Your Package Installs and Works
**This is important.**
If you can not install it locally, you'll have
problems trying to publish it. Or, worse yet, you'll be able to
publish it, but you'll be publishing a broken or pointless package.
So don't do that.
In the root of your package, do this:
npm install . -g
That'll show you that it's working. If you'd rather just create a symlink
package that points to your working directory, then do this:
npm link
Use `npm ls -g` to see if it's there.
To test a local install, go into some other folder, and then do:
cd ../some-other-folder
npm install ../my-package
to install it locally into the node_modules folder in that other place.
Then go into the node-repl, and try using require("my-thing") to
bring in your module's main module.
## Create a User Account
Create a user with the adduser command. It works like this:
npm adduser
and then follow the prompts.
This is documented better in npm-adduser(1). So do this to get the
details:
npm help adduser
## Publish your package
This part's easy. IN the root of your folder, do this:
npm publish
You can give publish a url to a tarball, or a filename of a tarball,
or a path to a folder.
Note that pretty much **everything in that folder will be exposed**
by default. So, if you have secret stuff in there, use a `.npminclude`
or `.npmignore` file to list out the globs to include/ignore, or publish
from a fresh checkout.
## Brag about it
Send emails, write blogs, blab in IRC.
Tell the world how easy it is to install your program!
npm-docs(1) -- Docs for a package in a web browser maybe
========================================================
## SYNOPSIS
npm docs <pkgname>
## DESCRIPTION
This command tries to guess at the likely location of a package's
documentation URL, and then tries to open it using the `--browser`
config param.
npm-edit(1) -- Edit an installed package
========================================
## SYNOPSIS
npm edit <name>[@<version>]
## DESCRIPTION
Opens the package folder in the default editor (or whatever you've
configured as the npm `editor` config -- see `npm help config`.)
After it has been edited, the package is rebuilt so as to pick up any
changes in compiled packages.
For instance, you can do `npm install connect` to install connect
into your package, and then `npm edit connect` to make a few
changes to your locally installed copy.
npm-explore(1) -- Browse an installed package
=============================================
## SYNOPSIS
npm explore <name>[@<version>] [ -- <cmd>]
## DESCRIPTION
Spawn a subshell in the directory of the installed package specified.
If a command is specified, then it is run in the subshell, which then
immediately terminates.
Note that the package is *not* automatically rebuilt afterwards, so be
sure to use `npm rebuild <pkg>` if you make any changes.
npm-faq(1) -- Frequently Asked Questions
========================================
## Where can I find these docs in HTML?
<https://github.com/isaacs/npm/tree/master/doc>
## It didn't work.
That's not really a question.
## Why didn't it work?
I don't know yet.
Read the error output, and if you can't figure out what it means,
do what it says and post a bug with all the information it asks for.
## Where does npm put stuff?
See `npm help folders`
tl;dr:
* Use the `npm root` command to see where modules go, and the `npm bin`
command to see where executables go
* Global installs are different from local installs. If you install
something with the `-g` flag, then its executables go in `npm bin -g`
and its modules go in `npm root -g`.
## How do I install something everywhere?
Install it globally by tacking `-g` or `--global` to the command.
## I installed something globally, but I can't `require()` it
Install it locally.
## I don't wanna.
Check out `npm link`. You might like it.
## No, I really want 0.x style "everything's global" style.
Ok, fine. Do this:
echo 'export NODE_PATH="'$(npm root -g)'"' >> ~/.bashrc
. ~/.bashrc
npm config set global true
This is not recommended.
## How do I list installed packages?
`npm ls`
## How do I search for packages?
`npm search`
Arguments are greps. `npm ls jsdom` shows jsdom packages.
## How do I update npm?
npm update npm -g
You can also update all outdated local packages by doing `npm update` without
any arguments, or global packages by doing `npm update -g`.
Occasionally, the version of npm will progress such that the current
version cannot be properly installed with the version that you have
installed already. (Consider, if there is ever a bug in the `update`
command.)
In those cases, you can do this:
curl http://npmjs.org/install.sh | sh
## What is a `package`?
A package is:
* a) a folder containing a program described by a package.json file
* b) a gzipped tarball containing (a)
* c) a url that resolves to (b)
* d) a `<name>@<version>` that is published on the registry with (c)
* e) a `<name>@<tag>` that points to (d)
* f) a `<name>` that has a "latest" tag satisfying (e)
Even if you never publish your package, you can still get a lot of
benefits of using npm if you just want to write a node program (a), and
perhaps if you also want to be able to easily install it elsewhere
after packing it up into a tarball (b).
## How do I install node with npm?
You don't. Try one of these:
* <http://github.com/isaacs/nave>
* <http://github.com/visionmedia/n>
* <http://github.com/creationix/nvm>
## How can I use npm for development?
See `npm help developers` and `npm help json`.
You'll most likely want to `npm link` your development folder. That's
awesomely handy.
To set up your own private registry, check out `npm help registry`.
## Can I list a url as a dependency?
Yes. It should be a url to a gzipped tarball containing a single folder
that has a package.json in its root. (See "what is a package?" above.)
## OK, but can I list a git repo as a dependency?
No.
However, you can list a url as a dependency.
## How do I symlink to a dev folder so I don't have to keep re-installing?
See `npm help link`
## The package registry website. What is that exactly?
See `npm help registry`.
## What's up with the insecure channel warnings?
As of this writing, node has problems uploading files over HTTPS. That
means that publishes go over HTTP by default.
Allegedly this problem is solved in node 0.4.7. You can suppress those
warnings by doing this:
npm config set registry https://registry.npmjs.org
## I forgot my password, and can't publish. How do I reset it?
Go to <http://admin.npmjs.org/>.
## I get ECONNREFUSED a lot. What's up?
Either the registry is down, or node's DNS isn't able to reach out.
This happens a lot if you don't follow *all* the steps in the Cygwin
setup doc.
To check if the registry is down, open up
<http://registry.npmjs.org/-/short>
in a web browser. This will also tell you if you are just unable to
access the internet for some reason.
If the registry IS down, let me know by emailing <i@izs.me>. I'll have
someone kick it or something.
## Who does npm?
`npm view npm author`
`npm view npm contributors`
## I have a question or request not addressed here. Where should I put it?
Discuss it on the mailing list, or post an issue.
* <npm-@googlegroups.com>
* <http://github.com/isaacs/npm/issues>
## Why does npm hate me?
npm is not capable of hatred. It loves everyone, especially you.
list.md
\ No newline at end of file
npm-folders(1) -- Folder Structures Used by npm
===============================================
## DESCRIPTION
npm puts various things on your computer. That's its job.
This document will tell you what it puts where.
### tl;dr
* Local install (default): puts stuff in ./node_modules
* Global install (with `-g`): puts stuff in /usr/local
* Install it **locally** if you're going to `require()` it.
* Install it **globally** if you're going to run it on the command line.
### prefix Configuration
The `prefix` config defaults to node's `process.installPrefix`. On most
systems, this is `/usr/local`.
When the `global` flag is set, npm installs things into this prefix.
When it is not set, it uses the root of the current package, or the
current working directory if not in a package already.
### Node Modules
Packages are dropped into the `node_modules` folder under the `prefix`.
When installing locally, this means that you can
`require("packagename")` to load its main module, or
`require("packagename/lib/path/to/sub/module")` to load other modules.
If you wish to `require()` a package, then install it locally.
### Executables
When in global mode, executables are linked into `prefix/bin`.
When in local mode, executables are linked into
`prefix/node_modules/.bin`.
### Man Pages
When in global mode, man pages are linked into `prefix/share/man`.
When in local mode, man pages are not installed.
### Cache
See `npm help cache`. Cache files are stored in `~/.npm` on Posix, or
`~/npm-cache` on Windows.
This is controlled by the `cache` configuration param.
### Temp Files
Temporary files are stored by default in the folder specified by the
`tmp` config, which defaults to either the TMPDIR environment
variable, or `/tmp`.
Temp files are given a unique folder under this root for each run of the
program, and are deleted upon successful exit.
## More Information
When doing local installings, npm first tries to find an appropriate
`prefix` folder. This is so that `npm install foo@1.2.3` will install
to the sensible root of your package, even if you happen to have `cd`ed
into some other folder.
Starting at the $PWD, npm will walk up the folder tree checking for a
folder that contains either a `package.json` file, or a `node_modules`
folder. If such a thing is found, then that is treated as the effective
"current directory" for the purpose of running npm commands. (This
behavior is inspired by and similar to git's .git-folder seeking
logic when running git commands in a working dir.)
If no package root is found, then the current folder is used.
When you run `npm install foo@1.2.3`, then the package is loaded into
the cache, and then unpacked into `./node_modules/foo`. Then, any of
foo's dependencies are similarly unpacked into
`./node_modules/foo/node_modules/...`.
Any bin files are symlinked to `./node_modules/.bin/`, so that they may
be found by npm scripts when necessary.
### Global Installation
If the `global` configuration is set to true, or if it is not explicitly
set false and no suitable node_modules folder was found, then npm will
install packages "globally".
For global installation, packages are installed roughly the same way,
but the module root is `/usr/local/lib/node_modules`, and bin files are
linked to `/usr/local/bin` instead of `./node_modules/.bin`.
### Cycles, Conflicts, and Folder Parsimony
Cycles are handled using the property of node's module system that it
walks up the directories looking for node_modules folders. So, at every
stage, if a package is already installed in an ancestor node_modules
folder, then it is not installed at the current location.
Consider the case above, where `foo -> bar -> baz`. Imagine if, in
addition to that, baz depended on bar, so you'd have:
`foo -> bar -> baz -> bar -> baz ...`. However, since the folder
structure is: foo/node_modules/bar/node_modules/baz, there's no need to
put another copy of bar into .../baz/node_modules, since when it calls
require("bar"), it will get the copy that is installed in
foo/node_modules/bar.
This shortcut is only used if the exact same
version would be installed in multiple nested node_modules folders. It
is still possible to have `a/node_modules/b/node_modules/a` if the two
"a" packages are different versions. However, without repeating the
exact same package multiple times, an infinite regress will always be
prevented.
Another optimization can be made by installing dependencies at the
highest level possible, below the localized "target" folder.
For example, consider this dependency graph:
foo
+-- bar@1.2.3
| +-- baz@2.x
| | `-- quux@3.x
| | `-- bar@1.2.3 (cycle)
| `-- asdf@*
`-- baz@1.2.3
`-- quux@3.x
`-- bar
In this case, we might expect a folder structure like this:
foo
+-- node_modules
+-- bar (1.2.3) <---[A]
| +-- node_modules
| | `-- baz (2.0.2) <---[B]
| | `-- node_modules
| | `-- quux (3.2.0)
| `-- asdf (2.3.4)
`-- baz (1.2.3) <---[C]
`-- node_modules
`-- quux (3.2.0) <---[D]
Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are
installed in foo's node_modules folder.
Bar [A] has dependencies on baz and asdf, so those are installed in bar's
node_modules folder. Because it depends on `baz@2.x`, it cannot re-use
the `baz@1.2.3` installed in the parent node_modules folder [C], and
must install its own copy [B].
Underneath bar, the `baz->quux->bar` dependency creates a cycle.
However, because `bar` is already in `quux`'s ancestry [A], it does not
unpack another copy of bar into that folder.
Underneath `foo->baz` [C], quux's [D] folder tree is empty, because its
dependnecy on bar is satisfied by the parent folder copy installed at [A].
For a graphical breakdown of what is installed where, use `npm ls`.
### Publishing
Upon publishing, npm will look in the node_modules folder. If any of
the items there are on the "dependencies" or "devDependencies" list,
and are not in the `bundledDependencies` array, then they will not be
included in the package tarball.
This allows a package maintainer to install all of their dependencies
(and dev dependencies) locally, but only re-publish those items that
cannot be found elsewhere.
config.md
\ No newline at end of file
folders.md
\ No newline at end of file
npm init(1) -- Interactively create a package.json file
=======================================================
## SYNOPSIS
npm init
## DESCRIPTION
This will ask you a bunch of questions, and then write a package.json for you.
It attempts to make reasonable guesses about what you want things to be set to,
and then writes a package.json file with the options you've selected.
If you already have a package.json file, it'll read that first, and default to
the options in there.
It is strictly additive, so it does not delete options from your package.json
without a really good reason to do so.
## SEE ALSO
npm-json(1)
npm-install(1) -- install a package
===================================
## SYNOPSIS
npm install (with no args in a package dir)
npm install <tarball file>
npm install <tarball url>
npm install <folder>
npm install <name>
npm install <name>@<tag>
npm install <name>@<version>
npm install <name>@<version range>
## DESCRIPTION
This command installs a package, and any packages that it depends on.
* npm install (in package directory):
Install the dependencies in the local node_modules folder.
In global mode, it is the same as `npm install $PWD`
* npm install `<tarball file>`:
Install a package that is sitting on the filesystem. Note: if you just want
to link a dev directory into your npm root, you can do this more easily by
using `npm link`.
In order to distinguish between this and remote installs, the argument
must either be "." or contain a "/" in it.
Example:
npm install ./package.tgz
* npm install `<tarball url>`:
Fetch the tarball url, and then install it. In order to distinguish between
this and other options, the argument must start with "http://" or "https://"
Example:
npm install http://github.com/waveto/node-crypto/tarball/v0.0.5
* npm install `<name>`:
Do a `<name>@<tag>` install, where `<tag>` is the "tag" config. (See
`npm help config`)
Example:
npm install sax
* npm install `<name>@<tag>`:
Install the version of the package that is referenced by the specified tag.
If the tag does not exist in the registry data for that package, then this
will fail.
Example:
npm install sax@stable
* npm install `<name>@<version>`:
Install the specified version of the package. This will fail if the version
has not been published to the registry.
Example:
npm install sax@0.1.1
* npm install `<name>@<version range>`:
Install a version of the package matching the specified version range. This
will follow the same rules for resolving dependencies described in `npm help json`.
Note that most version ranges must be put in quotes so that your shell will
treat it as a single argument.
Example:
npm install sax@">=0.1.0 <0.2.0"
You may combine multiple arguments, and even multiple types of arguments.
For example:
npm install sax@">=0.1.0 <0.2.0" bench supervisor
The `--tag` argument will apply to all of the specified install targets.
The `--force` argument will force npm to fetch remote resources even if a
local copy exists on disk.
npm install sax --force
## SEE ALSO
* npm-build(1)
* npm-registry(1)
* npm-build(1)
* npm-link(1)
* npm-folders(1)
* npm-tag(1)
This diff is collapsed.
npm-link(1) -- Symlink a package folder
=======================================
## SYNOPSIS
npm link (in package folder)
npm link <pkgname>
## DESCRIPTION
Package linking is a two-step process.
First, `npm link` in a package folder will create a globally-installed
symbolic link from `prefix/package-name` to the current folder.
Next, in some other location, `npm link package-name` will create a
symlink from the local `node_modules` folder to the global symlink.
When creating tarballs for `npm publish`, the linked packages are
"snapshotted" to their current state by resolving the symbolic links.
This is
handy for installing your own stuff, so that you can work on it and test it
iteratively without having to continually rebuild.
For example:
cd ~/projects/node-redis # go into the package directory
npm link # creates global link
cd ~/projects/node-bloggy # go into some other package directory.
npm link redis # link-install the package
Now, any changes to ~/projects/node-redis will be reflected in
~/projects/node-bloggy/node_modules/redis/
You may also shortcut the two steps in one. For example, to do the
above use-case in a shorter way:
cd ~/projects/node-bloggy # go into the dir of your main project
npm link ../node-redis # link the dir of your dependency
The second line is the equivalent of doing:
(cd ../node-redis; npm link)
npm link redis
That is, it first creates a global link, and then links the global
installation target into your project's `node_modules` folder.
npm-ls(1) -- List installed packages
======================================
## SYNOPSIS
npm list
npm ls
npm la
npm ll
## DESCRIPTION
This command will print to stdout all the versions of packages that are
installed, as well as their dependencies, in a tree-structure.
It does not take arguments.
It will print out extraneous, missing, and invalid packages.
When run as `ll` or `la`, it shows extended information by default.
## CONFIGURATION
### long
* Default: false
* Type: Boolean
Show extended information.
### parseable
* Default: false
* Type: Boolean
Show parseable output instead of tree view.
./link.md
\ No newline at end of file
./list.md
\ No newline at end of file
npm(1) -- node package manager
==============================
## SYNOPSIS
npm <command> [args]
## DESCRIPTION
npm is the package manager for the Node JavaScript platform. It puts
modules in place so that node can find them, and manages dependency
conflicts intelligently.
It is extremely configurable to support a wide variety of use cases.
Most commonly, it is used to publish, discover, install, and develop node
programs.
Run `npm help` to get a list of available commands.
## INTRODUCTION
You probably got npm because you want to install stuff.
Use `npm install blerg` to install the latest version of "blerg". Check out
`npm help install` for more info. It can do a lot of stuff.
Use the `npm search` command to show everything that's available.
Use `npm ls` to show everything you've installed.
## DEVELOPER USAGE
If you're using npm to develop and publish your code, check out the
following help topics:
* json:
Make a package.json file. See `npm help json`.
* link:
For linking your current working code into Node's path, so that you
don't have to reinstall every time you make a change. Use
`npm link` to do this.
* install:
It's a good idea to install things if you don't need the symbolic link.
Especially, installing other peoples code from the registry is done via
`npm install`
* adduser:
Create an account or log in. Creditials are stored (encrypted) in the
user config file.
* publish:
Use the `npm publish` command to upload your code to the registry.
## CONFIGURATION
npm is extremely configurable. It reads its configuration options from
5 places.
* Command line switches:
Set a config with `--key val`. All keys take a value, even if they
are booleans (the config parser doesn't know what the options are at
the time of parsing.) If no value is provided, then the option is set
to boolean `true`.
* Environment Variables:
Set any config by prefixing the name in an environment variable with
`npm_config_`. For example, `export npm_config_key=val`.
* User Configs:
The file at $HOME/.npmrc is an ini-formatted list of configs. If
present, it is parsed. If the `userconfig` option is set in the cli
or env, then that will be used instead.
* Global Configs:
The file found at ../etc/npmrc (from the node executable, by default
this resolves to /usr/local/etc/npmrc) will be parsed if it is found.
If the `globalconfig` option is set in the cli, env, or user config,
then that file is parsed instead.
* Defaults:
npm's default configuration options are defined in
lib/utils/config-defs.js. These must not be changed.
See `npm help config` for much much more information.
## CONTRIBUTIONS
Patches welcome!
* code:
Read through `npm help coding-style` if you plan to submit code.
You don't have to agree with it, but you do have to follow it.
* docs:
If you find an error in the documentation, edit the appropriate markdown
file in the "doc" folder. (Don't worry about generating the man page.)
Contributors are listed in npm's `package.json` file. You can view them
easily by doing `npm view npm contributors`.
If you would like to contribute, but don't know what to work on, check
the issues list or ask on the mailing list.
* <http://github.com/isaacs/npm/issues>
* <npm-@googlegroups.com>
## BUGS
When you find issues, please report them:
* web:
<http://github.com/isaacs/npm/issues>
* email:
<npm-@googlegroups.com>
Be sure to include *all* of the output from the npm command that didn't work
as expected. The `npm-debug.log` file is also helpful to provide.
You can also look for isaacs in #node.js on irc://irc.freenode.net. He
will no doubt tell you to put the output in a gist or email.
## HISTORY
See npm-changelog(1)
## AUTHOR
Isaac Z. Schlueter :: isaacs :: @izs :: <i@izs.me>
npm-outdated(1) -- Check for outdated packages
==============================================
## SYNOPSIS
npm outdated [<name> [<name> ...]]
## DESCRIPTION
This command will check the registry to see if any (or, specific) installed
packages are currently outdated.
npm-owner(1) -- Manage package owners
=====================================
## SYNOPSIS
npm owner ls <package name>
npm owner add <user> <package name>
npm owner rm <user> <package name>
## DESCRIPTION
* ls:
List all the users who have access to modify a package and push new versions.
Handy when you need to know who to bug for help.
* add:
Add a new user as a maintainer of a package. This user is enabled to modify
metadata, publish new versions, and add other owners.
* rm:
Remove a user from the package owner list. This immediately revokes their
privileges.
Note that there is only one level of access. Either you can modify a package,
or you can't. Future versions may contain more fine-grained access levels, but
that is not implemented at this time.
## SEE ALSO
* npm-publish(1)
* npm-registry(1)
npm-prefix(1) -- Display prefix
===============================
## SYNOPSIS
npm prefix
## DESCRIPTION
Print the prefix to standard out.
npm-prune(1) -- Remove extraneous packages
==========================================
## SYNOPSIS
npm prune [<name> [<name ...]]
## DESCRIPTION
This command removes "extraneous" packages. If a package name is
provided, then only packages matching one of the supplied names are
removed.
Extraneous packages are packages that are not listed on the parent
package's dependencies list.
npm-publish(1) -- Publish a package
===================================
## SYNOPSIS
npm publish <tarball>
npm publish <folder>
## DESCRIPTION
Publishes a package to the registry so that it can be installed by name.
* `<folder>`:
A folder containing a package.json file
* `<tarball>`:
A url or file path to a gzipped tar archive containing a single folder
with a package.json file inside.
Fails if the package name and version combination already exists in
the registry. Overwrites when the "--force" flag is set.
## SEE ALSO
* npm-registry(1)
* npm-adduser(1)
* npm-owner(1)
npm-rebuild(1) -- Rebuild a package
===================================
## SYNOPSIS
npm rebuild [<name> [<name> ...]]
* `<name>`:
The package to rebuild
## DESCRIPTION
This command runs the `npm build` command on the matched folders. This is useful
when you install a new version of node, and must recompile all your C++ addons with
the new binary.
## CONFIGURATION
See `npm help build`
npm-registry(1) -- The JavaScript Package Registry
==================================================
## DESCRIPTION
To resolve packages by name and version, npm talks to a registry website
that implements the CommonJS Package Registry specification for reading
package info.
Additionally, npm's package registry implementation supports several
write APIs as well, to allow for publishing packages and managing user
account information.
The official public npm registry is at <http://registry.npmjs.org/>. It
is powered by a CouchDB database at
<http://isaacs.couchone.com/registry>. The code for the couchapp is
available at <http://github.com/isaacs/npmjs.org>. npm user accounts
are CouchDB users, stored in the <http://isaacs.couchone.com/_users>
database.
The registry URL is supplied by the `registry` config parameter. See
`npm help config` for more on managing npm's configuration.
## Can I run my own private registry?
Yes!
The easiest way is to replicate the couch database, and use the same (or
similar) design doc to implement the APIs.
If you set up continuous replication from the official CouchDB, and then
set your internal CouchDB as the registry config, then you'll be able
to read any published packages, in addition to your private ones, and by
default will only publish internally. If you then want to publish a
package for the whole world to see, you can simply override the
`--registry` config for that command.
## Will you replicate from my registry into the public one?
No. If you want things to be public, then publish them into the public
registry using npm. What little security there is would be for nought
otherwise.
## Do I have to use couchdb to build a registry that npm can talk to?
No, but it's way easier.
## I published something elsewhere, and want to tell the npm registry about it.
That is supported, but not using the npm client. You'll have to get
your hands dirty and do some HTTP. The request looks something like
this:
PUT /my-foreign-package
content-type:application/json
accept:application/json
authorization:Basic $base_64_encoded
{ "name":"my-foreign-package"
, "maintainers":["owner","usernames"]
, "description":"A package that is hosted elsewhere"
, "keywords":["nih","my cheese smells the best"]
, "url":"http://my-different-registry.com/blerg/my-local-package"
}
(Keywords and description are optional, but recommended. Name,
maintainers, and url are required.)
Then, when a user tries to install "my-foreign-package", it'll redirect
to your registry. If that doesn't resolve to a valid package entry,
then it'll fail, so please make sure that you understand the spec, and
ask for help on the <npm-@googlegroups.com> mailing list.
## Is there a website or something to see package docs and such?
No, but such a thing is planned, and a tiny bit developed.
Stay tuned!
npm-removal(1) -- Cleaning the Slate
====================================
So sad to see you go.
sudo npm uninstall npm -g
Or, if that fails,
sudo make uninstall
## More Severe Uninstalling
Usually, the above instructions are sufficient. That will remove
npm, but leave behind anything you've installed.
If that doesn't work, or if you require more drastic measures,
continue reading.
This assumes that you installed node and npm in the default place. If
you configured node with a different `--prefix`, or installed npm with a
different prefix setting, then adjust the paths accordingly, replacing
`/usr/local` with your install prefix.
rm -rf /usr/local/{lib/node,lib/node/.npm,bin,share/man}/npm*
If you installed things *with* npm, then your best bet is to uninstall
them with npm first, and then install them again once you have a
proper install. This can help find any symlinks that are lying
around:
ls -laF /usr/local/{lib/node,lib/node/.npm,bin,share/man} | grep npm
Prior to version 0.3, npm used shim files for executables and node
modules. To track those down, you can do the following:
find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ;
(This is also in the README file.)
npm-restart(1) -- Start a package
=================================
## SYNOPSIS
npm restart <name>
## DESCRIPTION
This runs a package's "restart" script, if one was provided.
Otherwise it runs package's "stop" script, if one was provided, and then
the "start" script.
If no version is specified, then it restarts the "active" version.
## SEE ALSO
* npm-start(1)
* npm-stop(1)
./uninstall.md
\ No newline at end of file
npm-root(1) -- Display npm root
===============================
## SYNOPSIS
npm root
## DESCRIPTION
Print the effective `node_modules` folder to standard out.
npm-run-script(1) -- Run arbitrary package scripts
==================================================
## SYNOPSIS
npm run-script <script> <name>
## DESCRIPTION
This runs an arbitrary command from a package's "scripts" object.
It is used by the test, start, restart, and stop commands, but can be
called directly, as well.
## SEE ALSO
* npm-scripts(1)
* npm-test(1)
* npm-start(1)
* npm-restart(1)
* npm-stop(1)
npm-scripts(1) -- How npm handles the "scripts" field
=====================================================
## DESCRIPTION
npm supports the "scripts" member of the package.json script, for the
following scripts:
* preinstall:
Run BEFORE the package is installed
* install, postinstall:
Run AFTER the package is installed.
* preuninstall, uninstall:
Run BEFORE the package is uninstalled.
* postuninstall:
Run AFTER the package is uninstalled.
* preupdate:
Run BEFORE the package is updated with the update command.
* update, postupdate:
Run AFTER the package is updated with the update command.
* prepublish:
Run BEFORE the package is published.
* publish, postpublish:
Run AFTER the package is published.
* pretest, test, posttest:
Run by the `npm test` command.
* prestop, stop, poststop:
Run by the `npm stop` command.
* prestart, start, poststart:
Run by the `npm start` command.
* prerestart, restart, postrestart:
Run by the `npm restart` command. Note: `npm restart` will run the
stop and start scripts if no `restart` script is provided.
Additionally, arbitrary scrips can be run by doing
`npm run-script <stage> <pkg>`.
## ENVIRONMENT
Package scripts run in an environment where many pieces of information are
made available regarding the setup of npm and the current state of the
process.
### package.json vars
The package.json fields are tacked onto the `npm_package_` prefix. So, for
instance, if you had `{"name":"foo", "version":"1.2.5"}` in your package.json
file, then your package scripts would have the `npm_package_name` environment
variable set to "foo", and the `npm_package_version` set to "1.2.5"
### configuration
Configuration parameters are put in the environment with the `npm_config_`
prefix. For instance, you can view the effective `root` config by checking the
`npm_config_root` environment variable.
### Special: package.json "config" hash
The package.json "config" keys are overwritten in the environment if
there is a config param of `<name>[@<version>]:<key>`. For example, if
the package.json has this:
{ "name" : "foo"
, "config" : { "port" : "8080" }
, "scripts" : { "start" : "node server.js" } }
and the server.js is this:
http.createServer(...).listen(process.env.npm_package_config_port)
then the user could change the behavior by doing:
npm config set foo:port 80
### current lifecycle event
Lastly, the `npm_lifecycle_event` environment variable is set to whichever
stage of the cycle is being executed. So, you could have a single script used
for different parts of the process which switches based on what's currently
happening.
Objects are flattened following this format, so if you had
`{"scripts":{"install":"foo.js"}}` in your package.json, then you'd see this
in the script:
process.env.npm_package_scripts_install === "foo.js"
## EXAMPLES
For example, if your package.json contains this:
{ "scripts" :
{ "install" : "scripts/install.js"
, "postinstall" : "scripts/install.js"
, "activate" : "scripts/install.js"
, "uninstall" : "scripts/uninstall.js"
}
}
then the `scripts/install.js` will be called for the install, post-install,
and activate stages of the lifecycle, and the `scripts/uninstall.js` would be
called when the package is uninstalled. Since `scripts/install.js` is running
for three different phases, it would be wise in this case to look at the
`npm_lifecycle_event` environment variable.
If you want to run a make command, you can do so. This works just fine:
{ "scripts" :
{ "preinstall" : "./configure"
, "install" : "make && make install"
, "test" : "make test"
}
}
## EXITING
Scripts are run by passing the line as a script argument to `sh`.
If the script exits with a code other than 0, then this will abort the
process.
Note that these script files don't have to be nodejs or even javascript
programs. They just have to be some kind of executable file.
## HOOK SCRIPTS
If you want to run a specific script at a specific lifecycle event for ALL
packages, then you can use a hook script.
Place an executable file at `node_modules/.hooks/{eventname}`, and it'll get
run for all packages when they are going through that point in the package
lifecycle for any packages installed in that root.
Hook scripts are run exactly the same way as package.json scripts. That is,
they are in a separate child process, with the env described above.
## BEST PRACTICES
* Don't exit with a non-zero error code unless you *really* mean it.
Except for uninstall/deactivate scripts, this will cause the npm action
to fail, and potentially be rolled back. If the failure is minor or
only will prevent some optional features, then it's better to just
print a warning and exit successfully.
* Try not to use scripts to do what npm can do for you. Read through
`npm help json` to see all the things that you can specify and enable
by simply describing your package appropriately. In general, this will
lead to a more robust and consistent state.
* Inspect the env to determine where to put things. For instance, if
the `npm_config_binroot` environ is set to `/home/user/bin`, then don't
try to install executables into `/usr/local/bin`. The user probably
set it up that way for a reason.
* Don't prefix your script commands with "sudo". If root permissions are
required for some reason, then it'll fail with that error, and the user
will sudo the npm command in question.
npm-ls(1) -- List installed packages
======================================
## SYNOPSIS
npm search [search terms ...]
## DESCRIPTION
Search the registry for packages matching the search terms.
config.md
\ No newline at end of file
npm-start(1) -- Start a package
===============================
## SYNOPSIS
npm start <name>
## DESCRIPTION
This runs a package's "start" script, if one was provided.
npm-stop(1) -- Stop a package
=============================
## SYNOPSIS
npm stop <name>
## DESCRIPTION
This runs a package's "stop" script, if one was provided.
npm-tag(1) -- Tag a published version
=====================================
## SYNOPSIS
npm tag <name>@<version> [<tag>]
## DESCRIPTION
Tags the specified version of the package with the specified tag, or the
`--tag` config if not specified.
npm-test(1) -- Test a package
=============================
## SYNOPSIS
npm test <name>
## DESCRIPTION
This runs a package's "test" script, if one was provided.
To run tests as a condition of installation, set the `npat` config to
true.
npm-uninstall(1) -- Remove a package
====================================
## SYNOPSIS
npm uninstall <name>
npm rm <name>
## DESCRIPTION
This uninstalls a package, completely removing everything installed for it.
npm-unpublish(1) -- Remove a package from the registry
======================================================
## SYNOPSIS
npm unpublish <name>[@<version>]
## DESCRIPTION
This removes a package version from the registry, deleting its
entry and removing the tarball.
If no version is specified, or if all versions are removed then
the root package entry is removed from the registry entirely.
npm-update(1) -- Update a package
=================================
## SYNOPSIS
npm update [<name> [<name> ...]]
## DESCRIPTION
This command will update all the packages listed to the latest version
(specified by the `tag` config).
It will also install missing packages.
npm-version(1) -- Bump a package version
========================================
## SYNOPSIS
npm version <newversion>
## DESCRIPTION
Run this in a package directory to bump the version and write the new
data back to the package.json file.
If run in a git repo, it will also create a version commit and tag, and
fail if the repo is not clean.
npm-view(1) -- View registry info
=================================
## SYNOPSIS
npm view <name>[@<version>] [<field>[.<subfield>]...]
## DESCRIPTION
This command shows data about a package and prints it to the stream
referenced by the `outfd` config, which defaults to stdout.
To show the package registry entry for the `connect` package, you can do
this:
npm view connect
The default version is "latest" if unspecified.
Field names can be specified after the package descriptor.
For example, to show the dependencies of the `ronn` package at version
0.3.5, you could do the following:
npm view ronn@0.3.5 dependencies
You can view child field by separating them with a period.
To view the git repository URL for the latest version of npm, you could
do this:
npm view npm repository.url
This makes it easy to view information about a dependency with a bit of
shell scripting. For example, to view all the data about the version of
opts that ronn depends on, you can do this:
npm view opts@$(npm view ronn dependencies.opts)
For fields that are arrays, requesting a non-numeric field will return
all of the values from the objects in the list. For example, to get all
the contributor names for the "express" project, you can do this:
npm view express contributors.email
You may also use numeric indices in square braces to specifically select
an item in an array field. To just get the email address of the first
contributor in the list, you can do this:
npm view express contributors[0].email
Multiple fields may be specified, and will be printed one after another.
For exampls, to get all the contributor names and email addresses, you
can do this:
npm view express contributors.name contributors.email
"Person" fields are shown as a string if they would be shown as an
object. So, for example, this will show the list of npm contributors in
the shortened string format. (See `npm help json` for more on this.)
npm view npm contributors
If a version range is provided, then data will be printed for every
matching version of the package. This will show which version of jsdom
was required by each matching version of yui3:
npm view yui3@'>0.5.4' dependencies.jsdom
## OUTPUT
If only a single string field for a single version is output, then it
will not be colorized or quoted, so as to enable piping the output to
another command.
If the version range matches multiple versions, than each printed value
will be prefixed with the version it applies to.
If multiple fields are requested, than each of them are prefixed with
the field name.
npm-whoami(1) -- Display npm username
=====================================
## SYNOPSIS
npm whoami
## DESCRIPTION
Print the `username` config to standard output.
<!doctype html>
<html>
<head>
<style>
html { background:#202050;
font-family:CentSchbook Mono BT, Bitstream Vera Sans Mono, monofont, monospace;
}
body { background:#ddd; width:600px; border:10px solid #fff; margin:2em auto; padding:2em }
h1 {
font-size:200px;
line-height:1;
font-family:"gubblebum-blocky", monospace;
color:#f00;
text-align:center;
padding:0;
margin:0 auto;
text-indent:-999em;
height:202px;
width:519px;
background:url(npm.png) center;
}
h2 {
color:#202050;
font-size:100%;
}
p, ul, ol { margin:1em 0 0; padding:0 }
li { list-style-position:inside }
a { color:#f00; text-decoration:none; }
a:hover { text-decoration:underline; }
code { background:#fff ; outline: 1px solid #ccc; padding:0 2px; }
@font-face {
font-family:monofont;
src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMono.ttf) format("truetype");
}
@font-face {
font-family:monofont;
font-style:italic;
src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMoIt.ttf) format("truetype");
}
@font-face {
font-family:monofont;
font-weight:bold;
src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMoBd.ttf) format("truetype");
}
@font-face {
font-family:monofont;
font-style:italic;
font-weight:bold;
src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMoBI.ttf) format("truetype");
}
</style>
<title>npm - Node Package Manager</title>
</head>
<h1>npm</h1>
<p>npm is a package manager for <a href="http://nodejs.org/">node</a>. You can use it to install
and publish your node programs. It manages dependencies and does other cool stuff.</p>
<h2>One Line Install</h2>
<code>curl http://npmjs.org/install.sh | sh</code>
<h2>More Than One Line Install</h2>
<ol>
<li><a href="https://github.com/isaacs/npm">Get the code.</a>
<li>Do what <a href="https://github.com/isaacs/npm#readme">the README</a>
says to do.
</ol>
<h2>Other Cool Stuff</h2>
<ul>
<li><a href="https://github.com/isaacs/npm#readme">README</a>
<li><a href="https://github.com/isaacs/npm/blob/master/doc/faq.md#readme">FAQ</a>
<li><a href="http://search.npmjs.org/">Search for Packages</a>
<li><a href="http://groups.google.com/group/npm-">Mailing List</a>
<li><a href="https://github.com/isaacs/npm/issues">Bugs</a>
</ul>
</body>
</html>
module.exports = adduser
var registry = require('./utils/npm-registry-client')
, ini = require("./utils/ini")
, log = require("./utils/log")
, npm = require("../npm")
, prompt = require("./utils/prompt")
, promiseChain = require("./utils/promise-chain")
, crypto
try {
crypto = process.binding("crypto") && require("crypto")
} catch (ex) {}
adduser.usage = "npm adduser\nThen enter stuff at the prompts"
function adduser (args, cb) {
if (!crypto) return cb(new Error(
"You must compile node with ssl support to use the adduser feature"))
var u = { u : npm.config.get("username")
, p : npm.config.get("_password")
, e : npm.config.get("email")
}
, changed = false
promiseChain(cb)
(prompt, ["Username: ", u.u], function (un) {
changed = u.u !== un
u.u = un
})
(function (cb) {
if (u.p && !changed) return cb(null, u.p)
prompt("Password: ", u.p, true, cb)
}, [], function (pw) { u.p = pw })
(prompt, ["Email: ", u.e], function (em) { u.e = em })
(function (cb) {
if (changed) npm.config.del("_auth")
registry.adduser(u.u, u.p, u.e, function (er) {
if (er) return cb(er)
ini.set("username", u.u, "user")
ini.set("_password", u.p, "user")
ini.set("email", u.e, "user")
log("Authorized user " + u.u, "adduser")
ini.save(cb)
})
})
()
}
module.exports = bin
var npm = require("../npm")
, output = require("./utils/output")
bin.usage = "npm bin\nnpm bin -g\n(just prints the bin folder)"
function bin (args, cb) {
var path = require("path")
, global = npm.config.get("global")
, b = global ? path.join(npm.prefix, "bin") : path.join(npm.dir, ".bin")
, PATH = (process.env.PATH || "").split(":")
output.write(b, cb)
if (npm.config.get("global") && PATH.indexOf(b) === -1) {
output.write("(not in PATH env variable)"
,npm.config.get("logfd"))
}
}
// npm build command
// everything about the installation after the creation of
// the .npm/{name}/{version}/package folder.
// linking the modules into the npm.root,
// resolving dependencies, etc.
// This runs AFTER install or link are completed.
var npm = require("../npm")
, log = require("./utils/log")
, chain = require("./utils/chain")
, fs = require("./utils/graceful-fs")
, path = require("path")
, lifecycle = require("./utils/lifecycle")
, readJson = require("./utils/read-json")
, link = require("./utils/link")
, linkIfExists = link.ifExists
, asyncMap = require("./utils/async-map")
, output = require("./utils/output")
module.exports = build
build.usage = "npm build <folder>\n(this is plumbing)"
build._didBuild = {}
build._noLC = {}
function build (args, global, didPre, didRB, cb) {
if (typeof cb !== "function") cb = didRB, didRB = false
if (typeof cb !== "function") cb = didPre, didPre = false
if (typeof cb !== "function") {
cb = global, global = npm.config.get("global")
}
// it'd be nice to asyncMap these, but actually, doing them
// in parallel generally munges up the output from node-waf
var builder = build_(global, didPre, didRB)
chain(args.map(function (arg) { return function (cb) {
builder(arg, cb)
}}).concat(cb))
}
function build_ (global, didPre, didRB) { return function (folder, cb) {
folder = path.resolve(folder)
build._didBuild[folder] = true
log.info(folder, "build")
readJson(path.resolve(folder, "package.json"), function (er, pkg) {
if (er) return cb(er)
chain
( !didPre && [lifecycle, pkg, "preinstall", folder]
, [linkStuff, pkg, folder, global, didRB]
, didPre !== build._noLC && [lifecycle, pkg, "install", folder]
, didPre !== build._noLC && [lifecycle, pkg, "postinstall", folder]
, didPre !== build._noLC
&& npm.config.get("npat")
&& [lifecycle, pkg, "test", folder]
, cb )
})
}}
function linkStuff (pkg, folder, global, didRB, cb) {
// if it's global, and folder is in {prefix}/node_modules,
// then bins are in {prefix}/bin
// otherwise, then bins are in folder/../.bin
var parent = path.dirname(folder)
, gnm = global && path.resolve(npm.config.get("prefix")
, "lib", "node_modules")
, top = parent === npm.dir
, gtop = parent === gnm
log.verbose([global, gnm, gtop, parent], "linkStuff")
log(pkg._id, "linkStuff")
if (top && pkg.preferGlobal && !global) {
log.warn(pkg._id + " should be installed with -g", "prefer global")
}
asyncMap( [linkBins, linkMans, !didRB && rebuildBundles]
, function (fn, cb) {
if (!fn) return cb()
log.verbose(pkg._id, fn.name)
fn(pkg, folder, parent, gtop, cb)
}, cb)
}
function rebuildBundles (pkg, folder, parent, gtop, cb) {
if (!npm.config.get("rebuild-bundle")) return cb()
var deps = Object.keys(pkg.dependencies || {})
.concat(Object.keys(pkg.devDependencies || {}))
, bundles = pkg.bundleDependencies || pkg.bundledDependencies || []
fs.readdir(path.resolve(folder, "node_modules"), function (er, files) {
// error means no bundles
if (er) return cb()
log.verbose(files, "rebuildBundles")
// don't asyncMap these, because otherwise build script output
// gets interleaved and is impossible to read
chain(files.filter(function (file) {
// rebuild if:
// not a .folder, like .bin or .hooks
return file.charAt(0) !== "."
// not some old 0.x style bundle
&& file.indexOf("@") === -1
// either not a dep, or explicitly bundled
&& (deps.indexOf(file) === -1 || bundles.indexOf(file) !== -1)
}).map(function (file) {
file = path.resolve(folder, "node_modules", file)
return function (cb) {
if (build._didBuild[file]) return cb()
log.verbose(file, "rebuild bundle")
// if not a dir, then don't do it.
fs.lstat(file, function (er, st) {
if (er || !st.isDirectory()) return cb()
build_(false)(file, cb)
})
}}).concat(cb))
})
}
function linkBins (pkg, folder, parent, gtop, cb) {
if (!pkg.bin || !gtop && path.basename(parent) !== "node_modules") {
return cb()
}
var binRoot = gtop ? path.resolve(npm.config.get("prefix"), "bin")
: path.resolve(parent, ".bin")
log.verbose([pkg.bin, binRoot, gtop], "bins linking")
asyncMap(Object.keys(pkg.bin), function (b, cb) {
linkIfExists( path.resolve(folder, pkg.bin[b])
, path.resolve(binRoot, b)
, gtop && folder
, function (er) {
if (er) return cb(er)
// bins should always be executable.
fs.chmod(path.resolve(folder, pkg.bin[b]), 0755, function (er) {
if (er || !gtop) return cb(er)
output.write( path.resolve(binRoot, b)+" -> "
+ path.resolve(folder, pkg.bin[b]), cb)
})
})
}, cb)
}
function linkMans (pkg, folder, parent, gtop, cb) {
if (!pkg.man || !gtop) return cb()
var manRoot = path.resolve(npm.config.get("prefix"), "share", "man")
asyncMap(pkg.man, function (man, cb) {
var parseMan = man.match(/(.*)\.([0-9]+)(\.gz)?$/)
, stem = parseMan[1]
, sxn = parseMan[2]
, gz = parseMan[3] || ""
, bn = path.basename(stem)
, manSrc = path.join( folder, man )
, manDest = path.join( manRoot
, "man"+sxn
, (bn.indexOf(pkg.name) === 0 ? bn
: pkg.name + "-" + bn)
+ "." + sxn + gz
)
linkIfExists(manSrc, manDest, gtop && folder, cb)
}, cb)
}
This diff is collapsed.
module.exports = completion
completion.usage = "npm completion >> ~/.bashrc"
var output = require("./utils/output")
, configDefs = require("./utils/config-defs")
, configTypes = configDefs.types
, shorthands = configDefs.shorthands
, nopt = require("nopt")
, configNames = Object.keys(configTypes).filter(function (e) {
return e.charAt(0) !== "_"
})
, shorthandNames = Object.keys(shorthands)
, allConfs = configNames.concat(shorthandNames)
, stdio = process.binding("stdio")
, npm = require("../npm")
completion.completion = function (opts, cb) {
if (opts.w > 3) return cb()
var fs = require("fs")
, path = require("path")
, bashExists = null
, zshExists = null
, bashProfExists = null
fs.stat(path.resolve(process.env.HOME, ".bashrc"), function (er, b) {
bashExists = !er
next()
})
fs.stat(path.resolve(process.env.HOME, ".zshrc"), function (er, b) {
zshExists = !er
next()
})
function next () {
if (zshExists === null || bashExists === null) return
var out = []
if (zshExists) out.push("~/.zshrc")
if (bashExists) out.push("~/.bashrc")
if (opts.w === 2) out = out.map(function (m) {
return [">>", m]
})
cb(null, out)
}
}
function completion (args, cb) {
// if the COMP_* isn't in the env, then just dump the script.
if (process.env.COMP_CWORD === undefined
||process.env.COMP_LINE === undefined
||process.env.COMP_POINT === undefined
) return dumpScript(cb)
console.error(process.env.COMP_CWORD)
console.error(process.env.COMP_LINE)
console.error(process.env.COMP_POINT)
//console.log("abracadabrasauce\nabracad cat monger")
//if (Math.random() * 3 < 1) console.log("man\\ bear\\ pig")
//else if (Math.random() * 3 < 1)
// console.log("porkchop\\ sandwiches\nporkman")
//else console.log("encephylophagy")
// get the partial line and partial word,
// if the point isn't at the end.
// ie, tabbing at: npm foo b|ar
var w = +process.env.COMP_CWORD
, words = args.map(unescape)
, word = words[w]
, line = process.env.COMP_LINE
, point = +process.env.COMP_POINT
, lineLength = line.length
, partialLine = line.substr(0, point)
, partialWords = words.slice(0, w)
// figure out where in that last word the point is.
var partialWord = args[w]
, i = partialWord.length
while (partialWord.substr(0, i) !== partialLine.substr(-1*i) && i > 0) {
i --
}
partialWord = unescape(partialWord.substr(0, i))
partialWords.push(partialWord)
var opts = { words : words
, w : w
, word : word
, line : line
, lineLength : line.length
, point : point
, partialLine : partialLine
, partialWords : partialWords
, partialWord : partialWord
, raw: args
}
cb = wrapCb(cb, opts)
console.error(opts)
if (partialWords.slice(0, -1).indexOf("--") === -1) {
if (word.charAt(0) === "-") return configCompl(opts, cb)
if (words[w - 1]
&& words[w - 1].charAt(0) === "-"
&& !isFlag(words[w - 1])) {
// awaiting a value for a non-bool config.
// don't even try to do this for now
console.error("configValueCompl")
return configValueCompl(opts, cb)
}
}
// try to find the npm command.
// it's the first thing after all the configs.
// take a little shortcut and use npm's arg parsing logic.
// don't have to worry about the last arg being implicitly
// boolean'ed, since the last block will catch that.
var parsed = opts.conf =
nopt(configTypes, shorthands, partialWords.slice(0, -1), 0)
// check if there's a command already.
console.error(parsed)
var cmd = parsed.argv.remain[1]
if (!cmd) return cmdCompl(opts, cb)
Object.keys(parsed).forEach(function (k) {
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require("./utils/graceful-fs")
, path = require("path")
, p = path.resolve(__dirname, "utils/completion.sh")
fs.readFile(p, "utf8", function (er, d) {
d = d.replace(/^\#\!.*?\n/, "")
process.stdout.write(d, cb)
})
}
function unescape (w) {
if (w.charAt(0) === "\"") return w.replace(/^"|"$/g, "")
else return w.replace(/\\ /g, " ")
}
function escape (w) {
if (!w.match(/\s+/)) return w
return "\"" + w + "\""
}
// The command should respond with an array. Loop over that,
// wrapping quotes around any that have spaces, and writing
// them to stdout. Use console.log, not the outfd config.
// If any of the items are arrays, then join them with a space.
// Ie, returning ["a", "b c", ["d", "e"]] would allow it to expand
// to: "a", "b c", or "d" "e"
function wrapCb (cb, opts) { return function (er, compls) {
if (!Array.isArray(compls)) compls = compls ? [compls] : []
compls = compls.map(function (c) {
if (Array.isArray(c)) c = c.map(escape).join(" ")
else c = escape(c)
return c
})
if (opts.partialWord) compls = compls.filter(function (c) {
return c.indexOf(opts.partialWord) === 0
})
console.error([er && er.stack, compls, opts.partialWord])
if (er || compls.length === 0) return cb(er)
output.write(compls.join("\n"), stdio.stdoutFD, false, cb)
}}
// the current word has a dash. Return the config names,
// with the same number of dashes as the current word has.
function configCompl (opts, cb) {
var word = opts.word
, split = word.match(/^(-+)((?:no-)*)(.*)$/)
, dashes = split[1]
, no = split[2]
, conf = split[3]
, confs = allConfs
, flags = configNames.filter(isFlag)
console.error(flags)
return cb(null, allConfs.map(function (c) {
return dashes + c
}).concat(flags.map(function (f) {
return dashes + (no || "no-") + f
})))
}
// expand with the valid values of various config values.
// not yet implemented.
function configValueCompl (opts, cb) {
console.error('configValue', opts)
return cb(null, [])
}
// check if the thing is a flag or not.
function isFlag (word) {
// shorthands never take args.
var split = word.match(/^(-*)((?:no-)+)?(.*)$/)
, dashes = split[1]
, no = split[2]
, conf = split[3]
return no || configTypes[conf] === Boolean || shorthands[conf]
}
// complete against the npm commands
function cmdCompl (opts, cb) {
return cb(null, npm.fullList)
}
module.exports = config
config.usage = "npm config set <key> <value>"
+ "\nnpm config get <key>"
+ "\nnpm config delete <key>"
+ "\nnpm config list"
+ "\nnpm config edit"
var ini = require("./utils/ini")
, log = require("./utils/log")
, npm = require("../npm")
, exec = require("./utils/exec")
, fs = require("./utils/graceful-fs")
, dc
, output = require("./utils/output")
, types = require("./utils/config-defs").types
config.completion = function (opts, cb) {
var argv = opts.conf.argv.remain
if (argv[1] !== "config") argv.unshift("config")
if (argv.length === 2) {
var cmds = ["get", "set", "delete", "ls", "rm", "edit"]
if (opts.partialWord !== "l") cmds.push("list")
return cb(null, cmds)
}
var action = argv[2]
switch (action) {
case "set":
// todo: complete with valid values, if possible.
if (argv.length > 3) return cb(null, [])
// fallthrough
case "get":
case "delete":
case "rm":
return cb(null, Object.keys(types))
case "edit":
case "list": case "ls":
return cb(null, [])
default: return cb(null, [])
}
}
// npm config set key value
// npm config get key
// npm config list
function config (args, cb) {
var action = args.shift()
switch (action) {
case "set": return set(args[0], args[1], cb)
case "get": return get(args[0], cb)
case "delete": case "rm": case "del": return del(args[0], cb)
case "list": case "ls": return list(cb)
case "edit": return edit(cb)
default: return unknown(action, cb)
}
}
function edit (cb) {
var e = ini.get("editor")
, f = ini.get(ini.get("global") ? "globalconfig" : "userconfig")
if (!e) return cb(new Error("No EDITOR config or environ set."))
ini.save(function (er) {
if (er) return cb(er)
fs.readFile(f, "utf8", function (er, data) {
if (er) data = ""
dc = dc || require("./utils/config-defs").defaults
data = [ ";;;;"
, "; npm "+(ini.get("global") ? "globalconfig" : "userconfig")+" file"
, "; this is a simple ini-formatted file"
, "; lines that start with semi-colons are comments, and removed."
, "; read `npm help config` for help on the various options"
, ";;;;"
, ""
, data
].concat( [ ";;;;"
, "; all options with default values"
, ";;;;"
]
)
.concat(Object.keys(dc).map(function (k) {
return "; " + k + " = " + ini.unParseField(dc[k],k)
}))
.concat([""])
.join("\n")
fs.writeFile
( f
, data
, "utf8"
, function (er) {
if (er) return cb(er)
exec("sh", ["-c", e + " "+f], function (er) {
if (er) return cb(er)
ini.resolveConfigs(function (er) {
if (er) return cb(er)
ini.save(cb)
})
})
}
)
})
})
}
function del (key, cb) {
if (!key) return cb(new Error("no key provided"))
ini.del(key)
ini.save(cb)
}
function set (key, val, cb) {
if (val === undefined) {
if (key.indexOf("=") !== -1) {
var k = key.split("=")
key = k.shift()
val = k.join("=")
} else {
val = ""
}
}
key = key.trim()
val = val.trim()
log("set "+key+" "+val, "config")
var where = ini.get("global") ? "global" : "user"
ini.set(key, val, where)
ini.save(cb)
}
function get (key, cb) {
if (!key) return list(cb)
if (key.charAt(0) === "_") {
return cb(new Error("---sekretz---"))
}
output.write(npm.config.get(key), cb)
}
function sort (a, b) {
return a > b ? 1 : -1
}
function reverse (a, b) {
return a > b ? -1 : 1
}
function list (cb) {
var msg = ""
, long = npm.config.get("long")
// cli configs.
// show any that aren't secret
var cli = ini.configList.list[ini.TRANS.cli]
, cliKeys = Object.keys(cli).filter(function (k) {
return !(k.charAt(0) === "_" || types[k] !== types[k])
}).sort(function (a, b) {
return a > b ? 1 : -1
})
if (cliKeys.length) {
msg += "; cli configs\n"
cliKeys.forEach(function (k) {
msg += k + " = " + JSON.stringify(cli[k]) + "\n"
})
msg += "\n"
}
// env configs
var env = ini.configList.list[ini.TRANS.env]
, envKeys = Object.keys(env).filter(function (k) {
return !(k.charAt(0) === "_" || types[k] !== types[k])
}).sort(function (a, b) {
return a > b ? 1 : -1
})
if (envKeys.length) {
msg += "; environment configs\n"
envKeys.forEach(function (k) {
if (env[k] !== ini.get(k)) {
if (!long) return
msg += "; " + k + " = " + JSON.stringify(env[k])
+ " (overridden)\n"
} else msg += k + " = " + JSON.stringify(env[k]) + "\n"
})
msg += "\n"
}
// user config file
var uconf = ini.configList.list[ini.TRANS.user]
, uconfKeys = Object.keys(uconf).filter(function (k) {
return types[k] === types[k]
}).sort(function (a, b) {
return a > b ? 1 : -1
})
if (uconfKeys.length) {
msg += "; userconfig " + ini.get("userconfig") + "\n"
uconfKeys.forEach(function (k) {
var val = (k.charAt(0) === "_")
? "---sekretz---"
: JSON.stringify(uconf[k])
if (uconf[k] !== ini.get(k)) {
if (!long) return
msg += "; " + k + " = " + val
+ " (overridden)\n"
} else msg += k + " = " + val + "\n"
})
msg += "\n"
}
// global config file
var gconf = ini.configList.list[ini.TRANS.global]
, gconfKeys = Object.keys(gconf).filter(function (k) {
return types[k] === types[k]
}).sort(function (a, b) {
return a > b ? 1 : -1
})
if (gconfKeys.length) {
msg += "; globalconfig " + ini.get("globalconfig") + "\n"
gconfKeys.forEach(function (k) {
var val = (k.charAt(0) === "_")
? "---sekretz---"
: JSON.stringify(gconf[k])
if (gconf[k] !== ini.get(k)) {
if (!long) return
msg += "; " + k + " = " + val
+ " (overridden)\n"
} else msg += k + " = " + val + "\n"
})
msg += "\n"
}
// only show defaults if --long
if (!long) {
msg += "; node install prefix = " + process.installPrefix + "\n"
+ "; node bin location = " + process.execPath + "\n"
+ "; cwd = " + process.cwd() + "\n"
+ "; HOME = " + process.env.HOME + "\n"
+ "; 'npm config ls -l' to show all defaults.\n"
return output.write(msg, cb)
}
var defaults = ini.defaultConfig
, defKeys = Object.keys(defaults)
msg += "; default values\n"
defKeys.forEach(function (k) {
var val = JSON.stringify(defaults[k])
if (defaults[k] !== ini.get(k)) {
if (!long) return
msg += "; " + k + " = " + val
+ " (overridden)\n"
} else msg += k + " = " + val + "\n"
})
msg += "\n"
return output.write(msg, cb)
}
function unknown (action, cb) {
cb("Usage:\n" + config.usage)
}
module.exports = deprecate
deprecate.usage = "npm deprecate <pkg>[@<version>] <message>"
deprecate.completion = function (opts, cb) {
// first, get a list of remote packages this user owns.
// once we have a user account, then don't complete anything.
var un = npm.config.get("username")
if (!npm.config.get("username")) return cb()
if (opts.conf.argv.remain.length > 2) return cb()
// get the list of packages by user
var uri = "/-/by-user/"+encodeURIComponent(un)
registry.get(uri, null, 60000, function (er, list) {
if (er) return cb()
console.error(list)
return cb(null, list[un])
})
}
var registry = require("./utils/npm-registry-client")
, semver = require("semver")
, log = require("./utils/log")
, asyncMap = require("./utils/async-map")
, npm = require("../npm")
function deprecate (args, cb) {
var pkg = args[0]
, msg = args[1]
if (msg === undefined) return cb(new Error(deprecate.usage))
// fetch the data and make sure it exists.
pkg = pkg.split(/@/)
var name = pkg.shift()
, ver = pkg.join("@")
if (semver.validRange(ver) === null) {
return cb(new Error("invalid version range: "+ver))
}
registry.get(name, function (er, data) {
if (er) return cb(er)
// filter all the versions that match
Object.keys(data.versions).filter(function (v) {
return semver.satisfies(v, ver)
}).forEach(function (v) {
data.versions[v].deprecated = msg
})
// now update the doc on the registry
registry.request.PUT(data._id, data, cb)
})
}
module.exports = docs
docs.usage = "npm docs <pkgname>"
docs.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb()
registry.get("/-/short", null, 60000, function (er, list) {
return cb(null, list || [])
})
}
var exec = require("./utils/exec")
, registry = require("./utils/npm-registry-client")
, npm = require("../npm")
, log = require("./utils/log")
function docs (args, cb) {
if (!args.length) return cb(docs.usage)
var n = args[0].split("@").shift()
registry.get(args[0], "latest", 3600, function (er, d) {
if (er) return cb(er)
var homepage = d.homepage
, repo = d.repository || d.repositories
if (homepage) return open(homepage, cb)
if (repo) {
if (Array.isArray(repo)) repo = repo.shift()
if (repo.url) repo = repo.url
log.verbose(repo, "repository")
if (repo) {
return open(repo.replace(/^git(@|:\/\/)/, 'http://')
.replace(/\.git$/, '')+"#readme", cb)
}
}
log.error(n+" doesn't appear to have a 'homepage'"
+" or 'repository.url' listed")
cb()
})
}
function open (url, cb) {
exec(npm.config.get("browser"), [url], log.er(cb,
"Failed to open "+url+" in a browser. It could be that the\n"+
"'browser' config is not set. Try doing this:\n"+
" npm config set browser google-chrome\n"+
"or:\n"+
" npm config set browser lynx\n"))
}
// npm edit <pkg>[@<version>]
// open the package folder in the $EDITOR
module.exports = edit
edit.usage = "npm edit <pkg>"
edit.completion = require("./utils/completion/installed-shallow")
var npm = require("../npm")
, exec = require("./utils/exec")
, path = require("path")
, fs = require("./utils/graceful-fs")
, log = require("./utils/log")
function edit (args, cb) {
var p = args[0]
if (args.length !== 1 || !p) return cb(edit.usage)
var editor = npm.config.get("editor")
if (!editor) return cb(new Error(
"No editor set. Set the 'editor' config, or $EDITOR environ."))
fs.lstat(path.resolve(npm.dir, p), function (er) {
if (er) return cb(er)
exec(editor, [path.resolve(npm.dir, p)], function (er) {
if (er) return cb(er)
npm.commands.rebuild(args, cb)
})
})
}
// npm expore <pkg>[@<version>]
// open a subshell to the package folder.
module.exports = explore
explore.usage = "npm explore <pkg> [ -- <cmd>]"
explore.completion = require("./utils/completion/installed-shallow")
var npm = require("../npm")
, exec = require("./utils/exec")
, path = require("path")
, fs = require("./utils/graceful-fs")
function explore (args, cb) {
if (args.length < 1 || !args[0]) return cb(explore.usage)
var p = args.shift()
args = args.join(" ").trim()
if (args) args = ["-c", args]
else args = []
var editor = npm.config.get("editor")
, cwd = path.resolve(npm.dir, p)
fs.stat(cwd, function (er, s) {
if (er || !s.isDirectory()) return cb(new Error(
"It doesn't look like "+p+" is installed."))
if (!args.length) console.log(
"\nExploring "+cwd+"\n"+
"Type 'exit' or ^D when finished\n")
exec(npm.config.get("shell"), args, null, true, cwd, function (er) {
// only fail if non-interactive.
if (!args.length) return cb()
cb(er)
})
})
}
module.exports = faq
faq.usage = "npm faq"
var npm = require("../npm")
function faq (args, cb) { npm.commands.help(["faq"], cb) }
module.exports = get
get.usage = "npm get <key> <value> (See `npm config`)"
var npm = require("../npm")
get.completion = npm.commands.config.completion
function get (args, cb) {
npm.commands.config(["get"].concat(args), cb)
}
module.exports = help
help.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb(null, [])
getSections(cb)
}
var fs = require("./utils/graceful-fs")
, path = require("path")
, exec = require("./utils/exec")
, npm = require("../npm")
, output = require("./utils/output")
function help (args, cb) {
var section = args.shift()
if (section === "help") {
section = !npm.config.get("usage") && "npm"
}
if (section) {
if ( npm.config.get("usage")
&& npm.commands[section]
&& npm.commands[section].usage
) {
npm.config.set("loglevel", "silent")
return output.write(npm.commands[section].usage, cb)
}
var section_path = path.join(__dirname, "../man1/"+section+".1")
return fs.stat
( section_path
, function (e, o) {
if (e) return cb(new Error("Help section not found: "+section))
// function exec (cmd, args, env, takeOver, cb) {
var manpath = path.join(__dirname, "..")
, env = {}
Object.keys(process.env).forEach(function (i) { env[i] = process.env[i] })
env.MANPATH = manpath
var viewer = npm.config.get("viewer")
switch (viewer) {
case "woman":
var args = ["-e", "(woman-find-file \"" + section_path + "\")"]
exec("emacsclient", args, env, true, cb)
break
default:
exec("man", [section], env, true, cb)
}
}
)
} else getSections(function (er, sections) {
if (er) return cb(er)
npm.config.set("loglevel", "silent")
output.write
( ["\nUsage: npm <command>"
, ""
, "where <command> is one of:"
, " "+wrap(Object.keys(npm.commands))
, ""
, "Add -h to any command for quick help."
, ""
, "Specify configs in the ini-formatted file at "
+ npm.config.get("userconfig")
, "or on the command line via: npm <command> --key value"
, "Config info can be viewed via: npm help config"
, ""
, "Help usage: npm help <section>"
, ""
, "where <section> is one of:"
, " " + wrap(sections)
, ""
, "Even more help at: npm help help"
].join("\n"), function () { cb(er) })
})
}
function wrap (arr) {
var out = ['']
, l = 0
arr.sort(function (a,b) { return a<b?-1:1 })
.forEach(function (c) {
if (out[l].length + c.length + 2 < 60) {
out[l] += ', '+c
} else {
out[l++] += ','
out[l] = c
}
})
return out.join("\n ").substr(2)
}
function getSections(cb) {
fs.readdir(path.join(__dirname, "../man1/"), function (er, files) {
if (er) return cb(er)
var sectionList = files.concat("help.1")
.filter(function (s) { return s.match(/\.1$/) })
.map(function (s) { return s.replace(/\.1$/, '')})
cb(null, sectionList)
})
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
module.exports = prefix
var npm = require("../npm")
, output = require("./utils/output")
prefix.usage = "npm prefix\nnpm prefix -g\n(just prints the prefix folder)"
function prefix (args, cb) { output.write(npm.prefix, cb) }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment