For example, the following are equivalent:
* `"~1.2.3" = ">=1.2.3 <1.3.0"`
-* `"~1.2" = ">=1.2.0 <2.0.0"`
-* `"~1" = ">=1.0.0 <2.0.0"`
+* `"~1.2" = ">=1.2.0 <1.3.0"`
+* `"~1" = ">=1.0.0 <1.1.0"`
### X Version Ranges
npm supports the "scripts" member of the package.json script, for the
following scripts:
+* prepublish:
+ Run BEFORE the package is published. (Also run on local `npm
+ install` without any arguments.)
+* publish, postpublish:
+ Run AFTER the package is published.
* preinstall:
Run BEFORE the package is installed
* install, postinstall:
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:
Additionally, arbitrary scrips can be run by doing
`npm run-script <stage> <pkg>`.
+## NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN
+
+**tl;dr** Don't use `install`. Use a `.gyp` file for compilation, and
+`prepublish` for anything else.
+
+You should almost never have to explicitly set a `preinstall` or
+`install` script. If you are doing this, please consider if there is
+another option.
+
+The only valid use of `install` or `preinstall` scripts is for
+compilation which must be done on the target architecture. In early
+versions of node, this was often done using the `node-waf` scripts, or
+a standalone `Makefile`, and early versions of npm required that it be
+explicitly set in package.json. This was not portable, and harder to
+do properly.
+
+In the current version of node, the standard way to do this is using a
+`.gyp` file. If you have a file with a `.gyp` extension in the root
+of your package, then npm will run the appropriate `node-gyp` commands
+automatically at install time. This is the only officially supported
+method for compiling binary addons, and does not require that you add
+anything to your package.json file.
+
+If you have to do other things before your package is used, in a way
+that is not dependent on the operating system or architecture of the
+target system, then use a `prepublish` script instead. This includes
+tasks such as:
+
+* Compile CoffeeScript source code into JavaScript.
+* Create minified versions of JavaScript source code.
+* Fetching remote resources that your package will use.
+
+The advantage of doing these things at `prepublish` time instead of
+`preinstall` or `install` time is that they can be done once, in a
+single place, and thus greatly reduce complexity and variability.
+Additionally, this means that:
+
+* You can depend on `coffee-script` as a `devDependency`, and thus
+ your users don't need to have it installed.
+* You don't need to include the minifiers in your package, reducing
+ the size for your users.
+* You don't need to rely on your users having `curl` or `wget` or
+ other system tools on the target machines.
+
## DEFAULT VALUES
npm will default some script values based on package contents.
$ npm install semver
- semver.valid('1.2.3') // true
- semver.valid('a.b.c') // false
+ semver.valid('1.2.3') // '1.2.3'
+ semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
* `<1.2.3` Less than
* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
* `~1.2.3` := `>=1.2.3 <1.3.0`
-* `~1.2` := `>=1.2.0 <2.0.0`
+* `~1.2` := `>=1.2.0 <1.3.0`
* `~1` := `>=1.0.0 <2.0.0`
* `1.2.x` := `>=1.2.0 <1.3.0`
* `1.x` := `>=1.0.0 <2.0.0`
<p>This function should not be used programmatically. Instead, just refer
to the <code>npm.bin</code> member.</p>
</div>
-<p id="footer">bin — npm@1.1.70</p>
+<p id="footer">bin — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This command will launch a browser, so this command may not be the most
friendly for programmatic use.</p>
</div>
-<p id="footer">bugs — npm@1.1.70</p>
+<p id="footer">bugs — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">commands — npm@1.1.70</p>
+<p id="footer">commands — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">config — npm@1.1.70</p>
+<p id="footer">config — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../api/unpublish.html">unpublish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">deprecate — npm@1.1.70</p>
+<p id="footer">deprecate — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This command will launch a browser, so this command may not be the most
friendly for programmatic use.</p>
</div>
-<p id="footer">docs — npm@1.1.70</p>
+<p id="footer">docs — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Since this command opens an editor in a new process, be careful about where
and how this is used.</p>
</div>
-<p id="footer">edit — npm@1.1.70</p>
+<p id="footer">edit — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The first element in the 'args' parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p>
</div>
-<p id="footer">explore — npm@1.1.70</p>
+<p id="footer">explore — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The silent parameter is not neccessary not used, but it may in the future.</p>
</div>
-<p id="footer">help-search — npm@1.1.70</p>
+<p id="footer">help-search — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p><a href="../doc/json.html">json(1)</a></p>
</div>
-<p id="footer">init — npm@1.1.70</p>
+<p id="footer">init — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when all packages have been
installed or when an error has been encountered.</p>
</div>
-<p id="footer">install — npm@1.1.70</p>
+<p id="footer">install — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Now, any changes to the redis package will be reflected in
the package in the current working directory</p>
</div>
-<p id="footer">link — npm@1.1.70</p>
+<p id="footer">link — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>For a list of all the available command-line configs, see <code>npm help config</code></p>
</div>
-<p id="footer">load — npm@1.1.70</p>
+<p id="footer">load — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
This means that if a submodule a same dependency as a parent module, then the
dependency will only be output once.</p>
</div>
-<p id="footer">ls — npm@1.1.70</p>
+<p id="footer">ls — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.70</p>
+<p>1.2.0</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre>
</div>
-<p id="footer">npm — npm@1.1.70</p>
+<p id="footer">npm — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If the 'packages' parameter is left out, npm will check all packages.</p>
</div>
-<p id="footer">outdated — npm@1.1.70</p>
+<p id="footer">outdated — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">owner — npm@1.1.70</p>
+<p id="footer">owner — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If no arguments are supplied, then npm packs the current package folder.</p>
</div>
-<p id="footer">pack — npm@1.1.70</p>
+<p id="footer">pack — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">prefix — npm@1.1.70</p>
+<p id="footer">prefix — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Extraneous packages are packages that are not listed on the parent
package's dependencies list.</p>
</div>
-<p id="footer">prune — npm@1.1.70</p>
+<p id="footer">prune — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../api/owner.html">owner(3)</a></li></ul>
</div>
-<p id="footer">publish — npm@1.1.70</p>
+<p id="footer">publish — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>See <code>npm help build</code></p>
</div>
-<p id="footer">rebuild — npm@1.1.70</p>
+<p id="footer">rebuild — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
</div>
-<p id="footer">restart — npm@1.1.70</p>
+<p id="footer">restart — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically.</p>
</div>
-<p id="footer">root — npm@1.1.70</p>
+<p id="footer">root — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../api/test.html">test(3)</a></li><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/restart.html">restart(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
</div>
-<p id="footer">run-script — npm@1.1.70</p>
+<p id="footer">run-script — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
and doesn't try to read your mind (it doesn't do any verb tense matching or the
like).</p>
</div>
-<p id="footer">search — npm@1.1.70</p>
+<p id="footer">search — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when the shrinkwrap has
been saved.</p>
</div>
-<p id="footer">shrinkwrap — npm@1.1.70</p>
+<p id="footer">shrinkwrap — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">start — npm@1.1.70</p>
+<p id="footer">start — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run stop on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">stop — npm@1.1.70</p>
+<p id="footer">stop — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li>npm help json</li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule — npm@1.1.70</p>
+<p id="footer">submodule — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
used. For more information about how to set this config, check
<code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p>
</div>
-<p id="footer">tag — npm@1.1.70</p>
+<p id="footer">tag — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">test — npm@1.1.70</p>
+<p id="footer">test — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when all packages have been
uninstalled or when an error has been encountered.</p>
</div>
-<p id="footer">uninstall — npm@1.1.70</p>
+<p id="footer">uninstall — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If no version is specified, or if all versions are removed then
the root package entry is removed from the registry entirely.</p>
</div>
-<p id="footer">unpublish — npm@1.1.70</p>
+<p id="footer">unpublish — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.</p>
</div>
-<p id="footer">update — npm@1.1.70</p>
+<p id="footer">update — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
parameter. The difference, however, is this function will fail if it does
not have exactly one element. The only element should be a version number.</p>
</div>
-<p id="footer">version — npm@1.1.70</p>
+<p id="footer">version — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>corresponding to the list of fields selected.</p>
</div>
-<p id="footer">view — npm@1.1.70</p>
+<p id="footer">view — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">whoami — npm@1.1.70</p>
+<p id="footer">whoami — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.70</p>
+<p id="footer"><a href="../doc/README.html">README</a> — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li></ul>
</div>
-<p id="footer">adduser — npm@1.1.70</p>
+<p id="footer">adduser — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">bin — npm@1.1.70</p>
+<p id="footer">bin — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/docs.html">docs(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">bugs — npm@1.1.70</p>
+<p id="footer">bugs — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">build — npm@1.1.70</p>
+<p id="footer">build — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">bundle — npm@1.1.70</p>
+<p id="footer">bundle — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li></ul>
</div>
-<p id="footer">cache — npm@1.1.70</p>
+<p id="footer">cache — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li></ul>
</div>
-<p id="footer">changelog — npm@1.1.70</p>
+<p id="footer">changelog — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">coding-style — npm@1.1.70</p>
+<p id="footer">coding-style — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">completion — npm@1.1.70</p>
+<p id="footer">completion — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">config — npm@1.1.70</p>
+<p id="footer">config — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/ls.html">ls(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">dedupe — npm@1.1.70</p>
+<p id="footer">dedupe — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">deprecate — npm@1.1.70</p>
+<p id="footer">deprecate — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">developers — npm@1.1.70</p>
+<p id="footer">developers — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
</div>
-<p id="footer">disputes — npm@1.1.70</p>
+<p id="footer">disputes — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">docs — npm@1.1.70</p>
+<p id="footer">docs — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/explore.html">explore(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">edit — npm@1.1.70</p>
+<p id="footer">edit — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/submodule.html">submodule(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/edit.html">edit(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">explore — npm@1.1.70</p>
+<p id="footer">explore — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
</div>
-<p id="footer">faq — npm@1.1.70</p>
+<p id="footer">faq — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
</div>
-<p id="footer">folders — npm@1.1.70</p>
+<p id="footer">folders — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li></ul>
</div>
-<p id="footer">help-search — npm@1.1.70</p>
+<p id="footer">help-search — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/help-search.html">help-search(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">help — npm@1.1.70</p>
+<p id="footer">help — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p> Display npm username</p>
</div>
-<p id="footer">index — npm@1.1.70</p>
+<p id="footer">index — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="https://github.com/isaacs/init-package-json">https://github.com/isaacs/init-package-json</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
</div>
-<p id="footer">init — npm@1.1.70</p>
+<p id="footer">init — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></li></ul>
</div>
-<p id="footer">install — npm@1.1.70</p>
+<p id="footer">install — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>For example, the following are equivalent:</p>
-<ul><li><code>"~1.2.3" = ">=1.2.3 <1.3.0"</code></li><li><code>"~1.2" = ">=1.2.0 <2.0.0"</code></li><li><code>"~1" = ">=1.0.0 <2.0.0"</code></li></ul>
+<ul><li><code>"~1.2.3" = ">=1.2.3 <1.3.0"</code></li><li><code>"~1.2" = ">=1.2.0 <1.3.0"</code></li><li><code>"~1" = ">=1.0.0 <1.1.0"</code></li></ul>
<h3 id="X-Version-Ranges">X Version Ranges</h3>
<ul><li><a href="../doc/semver.html">semver(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/version.html">version(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li></ul>
</div>
-<p id="footer">json — npm@1.1.70</p>
+<p id="footer">json — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">link — npm@1.1.70</p>
+<p id="footer">link — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
nested packages will <em>also</em> show the paths to the specified packages.
For example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
-<pre><code>npm@1.1.70 /path/to/npm
+<pre><code>npm@1.2.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5</code></pre>
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/update.html">update(1)</a></li></ul>
</div>
-<p id="footer">ls — npm@1.1.70</p>
+<p id="footer">ls — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.70</p>
+<p>1.2.0</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<ul><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/index.html">index(1)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">npm — npm@1.1.70</p>
+<p id="footer">npm — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
</div>
-<p id="footer">outdated — npm@1.1.70</p>
+<p id="footer">outdated — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
</div>
-<p id="footer">owner — npm@1.1.70</p>
+<p id="footer">owner — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">pack — npm@1.1.70</p>
+<p id="footer">pack — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">prefix — npm@1.1.70</p>
+<p id="footer">prefix — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">prune — npm@1.1.70</p>
+<p id="footer">prune — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li></ul>
</div>
-<p id="footer">publish — npm@1.1.70</p>
+<p id="footer">publish — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">rebuild — npm@1.1.70</p>
+<p id="footer">rebuild — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
</div>
-<p id="footer">registry — npm@1.1.70</p>
+<p id="footer">registry — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/README.html">README</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li></ul>
</div>
-<p id="footer">removing-npm — npm@1.1.70</p>
+<p id="footer">removing-npm — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">restart — npm@1.1.70</p>
+<p id="footer">restart — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">root — npm@1.1.70</p>
+<p id="footer">root — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">run-script — npm@1.1.70</p>
+<p id="footer">run-script — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm supports the "scripts" member of the package.json script, for the
following scripts:</p>
-<ul><li>preinstall:
+<ul><li>prepublish:
+Run BEFORE the package is published. (Also run on local <code>npm
+install</code> without any arguments.)</li><li>publish, postpublish:
+Run AFTER the package is published.</li><li>preinstall:
Run BEFORE the package is installed</li><li>install, postinstall:
Run AFTER the package is installed.</li><li>preuninstall, uninstall:
Run BEFORE the package is uninstalled.</li><li>postuninstall:
Run AFTER the package is uninstalled.</li><li>preupdate:
Run BEFORE the package is updated with the update command.</li><li>update, postupdate:
-Run AFTER the package is updated with the update command.</li><li>prepublish:
-Run BEFORE the package is published.</li><li>publish, postpublish:
-Run AFTER the package is published.</li><li>pretest, test, posttest:
+Run AFTER the package is updated with the update command.</li><li>pretest, test, posttest:
Run by the <code>npm test</code> command.</li><li>prestop, stop, poststop:
Run by the <code>npm stop</code> command.</li><li>prestart, start, poststart:
Run by the <code>npm start</code> command.</li><li>prerestart, restart, postrestart:
<p>Additionally, arbitrary scrips can be run by doing
<code>npm run-script <stage> <pkg></code>.</p>
+<h2 id="NOTE-INSTALL-SCRIPTS-ARE-AN-ANTIPATTERN">NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN</h2>
+
+<p><strong>tl;dr</strong> Don't use <code>install</code>. Use a <code>.gyp</code> file for compilation, and
+<code>prepublish</code> for anything else.</p>
+
+<p>You should almost never have to explicitly set a <code>preinstall</code> or
+<code>install</code> script. If you are doing this, please consider if there is
+another option.</p>
+
+<p>The only valid use of <code>install</code> or <code>preinstall</code> scripts is for
+compilation which must be done on the target architecture. In early
+versions of node, this was often done using the <code>node-waf</code> scripts, or
+a standalone <code>Makefile</code>, and early versions of npm required that it be
+explicitly set in package.json. This was not portable, and harder to
+do properly.</p>
+
+<p>In the current version of node, the standard way to do this is using a
+<code>.gyp</code> file. If you have a file with a <code>.gyp</code> extension in the root
+of your package, then npm will run the appropriate <code>node-gyp</code> commands
+automatically at install time. This is the only officially supported
+method for compiling binary addons, and does not require that you add
+anything to your package.json file.</p>
+
+<p>If you have to do other things before your package is used, in a way
+that is not dependent on the operating system or architecture of the
+target system, then use a <code>prepublish</code> script instead. This includes
+tasks such as:</p>
+
+<ul><li>Compile CoffeeScript source code into JavaScript.</li><li>Create minified versions of JavaScript source code.</li><li>Fetching remote resources that your package will use.</li></ul>
+
+<p>The advantage of doing these things at <code>prepublish</code> time instead of
+<code>preinstall</code> or <code>install</code> time is that they can be done once, in a
+single place, and thus greatly reduce complexity and variability.
+Additionally, this means that:</p>
+
+<ul><li>You can depend on <code>coffee-script</code> as a <code>devDependency</code>, and thus
+your users don't need to have it installed.</li><li>You don't need to include the minifiers in your package, reducing
+the size for your users.</li><li>You don't need to rely on your users having <code>curl</code> or <code>wget</code> or
+other system tools on the target machines.</li></ul>
+
<h2 id="DEFAULT-VALUES">DEFAULT VALUES</h2>
<p>npm will default some script values based on package contents.</p>
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">scripts — npm@1.1.70</p>
+<p id="footer">scripts — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/view.html">view(1)</a></li></ul>
</div>
-<p id="footer">search — npm@1.1.70</p>
+<p id="footer">search — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<pre><code>$ npm install semver
-semver.valid('1.2.3') // true
-semver.valid('a.b.c') // false
+semver.valid('1.2.3') // '1.2.3'
+semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
<p>The following range styles are supported:</p>
-<ul><li><code>>1.2.3</code> Greater than a specific version.</li><li><code><1.2.3</code> Less than</li><li><code>1.2.3 - 2.3.4</code> := <code>>=1.2.3 <=2.3.4</code></li><li><code>~1.2.3</code> := <code>>=1.2.3 <1.3.0</code></li><li><code>~1.2</code> := <code>>=1.2.0 <2.0.0</code></li><li><code>~1</code> := <code>>=1.0.0 <2.0.0</code></li><li><code>1.2.x</code> := <code>>=1.2.0 <1.3.0</code></li><li><code>1.x</code> := <code>>=1.0.0 <2.0.0</code></li></ul>
+<ul><li><code>>1.2.3</code> Greater than a specific version.</li><li><code><1.2.3</code> Less than</li><li><code>1.2.3 - 2.3.4</code> := <code>>=1.2.3 <=2.3.4</code></li><li><code>~1.2.3</code> := <code>>=1.2.3 <1.3.0</code></li><li><code>~1.2</code> := <code>>=1.2.0 <1.3.0</code></li><li><code>~1</code> := <code>>=1.0.0 <2.0.0</code></li><li><code>1.2.x</code> := <code>>=1.2.0 <1.3.0</code></li><li><code>1.x</code> := <code>>=1.0.0 <2.0.0</code></li></ul>
<p>Ranges can be joined with either a space (which implies "and") or a
<code>||</code> (which implies "or").</p>
<ul><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">semver — npm@1.1.70</p>
+<p id="footer">semver — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">shrinkwrap — npm@1.1.70</p>
+<p id="footer">shrinkwrap — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">star — npm@1.1.70</p>
+<p id="footer">star — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">start — npm@1.1.70</p>
+<p id="footer">start — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li></ul>
</div>
-<p id="footer">stop — npm@1.1.70</p>
+<p id="footer">stop — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule — npm@1.1.70</p>
+<p id="footer">submodule — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">tag — npm@1.1.70</p>
+<p id="footer">tag — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">test — npm@1.1.70</p>
+<p id="footer">test — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">uninstall — npm@1.1.70</p>
+<p id="footer">uninstall — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
</div>
-<p id="footer">unpublish — npm@1.1.70</p>
+<p id="footer">unpublish — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">update — npm@1.1.70</p>
+<p id="footer">update — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/semver.html">semver(1)</a></li></ul>
</div>
-<p id="footer">version — npm@1.1.70</p>
+<p id="footer">version — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/search.html">search(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/docs.html">docs(1)</a></li></ul>
</div>
-<p id="footer">view — npm@1.1.70</p>
+<p id="footer">view — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">whoami — npm@1.1.70</p>
+<p id="footer">whoami — npm@1.2.0</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
}
readJson(jsonFile, function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) return addNamed(name, ver, c)
deprCheck(data)
c(er, data)
if (gitEnv_) return gitEnv_
gitEnv_ = {}
for (var k in process.env) {
- if (!~['GIT_PROXY_COMMAND'].indexOf(k) && k.match(/^GIT/)) continue
+ if (!~['GIT_PROXY_COMMAND','GIT_SSH'].indexOf(k) && k.match(/^GIT/)) continue
gitEnv_[k] = process.env[k]
}
return gitEnv_
if (!er) readJson( path.join( npm.cache, name, ver
, "package", "package.json" )
, function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) return fetchit()
return cb(null, data)
})
}
function maybeGithub (p, name, er, cb) {
- var u = "git://github.com/" + p
+ var u = "https://github.com/" + p
, up = url.parse(u)
+ if (up.hash && up.hash[0] === "#")
+ up.hash = up.hash.slice(1)
+
+ var ref = encodeURIComponent(up.hash || "master")
+ up.pathname = path.join(up.pathname, "tarball", ref).replace(/\\/g, "/")
+ u = url.format(up)
log.info("maybeGithub", "Attempting to fetch %s from %s", p, u)
- return addRemoteGit(u, up, name, function (er2, data) {
+ return addRemoteTarball(u, null, name, function (er2, data) {
if (er2) return cb(er)
return cb(null, data)
})
})
readJson(path.resolve(dir, "package.json"), function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) return cb() // not a package, probably.
counter[data.name] = counter[data.name] || 0
counter[data.name]++
function deprecate (args, cb) {
var pkg = args[0]
, msg = args[1]
- if (msg === undefined) return cb(new Error(deprecate.usage))
+ if (msg === undefined) return cb("Usage: " + deprecate.usage)
// fetch the data and make sure it exists.
pkg = pkg.split(/@/)
var name = pkg.shift()
module.exports = install
-install.usage = "npm install <tarball file>"
- + "\nnpm install <tarball url>"
- + "\nnpm install <folder>"
+install.usage = "npm install"
+ "\nnpm install <pkg>"
+ "\nnpm install <pkg>@<tag>"
+ "\nnpm install <pkg>@<version>"
+ "\nnpm install <pkg>@<version range>"
+ + "\nnpm install <folder>"
+ + "\nnpm install <tarball file>"
+ + "\nnpm install <tarball url>"
+ + "\nnpm install <git:// url>"
+ + "\nnpm install <github username>/<github project>"
+ "\n\nCan specify one or more: npm install ./foo.tgz bar@stable /some/folder"
+ "\nIf no argument is supplied and ./npm-shrinkwrap.json is "
+ "\npresent, installs dependencies specified in the shrinkwrap."
, parsed = url.parse(target.replace(/^git\+/, "git"))
target = dep + "@" + target
return target
- }), where, context, cb)
+ }), where, context, function(er, results) {
+ if (er) return cb(er, results)
+ lifecycle(data, "prepublish", where, function(er) {
+ return cb(er, results)
+ })
+ })
})
}
// initial "family" is the name:version of the root, if it's got
// a package.json file.
readJson(path.resolve(where, "package.json"), function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) data = null
var context = { family: {}
, ancestors: {}
} catch (ex) {
er = ex
}
+
if (er) {
return cb(null, installed, tree, pretty)
-
}
var deps = npm.config.get("save-optional") ? "optionalDependencies"
return path.resolve(nm, p, "package.json")
}), function (jsonfile, cb) {
readJson(jsonfile, function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) return cb(null, [])
return cb(null, [[data.name, data.version]])
})
}, function (er, packages) {
+ // if there's nothing in node_modules, then don't freak out.
+ if (er) packages = []
// add all the existing packages to the family list.
// however, do not add to the ancestors list.
packages.forEach(function (p) {
if (er) return alreadyInstalledManually = []
asyncMap(inst, function (pkg, cb) {
readJson(path.resolve(nm, pkg, "package.json"), function (er, d) {
+ if (er && er.code !== "ENOENT") return cb(er)
// error means it's not a package, most likely.
if (er) return cb(null, [])
, parent = context.parent
readJson(jsonFile, function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er || data._id === target._id) {
if (er) {
install( path.resolve(npm.globalDir, "..")
// before continuing to installing dependencies, check for a shrinkwrap.
var opt = { dev: npm.config.get("dev") }
readDependencies(context, targetFolder, opt, function (er, data, wrap) {
- var deps = Object.keys(data.dependencies || {})
-
- // don't install bundleDependencies, unless they're missing.
- if (data.bundleDependencies) {
- deps = deps.filter(function (d) {
- return data.bundleDependencies.indexOf(d) === -1 ||
- bundled.indexOf(d) === -1
- })
- }
-
- var newcontext = { family: family
+ var deps = prepareForInstallMany(data, "dependencies", bundled, wrap,
+ family)
+ var depsTargetFolder = targetFolder
+ var depsContext = { family: family
, ancestors: context.ancestors
, parent: target
, explicit: false
, wrap: wrap }
- installMany(deps.filter(function (d) {
- // prefer to not install things that are satisfied by
- // something in the "family" list, unless we're installing
- // from a shrinkwrap.
- return wrap || !semver.satisfies(family[d], data.dependencies[d])
- }).map(function (d) {
- var t = data.dependencies[d]
- , parsed = url.parse(t.replace(/^git\+/, "git"))
- t = d + "@" + t
- return t
- }), targetFolder, newcontext, function (er, d) {
- log.verbose("about to build", targetFolder)
- if (er) return cb(er)
- npm.commands.build( [targetFolder]
- , npm.config.get("global")
- , true
- , function (er) { return cb(er, d) })
- })
+
+ var peerDeps = prepareForInstallMany(data, "peerDependencies", bundled,
+ wrap, family)
+ var pdTargetFolder = path.resolve(targetFolder, "..", "..")
+ var pdContext = context
+
+ var actions =
+ [ [ installManyAndBuild, deps, depsTargetFolder, depsContext ] ]
+
+ if (peerDeps.length > 0) {
+ actions.push(
+ [ installManyAndBuild, peerDeps, pdTargetFolder, pdContext ]
+ )
+ }
+
+ chain(actions, cb)
})
})
}
+
+function installManyAndBuild (deps, targetFolder, context, cb) {
+ installMany(deps, targetFolder, context, function (er, d) {
+ log.verbose("about to build", targetFolder)
+ if (er) return cb(er)
+ npm.commands.build( [targetFolder]
+ , npm.config.get("global")
+ , true
+ , function (er) { return cb(er, d) })
+ })
+}
+
+function prepareForInstallMany (packageData, depsKey, bundled, wrap, family) {
+ var deps = Object.keys(packageData[depsKey] || {})
+
+ // don't install bundleDependencies, unless they're missing.
+ if (packageData.bundleDependencies) {
+ deps = deps.filter(function (d) {
+ return packageData.bundleDependencies.indexOf(d) === -1 ||
+ bundled.indexOf(d) === -1
+ })
+ }
+
+ return deps.filter(function (d) {
+ // prefer to not install things that are satisfied by
+ // something in the "family" list, unless we're installing
+ // from a shrinkwrap.
+ return wrap || !semver.satisfies(family[d], packageData[depsKey][d])
+ }).map(function (d) {
+ var t = packageData[depsKey][d]
+ , parsed = url.parse(t.replace(/^git\+/, "git"))
+ t = d + "@" + t
+ return t
+ })
+}
})
}
-// only include
+// only include
function filter (data, args) {
}
+ " " + (data.path || "") )
}
+ if (data.peerInvalid) {
+ lite.peerInvalid = true
+ lite.problems = lite.problems || []
+ lite.problems.push( "peer invalid: "
+ + data.name + "@" + data.version
+ + " " + (data.path || "") )
+ }
+
if (data.dependencies) {
var deps = Object.keys(data.dependencies)
if (deps.length) lite.dependencies = deps.map(function (d) {
+ (color ? "\033[0m" : "")
}
+ if (data.peerInvalid) {
+ out.label += " " + (color ? "\033[31;40m" : "")
+ + "peer invalid"
+ + (color ? "\033[0m" : "")
+ }
+
if (data.extraneous && data.path !== dir) {
out.label += " " + (color ? "\033[32;40m" : "")
+ "extraneous"
+ ":" + (data.realPath !== data.path ? data.realPath : "")
+ (data.extraneous ? ":EXTRANEOUS" : "")
+ (data.invalid ? ":INVALID" : "")
+ + (data.peerInvalid ? ":PEERINVALID" : "")
}
var deps = null
readJson(path.resolve(dir, "package.json"), function (er, d) {
+ if (er && er.code !== "ENOENT") return cb(er)
deps = (er) ? true : (d.dependencies || {})
return next()
})
asyncMap(pkgs, function (pkg, cb) {
var jsonFile = path.resolve(dir, "node_modules", pkg, "package.json")
readJson(jsonFile, function (er, d) {
+ if (er && er.code !== "ENOENT") return cb(er)
cb(null, er ? [] : [[d.name, d.version]])
})
}, function (er, pvs) {
var arg = args[0]
// if it's a local folder, then run the prepublish there, first.
readJson(path.resolve(arg, "package.json"), function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
// error is ok. could be publishing a url or tarball
// however, that means that we will not have automatically run
// the prepublish script, since that gets run when adding a folder
// or a package, in which case, complete against its scripts
var json = path.join(npm.prefix, "package.json")
return readJson(json, function (er, d) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) d = {}
var scripts = Object.keys(d.scripts || {})
console.error("local scripts", scripts)
var pkgDir = path.resolve( pref, "node_modules"
, argv[2], "package.json" )
readJson(pkgDir, function (er, d) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) d = {}
var scripts = Object.keys(d.scripts || {})
return cb(null, scripts)
if (npm.config.get("global")) scripts = [], next()
else readJson(path.join(npm.prefix, "package.json"), function (er, d) {
+ if (er && er.code !== "ENOENT") return cb(er)
d = d || {}
scripts = Object.keys(d.scripts || {})
next()
// remove this package from the global space, if it's installed there
if (npm.config.get("global")) return cb(uninstall.usage)
readJson(path.resolve(npm.prefix, "package.json"), function (er, pkg) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) return cb(uninstall.usage)
uninstall_( [pkg.name]
, npm.dir
// read the package name and version out of that.
var cwdJson = path.join(process.cwd(), "package.json")
return readJson(cwdJson, function (er, data) {
+ if (er && er.code !== "ENOENT") return cb(er)
if (er) return cb("Usage:\n"+unpublish.usage)
gotProject(data.name, data.version, cb)
})
var env = makeEnv(pkg)
env.npm_lifecycle_event = stage
env.npm_node_execpath = env.NODE = env.NODE || process.execPath
+ env.npm_execpath = require.main.filename
// "nobody" typically doesn't have permission to write to /tmp
// even if it's never used, sh freaks out.
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM" "1" "December 2012" "" ""
+.TH "NPM" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm\fR \-\- node package manager
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-ADDUSER" "1" "December 2012" "" ""
+.TH "NPM\-ADDUSER" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-adduser\fR \-\- Add a registry user account
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-BIN" "1" "December 2012" "" ""
+.TH "NPM\-BIN" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-bin\fR \-\- Display npm bin folder
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-BUGS" "1" "December 2012" "" ""
+.TH "NPM\-BUGS" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-bugs\fR \-\- Bugs for a package in a web browser maybe
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-BUILD" "1" "December 2012" "" ""
+.TH "NPM\-BUILD" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-build\fR \-\- Build a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-BUNDLE" "1" "December 2012" "" ""
+.TH "NPM\-BUNDLE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-bundle\fR \-\- REMOVED
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-CACHE" "1" "December 2012" "" ""
+.TH "NPM\-CACHE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-cache\fR \-\- Manipulates packages cache
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-CHANGELOG" "1" "December 2012" "" ""
+.TH "NPM\-CHANGELOG" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-changelog\fR \-\- Changes
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-CODING\-STYLE" "1" "December 2012" "" ""
+.TH "NPM\-CODING\-STYLE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-coding-style\fR \-\- npm\'s "funny" coding style
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-COMPLETION" "1" "December 2012" "" ""
+.TH "NPM\-COMPLETION" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-completion\fR \-\- Tab Completion for npm
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-CONFIG" "1" "December 2012" "" ""
+.TH "NPM\-CONFIG" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-config\fR \-\- Manage the npm configuration file
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DEDUPE" "1" "December 2012" "" ""
+.TH "NPM\-DEDUPE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-dedupe\fR \-\- Reduce duplication
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DEPRECATE" "1" "December 2012" "" ""
+.TH "NPM\-DEPRECATE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-deprecate\fR \-\- Deprecate a version of a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DEVELOPERS" "1" "December 2012" "" ""
+.TH "NPM\-DEVELOPERS" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-developers\fR \-\- Developer Guide
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DISPUTES" "1" "December 2012" "" ""
+.TH "NPM\-DISPUTES" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-disputes\fR \-\- Handling Module Name Disputes
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DOCS" "1" "December 2012" "" ""
+.TH "NPM\-DOCS" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-docs\fR \-\- Docs for a package in a web browser maybe
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-EDIT" "1" "December 2012" "" ""
+.TH "NPM\-EDIT" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-edit\fR \-\- Edit an installed package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-EXPLORE" "1" "December 2012" "" ""
+.TH "NPM\-EXPLORE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-explore\fR \-\- Browse an installed package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-FAQ" "1" "December 2012" "" ""
+.TH "NPM\-FAQ" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-faq\fR \-\- Frequently Asked Questions
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-FOLDERS" "1" "December 2012" "" ""
+.TH "NPM\-FOLDERS" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-folders\fR \-\- Folder Structures Used by npm
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-HELP\-SEARCH" "1" "December 2012" "" ""
+.TH "NPM\-HELP\-SEARCH" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-help-search\fR \-\- Search npm help documentation
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-HELP" "1" "December 2012" "" ""
+.TH "NPM\-HELP" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-help\fR \-\- Get help on npm
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-INDEX" "1" "December 2012" "" ""
+.TH "NPM\-INDEX" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-index\fR \-\- Index of all npm documentation
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-INIT" "1" "December 2012" "" ""
+.TH "NPM\-INIT" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-init\fR \-\- Interactively create a package\.json file
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-INSTALL" "1" "December 2012" "" ""
+.TH "NPM\-INSTALL" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-install\fR \-\- Install a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-JSON" "1" "December 2012" "" ""
+.TH "NPM\-JSON" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-json\fR \-\- Specifics of npm\'s package\.json handling
\fB"~1\.2\.3" = ">=1\.2\.3 <1\.3\.0"\fR
.
.IP "\(bu" 4
-\fB"~1\.2" = ">=1\.2\.0 <2\.0\.0"\fR
+\fB"~1\.2" = ">=1\.2\.0 <1\.3\.0"\fR
.
.IP "\(bu" 4
-\fB"~1" = ">=1\.0\.0 <2\.0\.0"\fR
+\fB"~1" = ">=1\.0\.0 <1\.1\.0"\fR
.
.IP "" 0
.
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-LINK" "1" "December 2012" "" ""
+.TH "NPM\-LINK" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-link\fR \-\- Symlink a package folder
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-LS" "1" "December 2012" "" ""
+.TH "NPM\-LS" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-ls\fR \-\- List installed packages
.IP "" 4
.
.nf
-npm@1.1.70 /path/to/npm
+npm@1.2.0 /path/to/npm
└─┬ init\-package\-json@0\.0\.4
└── promzard@0\.1\.5
.
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM" "1" "December 2012" "" ""
+.TH "NPM" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm\fR \-\- node package manager
.fi
.
.SH "VERSION"
-1.1.70
+1.2.0
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-OUTDATED" "1" "December 2012" "" ""
+.TH "NPM\-OUTDATED" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-outdated\fR \-\- Check for outdated packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-OWNER" "1" "December 2012" "" ""
+.TH "NPM\-OWNER" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-owner\fR \-\- Manage package owners
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PACK" "1" "December 2012" "" ""
+.TH "NPM\-PACK" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-pack\fR \-\- Create a tarball from a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PREFIX" "1" "December 2012" "" ""
+.TH "NPM\-PREFIX" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-prefix\fR \-\- Display prefix
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PRUNE" "1" "December 2012" "" ""
+.TH "NPM\-PRUNE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-prune\fR \-\- Remove extraneous packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PUBLISH" "1" "December 2012" "" ""
+.TH "NPM\-PUBLISH" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-publish\fR \-\- Publish a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-REBUILD" "1" "December 2012" "" ""
+.TH "NPM\-REBUILD" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-rebuild\fR \-\- Rebuild a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-REGISTRY" "1" "December 2012" "" ""
+.TH "NPM\-REGISTRY" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-registry\fR \-\- The JavaScript Package Registry
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-REMOVAL" "1" "December 2012" "" ""
+.TH "NPM\-REMOVAL" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-removal\fR \-\- Cleaning the Slate
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-RESTART" "1" "December 2012" "" ""
+.TH "NPM\-RESTART" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-restart\fR \-\- Start a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-ROOT" "1" "December 2012" "" ""
+.TH "NPM\-ROOT" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-root\fR \-\- Display npm root
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-RUN\-SCRIPT" "1" "December 2012" "" ""
+.TH "NPM\-RUN\-SCRIPT" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-run-script\fR \-\- Run arbitrary package scripts
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SCRIPTS" "1" "December 2012" "" ""
+.TH "NPM\-SCRIPTS" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-scripts\fR \-\- How npm handles the "scripts" field
following scripts:
.
.IP "\(bu" 4
+prepublish:
+Run BEFORE the package is published\. (Also run on local \fBnpm
+install\fR without any arguments\.)
+.
+.IP "\(bu" 4
+publish, postpublish:
+Run AFTER the package is published\.
+.
+.IP "\(bu" 4
preinstall:
Run BEFORE the package is installed
.
Run AFTER the package is updated with the update command\.
.
.IP "\(bu" 4
-prepublish:
-Run BEFORE the package is published\.
-.
-.IP "\(bu" 4
-publish, postpublish:
-Run AFTER the package is published\.
-.
-.IP "\(bu" 4
pretest, test, posttest:
Run by the \fBnpm test\fR command\.
.
.P
Additionally, arbitrary scrips can be run by doing \fBnpm run\-script <stage> <pkg>\fR\|\.
.
+.SH "NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN"
+\fBtl;dr\fR Don\'t use \fBinstall\fR\|\. Use a \fB\|\.gyp\fR file for compilation, and \fBprepublish\fR for anything else\.
+.
+.P
+You should almost never have to explicitly set a \fBpreinstall\fR or \fBinstall\fR script\. If you are doing this, please consider if there is
+another option\.
+.
+.P
+The only valid use of \fBinstall\fR or \fBpreinstall\fR scripts is for
+compilation which must be done on the target architecture\. In early
+versions of node, this was often done using the \fBnode\-waf\fR scripts, or
+a standalone \fBMakefile\fR, and early versions of npm required that it be
+explicitly set in package\.json\. This was not portable, and harder to
+do properly\.
+.
+.P
+In the current version of node, the standard way to do this is using a \fB\|\.gyp\fR file\. If you have a file with a \fB\|\.gyp\fR extension in the root
+of your package, then npm will run the appropriate \fBnode\-gyp\fR commands
+automatically at install time\. This is the only officially supported
+method for compiling binary addons, and does not require that you add
+anything to your package\.json file\.
+.
+.P
+If you have to do other things before your package is used, in a way
+that is not dependent on the operating system or architecture of the
+target system, then use a \fBprepublish\fR script instead\. This includes
+tasks such as:
+.
+.IP "\(bu" 4
+Compile CoffeeScript source code into JavaScript\.
+.
+.IP "\(bu" 4
+Create minified versions of JavaScript source code\.
+.
+.IP "\(bu" 4
+Fetching remote resources that your package will use\.
+.
+.IP "" 0
+.
+.P
+The advantage of doing these things at \fBprepublish\fR time instead of \fBpreinstall\fR or \fBinstall\fR time is that they can be done once, in a
+single place, and thus greatly reduce complexity and variability\.
+Additionally, this means that:
+.
+.IP "\(bu" 4
+You can depend on \fBcoffee\-script\fR as a \fBdevDependency\fR, and thus
+your users don\'t need to have it installed\.
+.
+.IP "\(bu" 4
+You don\'t need to include the minifiers in your package, reducing
+the size for your users\.
+.
+.IP "\(bu" 4
+You don\'t need to rely on your users having \fBcurl\fR or \fBwget\fR or
+other system tools on the target machines\.
+.
+.IP "" 0
+.
.SH "DEFAULT VALUES"
npm will default some script values based on package contents\.
.
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SEARCH" "1" "December 2012" "" ""
+.TH "NPM\-SEARCH" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-search\fR \-\- Search for packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SEMVER" "1" "December 2012" "" ""
+.TH "NPM\-SEMVER" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-semver\fR \-\- The semantic versioner for npm
.
.nf
$ npm install semver
-semver\.valid(\'1\.2\.3\') // true
-semver\.valid(\'a\.b\.c\') // false
+semver\.valid(\'1\.2\.3\') // \'1\.2\.3\'
+semver\.valid(\'a\.b\.c\') // null
semver\.clean(\' =v1\.2\.3 \') // \'1\.2\.3\'
semver\.satisfies(\'1\.2\.3\', \'1\.x || >=2\.5\.0 || 5\.0\.0 \- 7\.2\.3\') // true
semver\.gt(\'1\.2\.3\', \'9\.8\.7\') // false
\fB~1\.2\.3\fR := \fB>=1\.2\.3 <1\.3\.0\fR
.
.IP "\(bu" 4
-\fB~1\.2\fR := \fB>=1\.2\.0 <2\.0\.0\fR
+\fB~1\.2\fR := \fB>=1\.2\.0 <1\.3\.0\fR
.
.IP "\(bu" 4
\fB~1\fR := \fB>=1\.0\.0 <2\.0\.0\fR
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SHRINKWRAP" "1" "December 2012" "" ""
+.TH "NPM\-SHRINKWRAP" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-shrinkwrap\fR \-\- Lock down dependency versions
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-STAR" "1" "December 2012" "" ""
+.TH "NPM\-STAR" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-star\fR \-\- Mark your favorite packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-START" "1" "December 2012" "" ""
+.TH "NPM\-START" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-start\fR \-\- Start a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-STOP" "1" "December 2012" "" ""
+.TH "NPM\-STOP" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-stop\fR \-\- Stop a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SUBMODULE" "1" "December 2012" "" ""
+.TH "NPM\-SUBMODULE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-submodule\fR \-\- Add a package as a git submodule
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-TAG" "1" "December 2012" "" ""
+.TH "NPM\-TAG" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-tag\fR \-\- Tag a published version
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-TEST" "1" "December 2012" "" ""
+.TH "NPM\-TEST" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-test\fR \-\- Test a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-RM" "1" "December 2012" "" ""
+.TH "NPM\-RM" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-rm\fR \-\- Remove a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-UNPUBLISH" "1" "December 2012" "" ""
+.TH "NPM\-UNPUBLISH" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-unpublish\fR \-\- Remove a package from the registry
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-UPDATE" "1" "December 2012" "" ""
+.TH "NPM\-UPDATE" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-update\fR \-\- Update a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-VERSION" "1" "December 2012" "" ""
+.TH "NPM\-VERSION" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-version\fR \-\- Bump a package version
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-VIEW" "1" "December 2012" "" ""
+.TH "NPM\-VIEW" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-view\fR \-\- View registry info
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-WHOAMI" "1" "December 2012" "" ""
+.TH "NPM\-WHOAMI" "1" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-whoami\fR \-\- Display npm username
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-BIN" "3" "December 2012" "" ""
+.TH "NPM\-BIN" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-bin\fR \-\- Display npm bin folder
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-BUGS" "3" "December 2012" "" ""
+.TH "NPM\-BUGS" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-bugs\fR \-\- Bugs for a package in a web browser maybe
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-COMMANDS" "3" "December 2012" "" ""
+.TH "NPM\-COMMANDS" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-commands\fR \-\- npm commands
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-CONFIG" "3" "December 2012" "" ""
+.TH "NPM\-CONFIG" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-config\fR \-\- Manage the npm configuration files
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DEPRECATE" "3" "December 2012" "" ""
+.TH "NPM\-DEPRECATE" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-deprecate\fR \-\- Deprecate a version of a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-DOCS" "3" "December 2012" "" ""
+.TH "NPM\-DOCS" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-docs\fR \-\- Docs for a package in a web browser maybe
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-EDIT" "3" "December 2012" "" ""
+.TH "NPM\-EDIT" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-edit\fR \-\- Edit an installed package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-EXPLORE" "3" "December 2012" "" ""
+.TH "NPM\-EXPLORE" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-explore\fR \-\- Browse an installed package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-HELP\-SEARCH" "3" "December 2012" "" ""
+.TH "NPM\-HELP\-SEARCH" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-help-search\fR \-\- Search the help pages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "INIT" "3" "December 2012" "" ""
+.TH "INIT" "3" "January 2013" "" ""
.
.SH "NAME"
\fBinit\fR \-\- Interactively create a package\.json file
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-INSTALL" "3" "December 2012" "" ""
+.TH "NPM\-INSTALL" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-install\fR \-\- install a package programmatically
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-LINK" "3" "December 2012" "" ""
+.TH "NPM\-LINK" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-link\fR \-\- Symlink a package folder
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-LOAD" "3" "December 2012" "" ""
+.TH "NPM\-LOAD" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-load\fR \-\- Load config settings
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-LS" "3" "December 2012" "" ""
+.TH "NPM\-LS" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-ls\fR \-\- List installed packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM" "3" "December 2012" "" ""
+.TH "NPM" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm\fR \-\- node package manager
.fi
.
.SH "VERSION"
-1.1.70
+1.2.0
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-OUTDATED" "3" "December 2012" "" ""
+.TH "NPM\-OUTDATED" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-outdated\fR \-\- Check for outdated packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-OWNER" "3" "December 2012" "" ""
+.TH "NPM\-OWNER" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-owner\fR \-\- Manage package owners
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PACK" "3" "December 2012" "" ""
+.TH "NPM\-PACK" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-pack\fR \-\- Create a tarball from a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PREFIX" "3" "December 2012" "" ""
+.TH "NPM\-PREFIX" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-prefix\fR \-\- Display prefix
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PRUNE" "3" "December 2012" "" ""
+.TH "NPM\-PRUNE" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-prune\fR \-\- Remove extraneous packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-PUBLISH" "3" "December 2012" "" ""
+.TH "NPM\-PUBLISH" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-publish\fR \-\- Publish a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-REBUILD" "3" "December 2012" "" ""
+.TH "NPM\-REBUILD" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-rebuild\fR \-\- Rebuild a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-RESTART" "3" "December 2012" "" ""
+.TH "NPM\-RESTART" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-restart\fR \-\- Start a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-ROOT" "3" "December 2012" "" ""
+.TH "NPM\-ROOT" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-root\fR \-\- Display npm root
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-RUN\-SCRIPT" "3" "December 2012" "" ""
+.TH "NPM\-RUN\-SCRIPT" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-run-script\fR \-\- Run arbitrary package scripts
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SEARCH" "3" "December 2012" "" ""
+.TH "NPM\-SEARCH" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-search\fR \-\- Search for packages
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SHRINKWRAP" "3" "December 2012" "" ""
+.TH "NPM\-SHRINKWRAP" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-shrinkwrap\fR \-\- programmatically generate package shrinkwrap file
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-START" "3" "December 2012" "" ""
+.TH "NPM\-START" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-start\fR \-\- Start a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-STOP" "3" "December 2012" "" ""
+.TH "NPM\-STOP" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-stop\fR \-\- Stop a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-SUBMODULE" "3" "December 2012" "" ""
+.TH "NPM\-SUBMODULE" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-submodule\fR \-\- Add a package as a git submodule
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-TAG" "3" "December 2012" "" ""
+.TH "NPM\-TAG" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-tag\fR \-\- Tag a published version
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-TEST" "3" "December 2012" "" ""
+.TH "NPM\-TEST" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-test\fR \-\- Test a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-UNINSTALL" "3" "December 2012" "" ""
+.TH "NPM\-UNINSTALL" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-uninstall\fR \-\- uninstall a package programmatically
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-UNPUBLISH" "3" "December 2012" "" ""
+.TH "NPM\-UNPUBLISH" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-unpublish\fR \-\- Remove a package from the registry
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-UPDATE" "3" "December 2012" "" ""
+.TH "NPM\-UPDATE" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-update\fR \-\- Update a package
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-VERSION" "3" "December 2012" "" ""
+.TH "NPM\-VERSION" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-version\fR \-\- Bump a package version
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-VIEW" "3" "December 2012" "" ""
+.TH "NPM\-VIEW" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-view\fR \-\- View registry info
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
-.TH "NPM\-WHOAMI" "3" "December 2012" "" ""
+.TH "NPM\-WHOAMI" "3" "January 2013" "" ""
.
.SH "NAME"
\fBnpm-whoami\fR \-\- Display npm username
me._stream = fs.createWriteStream(me._path, so)
me._stream.on("open", function (fd) {
+ // console.error("FW open", me._buffer, me._path)
me.ready = true
me._buffer.forEach(function (c) {
if (c === EOF) me._stream.end()
else me._stream.write(c)
})
me.emit("ready")
+ // give this a kick just in case it needs it.
+ me.emit("drain")
})
me._stream.on("drain", function () { me.emit("drain") })
me._bytesWritten += c.length
if (!me.ready) {
+ if (!Buffer.isBuffer(c) && typeof c !== 'string')
+ throw new Error('invalid write data')
me._buffer.push(c)
return false
}
var calls = me._buffer
calls.forEach(function (c) {
// console.error("~~ ~~ proxy buffered call", c[0], c[1])
- proxy[c[0]].call(proxy, c[1])
+ proxy[c[0]].apply(proxy, c[1])
})
me._buffer.length = 0
if (me._needsDrain) me.emit("drain")
ProxyWriter.prototype.end = function (c) {
// console.error("~~ proxy end")
if (!this._proxy) {
- this._buffer.push(["end", c])
+ this._buffer.push(["end", [c]])
return false
}
return this._proxy.end(c)
},
"name": "fstream",
"description": "Advanced file system stream things",
- "version": "0.1.20",
+ "version": "0.1.21",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/fstream.git"
"license": "BSD",
"readme": "Like FS streams, but with stat on them, and supporting directories and\nsymbolic links, as well as normal files. Also, you can use this to set\nthe stats on a file, even if you don't change its contents, or to create\na symlink, etc.\n\nSo, for example, you can \"write\" a directory, and it'll call `mkdir`. You\ncan specify a uid and gid, and it'll call `chown`. You can specify a\n`mtime` and `atime`, and it'll call `utimes`. You can call it a symlink\nand provide a `linkpath` and it'll call `symlink`.\n\nNote that it won't automatically resolve symbolic links. So, if you\ncall `fstream.Reader('/some/symlink')` then you'll get an object\nthat stats and then ends immediately (since it has no data). To follow\nsymbolic links, do this: `fstream.Reader({path:'/some/symlink', follow:\ntrue })`.\n\nThere are various checks to make sure that the bytes emitted are the\nsame as the intended size, if the size is set.\n\n## Examples\n\n```javascript\nfstream\n .Writer({ path: \"path/to/file\"\n , mode: 0755\n , size: 6\n })\n .write(\"hello\\n\")\n .end()\n```\n\nThis will create the directories if they're missing, and then write\n`hello\\n` into the file, chmod it to 0755, and assert that 6 bytes have\nbeen written when it's done.\n\n```javascript\nfstream\n .Writer({ path: \"path/to/file\"\n , mode: 0755\n , size: 6\n , flags: \"a\"\n })\n .write(\"hello\\n\")\n .end()\n```\n\nYou can pass flags in, if you want to append to a file.\n\n```javascript\nfstream\n .Writer({ path: \"path/to/symlink\"\n , linkpath: \"./file\"\n , SymbolicLink: true\n , mode: \"0755\" // octal strings supported\n })\n .end()\n```\n\nIf isSymbolicLink is a function, it'll be called, and if it returns\ntrue, then it'll treat it as a symlink. If it's not a function, then\nany truish value will make a symlink, or you can set `type:\n'SymbolicLink'`, which does the same thing.\n\nNote that the linkpath is relative to the symbolic link location, not\nthe parent dir or cwd.\n\n```javascript\nfstream\n .Reader(\"path/to/dir\")\n .pipe(fstream.Writer(\"path/to/other/dir\"))\n```\n\nThis will do like `cp -Rp path/to/dir path/to/other/dir`. If the other\ndir exists and isn't a directory, then it'll emit an error. It'll also\nset the uid, gid, mode, etc. to be identical. In this way, it's more\nlike `rsync -a` than simply a copy.\n",
"readmeFilename": "README.md",
- "_id": "fstream@0.1.20",
- "_from": "fstream@~0.1.17"
+ "_id": "fstream@0.1.21",
+ "_from": "fstream@latest"
}
, log = require('npmlog')
, which = require('which')
, mkdirp = require('mkdirp')
+ , exec = require('child_process').exec
, win = process.platform == 'win32'
exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
if (err) {
if (win && /not found/.test(err.message)) {
// On windows and no 'msbuild' found. Let's guess where it is
- guessMsbuild()
+ findMsbuild()
} else {
// Some other error or 'make' not found on Unix, report that to the user
callback(err)
}
/**
- * Guess the location of the "msbuild.exe" file on Windows.
+ * Search for the location of "msbuild.exe" file on Windows.
*/
- function guessMsbuild () {
+ function findMsbuild () {
log.verbose('could not find "msbuild.exe". guessing location')
- // This is basically just hard-coded. If this causes problems
- // then we'll think of something more clever.
- var windir = process.env.WINDIR || process.env.SYSTEMROOT || 'C:\\WINDOWS'
- , frameworkDir = path.resolve(windir, 'Microsoft.NET', 'Framework')
- , versionDir = path.resolve(frameworkDir, 'v4.0.30319') // This is probably the most brittle part...
- , msbuild = path.resolve(versionDir, 'msbuild.exe')
- fs.stat(msbuild, function (err, stat) {
+ var notfoundErr = new Error('Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?')
+ exec('reg query HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions /s /f MSBuildToolsPath /e /t REG_SZ', function (err, stdout, stderr) {
+ var reVers = /Software\\Microsoft\\MSBuild\\ToolsVersions\\([^\r]+)\r\n\s+MSBuildToolsPath\s+REG_SZ\s+([^\r]+)/gi
+ , msbuilds = []
+ , r
+ , msbuildPath
if (err) {
- if (err.code == 'ENOENT') {
- callback(new Error('Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2010 installed?'))
- } else {
- callback(err)
+ return callback(notfoundErr)
+ }
+ while (r = reVers.exec(stdout)) {
+ if (parseFloat(r[1], 10) >= 3.5) {
+ msbuilds.push({
+ version: parseFloat(r[1], 10),
+ path: r[2]
+ })
}
- return
}
- command = msbuild
- copyNodeLib()
+ msbuilds.sort(function (x, y) {
+ return (x.version < y.version ? -1 : 1)
+ })
+ ;(function verifyMsbuild () {
+ msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe')
+ fs.stat(msbuildPath, function (err, stat) {
+ if (err) {
+ if (err.code == 'ENOENT') {
+ if (msbuilds.length) {
+ return verifyMsbuild()
+ } else {
+ callback(notfoundErr)
+ }
+ } else {
+ callback(err)
+ }
+ return
+ }
+ command = msbuildPath
+ copyNodeLib()
+ })
+ })()
})
}
}
function checkPythonVersion () {
- execFile(python, ['-c', 'import platform; print platform.python_version();'], function (err, stdout) {
+ execFile(python, ['-c', 'import platform; print(platform.python_version());'], function (err, stdout) {
if (err) {
return callback(err)
}
- log.verbose('check python version', '`%s -c "import platform; print platform.python_version();"` returned: %j', python, stdout)
+ log.verbose('check python version', '`%s -c "import platform; print(platform.python_version());"` returned: %j', python, stdout)
var version = stdout.trim()
if (~version.indexOf('+')) {
log.silly('stripping "+" sign(s) from version')
}
// 0.x.y-pre versions are not published yet and cannot be installed. Bail.
- if (version[5] === '-pre') {
+ if (version[5] && version[5].match(/\-pre$/)) {
log.verbose('detected "pre" node version', versionStr)
if (gyp.opts.nodedir) {
log.verbose('--nodedir flag was passed; skipping install', gyp.opts.nodedir)
"bindings",
"gyp"
],
- "version": "0.8.1",
+ "version": "0.8.2",
"installVersion": 9,
"author": {
"name": "Nathan Rajlich",
},
"readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n * On Unix:\n * `python`\n * `make`\n * A proper C/C++ compiler toolchain, like GCC\n * On Windows:\n * [Python][windows-python] ([`v2.7.3`][windows-python-v2.7.3] recommended, `v3.x.x` is __*not*__ supported)\n * Windows XP/Vista/7:\n * Microsoft Visual Studio C++ 2010 ([Express][msvc2010] version works well)\n * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]\n * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]\n * Windows 8:\n * Microsoft Visual Studio C++ 2012 for Windows Desktop ([Express][msvc2012] version works well)\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n \"targets\": [\n {\n \"target_name\": \"binding\",\n \"sources\": [ \"src/binding.cc\" ]\n }\n ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * [*\"binding.gyp\" files out in the wild* wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n| **Command** | **Description**\n|:--------------|:---------------------------------------------------------------\n| `build` | Invokes `make`/`msbuild.exe` and builds the native addon\n| `clean` | Removes any the `build` dir if it exists\n| `configure` | Generates project build files for the current platform\n| `rebuild` | Runs \"clean\", \"configure\" and \"build\" all in a row\n| `install` | Installs node development header files for the given version\n| `list` | Lists the currently installed node development file versions\n| `remove` | Removes the node development header files for the given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.3]: http://www.python.org/download/releases/2.7.3#download\n[msvc2010]: http://go.microsoft.com/?linkid=9709949\n[msvc2012]: http://go.microsoft.com/?linkid=9816758\n[win7sdk]: http://www.microsoft.com/en-us/download/details.aspx?id=8279\n[compiler update for the Windows SDK 7.1]: http://www.microsoft.com/en-us/download/details.aspx?id=4422\n",
"readmeFilename": "README.md",
- "_id": "node-gyp@0.8.1",
- "_from": "node-gyp@latest"
+ "_id": "node-gyp@0.8.2",
+ "dist": {
+ "shasum": "d1a72a944a16a97b91ed3ea2f2ec6e7c0826c294"
+ },
+ "_from": "node-gyp@~0.8.1"
}
* `<1.2.3` Less than
* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
* `~1.2.3` := `>=1.2.3 <1.3.0`
-* `~1.2` := `>=1.2.0 <2.0.0`
+* `~1.2` := `>=1.2.0 <1.3.0`
* `~1` := `>=1.0.0 <2.0.0`
* `1.2.x` := `>=1.2.0 <1.3.0`
* `1.x` := `>=1.0.0 <2.0.0`
{
"name": "semver",
- "version": "1.1.1",
+ "version": "1.1.2",
"description": "The semantic version parser used by npm.",
"main": "semver.js",
"scripts": {
"bin": {
"semver": "./bin/semver"
},
- "readme": "semver(1) -- The semantic versioner for npm\n===========================================\n\n## Usage\n\n $ npm install semver\n\n semver.valid('1.2.3') // '1.2.3'\n semver.valid('a.b.c') // null\n semver.clean(' =v1.2.3 ') // '1.2.3'\n semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true\n semver.gt('1.2.3', '9.8.7') // false\n semver.lt('1.2.3', '9.8.7') // true\n\nAs a command-line utility:\n\n $ semver -h\n\n Usage: semver -v <version> [-r <range>]\n Test if version(s) satisfy the supplied range(s),\n and sort them.\n\n Multiple versions or ranges may be supplied.\n\n Program exits successfully if any valid version satisfies\n all supplied ranges, and prints all satisfying versions.\n\n If no versions are valid, or ranges are not satisfied,\n then exits failure.\n\n Versions are printed in ascending order, so supplying\n multiple versions to the utility will just sort them.\n\n## Versions\n\nA version is the following things, in this order:\n\n* a number (Major)\n* a period\n* a number (minor)\n* a period\n* a number (patch)\n* OPTIONAL: a hyphen, followed by a number (build)\n* OPTIONAL: a collection of pretty much any non-whitespace characters\n (tag)\n\nA leading `\"=\"` or `\"v\"` character is stripped off and ignored.\n\n## Comparisons\n\nThe ordering of versions is done using the following algorithm, given\ntwo versions and asked to find the greater of the two:\n\n* If the majors are numerically different, then take the one\n with a bigger major number. `2.3.4 > 1.3.4`\n* If the minors are numerically different, then take the one\n with the bigger minor number. `2.3.4 > 2.2.4`\n* If the patches are numerically different, then take the one with the\n bigger patch number. `2.3.4 > 2.3.3`\n* If only one of them has a build number, then take the one with the\n build number. `2.3.4-0 > 2.3.4`\n* If they both have build numbers, and the build numbers are numerically\n different, then take the one with the bigger build number.\n `2.3.4-10 > 2.3.4-9`\n* If only one of them has a tag, then take the one without the tag.\n `2.3.4 > 2.3.4-beta`\n* If they both have tags, then take the one with the lexicographically\n larger tag. `2.3.4-beta > 2.3.4-alpha`\n* At this point, they're equal.\n\n## Ranges\n\nThe following range styles are supported:\n\n* `>1.2.3` Greater than a specific version.\n* `<1.2.3` Less than\n* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`\n* `~1.2.3` := `>=1.2.3 <1.3.0`\n* `~1.2` := `>=1.2.0 <2.0.0`\n* `~1` := `>=1.0.0 <2.0.0`\n* `1.2.x` := `>=1.2.0 <1.3.0`\n* `1.x` := `>=1.0.0 <2.0.0`\n\nRanges can be joined with either a space (which implies \"and\") or a\n`||` (which implies \"or\").\n\n## Functions\n\n* valid(v): Return the parsed version, or null if it's not valid.\n* inc(v, release): Return the version incremented by the release type\n (major, minor, patch, or build), or null if it's not valid.\n\n### Comparison\n\n* gt(v1, v2): `v1 > v2`\n* gte(v1, v2): `v1 >= v2`\n* lt(v1, v2): `v1 < v2`\n* lte(v1, v2): `v1 <= v2`\n* eq(v1, v2): `v1 == v2` This is true if they're logically equivalent,\n even if they're not the exact same string. You already know how to\n compare strings.\n* neq(v1, v2): `v1 != v2` The opposite of eq.\n* cmp(v1, comparator, v2): Pass in a comparison string, and it'll call\n the corresponding function above. `\"===\"` and `\"!==\"` do simple\n string comparison, but are included for completeness. Throws if an\n invalid comparison string is provided.\n* compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if\n v2 is greater. Sorts in ascending order if passed to Array.sort().\n* rcompare(v1, v2): The reverse of compare. Sorts an array of versions\n in descending order when passed to Array.sort().\n\n\n### Ranges\n\n* validRange(range): Return the valid range or null if it's not valid\n* satisfies(version, range): Return true if the version satisfies the\n range.\n* maxSatisfying(versions, range): Return the highest version in the list\n that satisfies the range, or null if none of them do.\n",
+ "readme": "semver(1) -- The semantic versioner for npm\n===========================================\n\n## Usage\n\n $ npm install semver\n\n semver.valid('1.2.3') // '1.2.3'\n semver.valid('a.b.c') // null\n semver.clean(' =v1.2.3 ') // '1.2.3'\n semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true\n semver.gt('1.2.3', '9.8.7') // false\n semver.lt('1.2.3', '9.8.7') // true\n\nAs a command-line utility:\n\n $ semver -h\n\n Usage: semver -v <version> [-r <range>]\n Test if version(s) satisfy the supplied range(s),\n and sort them.\n\n Multiple versions or ranges may be supplied.\n\n Program exits successfully if any valid version satisfies\n all supplied ranges, and prints all satisfying versions.\n\n If no versions are valid, or ranges are not satisfied,\n then exits failure.\n\n Versions are printed in ascending order, so supplying\n multiple versions to the utility will just sort them.\n\n## Versions\n\nA version is the following things, in this order:\n\n* a number (Major)\n* a period\n* a number (minor)\n* a period\n* a number (patch)\n* OPTIONAL: a hyphen, followed by a number (build)\n* OPTIONAL: a collection of pretty much any non-whitespace characters\n (tag)\n\nA leading `\"=\"` or `\"v\"` character is stripped off and ignored.\n\n## Comparisons\n\nThe ordering of versions is done using the following algorithm, given\ntwo versions and asked to find the greater of the two:\n\n* If the majors are numerically different, then take the one\n with a bigger major number. `2.3.4 > 1.3.4`\n* If the minors are numerically different, then take the one\n with the bigger minor number. `2.3.4 > 2.2.4`\n* If the patches are numerically different, then take the one with the\n bigger patch number. `2.3.4 > 2.3.3`\n* If only one of them has a build number, then take the one with the\n build number. `2.3.4-0 > 2.3.4`\n* If they both have build numbers, and the build numbers are numerically\n different, then take the one with the bigger build number.\n `2.3.4-10 > 2.3.4-9`\n* If only one of them has a tag, then take the one without the tag.\n `2.3.4 > 2.3.4-beta`\n* If they both have tags, then take the one with the lexicographically\n larger tag. `2.3.4-beta > 2.3.4-alpha`\n* At this point, they're equal.\n\n## Ranges\n\nThe following range styles are supported:\n\n* `>1.2.3` Greater than a specific version.\n* `<1.2.3` Less than\n* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`\n* `~1.2.3` := `>=1.2.3 <1.3.0`\n* `~1.2` := `>=1.2.0 <1.3.0`\n* `~1` := `>=1.0.0 <2.0.0`\n* `1.2.x` := `>=1.2.0 <1.3.0`\n* `1.x` := `>=1.0.0 <2.0.0`\n\nRanges can be joined with either a space (which implies \"and\") or a\n`||` (which implies \"or\").\n\n## Functions\n\n* valid(v): Return the parsed version, or null if it's not valid.\n* inc(v, release): Return the version incremented by the release type\n (major, minor, patch, or build), or null if it's not valid.\n\n### Comparison\n\n* gt(v1, v2): `v1 > v2`\n* gte(v1, v2): `v1 >= v2`\n* lt(v1, v2): `v1 < v2`\n* lte(v1, v2): `v1 <= v2`\n* eq(v1, v2): `v1 == v2` This is true if they're logically equivalent,\n even if they're not the exact same string. You already know how to\n compare strings.\n* neq(v1, v2): `v1 != v2` The opposite of eq.\n* cmp(v1, comparator, v2): Pass in a comparison string, and it'll call\n the corresponding function above. `\"===\"` and `\"!==\"` do simple\n string comparison, but are included for completeness. Throws if an\n invalid comparison string is provided.\n* compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if\n v2 is greater. Sorts in ascending order if passed to Array.sort().\n* rcompare(v1, v2): The reverse of compare. Sorts an array of versions\n in descending order when passed to Array.sort().\n\n\n### Ranges\n\n* validRange(range): Return the valid range or null if it's not valid\n* satisfies(version, range): Return true if the version satisfies the\n range.\n* maxSatisfying(versions, range): Return the highest version in the list\n that satisfies the range, or null if none of them do.\n",
"readmeFilename": "README.md",
- "_id": "semver@1.1.1",
- "_from": "semver@~1.1.0"
+ "_id": "semver@1.1.2",
+ "_from": "semver@latest"
}
{
- "version": "1.1.70",
+ "version": "1.2.0",
"name": "npm",
"publishConfig": {
"proprietary-attribs": false
"main": "./lib/npm.js",
"bin": "./bin/npm-cli.js",
"dependencies": {
- "semver": "~1.1.0",
+ "semver": "~1.1.2",
"ini": "~1.0.5",
"slide": "1",
"abbrev": "1",
--- /dev/null
+just an npm test
--- /dev/null
+{
+ "name": "npm-test-peer-deps-invalid",
+ "version": "0.0.0",
+ "dependencies": {
+ "npm-test-peer-deps-file": {
+ "version": "1.2.3",
+ "from": "https://raw.github.com/gist/3971128/3f6aa37b4fa1186c2f47da9b77dcc4ec496e3483/index.js",
+ "dependencies": {
+ "opener": {
+ "version": "1.3.0"
+ }
+ }
+ },
+ "npm-test-peer-deps-file-invalid": {
+ "version": "1.2.3",
+ "from": "https://gist.github.com/raw/4303335/861f8d3213061826ab31591840c3cb0ac737f4fc/index.js"
+ },
+ "dict": {
+ "peerInvalid": true
+ }
+ }
+}
--- /dev/null
+{
+ "author": "Domenic Denicola <domenic@domenicdenicola.com> (http://domenicdenicola.com/)",
+ "name": "npm-test-peer-deps-invalid",
+ "version": "0.0.0",
+ "dependencies": {
+ "npm-test-peer-deps-file": "https://raw.github.com/gist/3971128/3f6aa37b4fa1186c2f47da9b77dcc4ec496e3483/index.js",
+ "npm-test-peer-deps-file-invalid": "https://gist.github.com/raw/4303335/861f8d3213061826ab31591840c3cb0ac737f4fc/index.js"
+ },
+ "scripts": {
+ "test": "node test.js"
+ }
+}
--- /dev/null
+var path = require("path")
+var assert = require("assert")
+
+process.env.npm_config_prefix = process.cwd()
+delete process.env.npm_config_global
+delete process.env.npm_config_depth
+
+var npm = process.env.npm_execpath
+
+require("child_process").exec(npm + " ls --json", {
+ env: process.env, cwd: process.cwd() },
+ function (err, stdout, stderr) {
+
+ var actual = JSON.parse(stdout).dependencies
+ var expected = require("./npm-ls.json").dependencies
+
+ // Delete the "problems" entry because it contains system-specific path info,
+ // so we can't compare it accurately and thus have deleted it from
+ // ./npm-ls.json.
+ delete actual.dict.problems
+
+ // It's undefined which peerDependency will get installed first, so
+ // this will be either version 1.1.0 or version 1.0.0
+ var dictVer = actual.dict.version
+ delete actual.dict.version
+ assert(dictVer === "1.1.0" || dictVer === "1.0.0")
+ assert.deepEqual(actual, expected)
+
+ assert.ok(err)
+ assert(/peer invalid/.test(err.message))
+})
--- /dev/null
+just an npm test
--- /dev/null
+{
+ "name": "npm-test-peer-deps",
+ "version": "0.0.0",
+ "dependencies": {
+ "npm-test-peer-deps-file": {
+ "version": "1.2.3",
+ "from": "https://raw.github.com/gist/3971128/3f6aa37b4fa1186c2f47da9b77dcc4ec496e3483/index.js",
+ "dependencies": {
+ "opener": {
+ "version": "1.3.0"
+ }
+ }
+ },
+ "dict": {
+ "version": "1.1.0"
+ }
+ }
+}
--- /dev/null
+{
+ "author": "Domenic Denicola <domenic@domenicdenicola.com> (http://domenicdenicola.com/)",
+ "name": "npm-test-peer-deps",
+ "version": "0.0.0",
+ "dependencies": {
+ "npm-test-peer-deps-file": "https://raw.github.com/gist/3971128/3f6aa37b4fa1186c2f47da9b77dcc4ec496e3483/index.js"
+ },
+ "scripts": {
+ "test": "node test.js"
+ }
+}
--- /dev/null
+var path = require("path")
+var assert = require("assert")
+
+process.env.npm_config_prefix = process.cwd()
+delete process.env.npm_config_global
+delete process.env.npm_config_depth
+
+var npm = process.env.npm_execpath
+
+require("child_process").exec(npm + " ls --json", {
+ env: process.env, cwd: process.cwd() },
+ function (err, stdout, stderr) {
+
+ if (err) throw err
+
+ var actual = JSON.parse(stdout).dependencies
+ var expected = require("./npm-ls.json").dependencies
+
+ assert.deepEqual(actual, expected)
+})