npm: upgrade to 1.1.39
authorisaacs <i@izs.me>
Thu, 12 Jul 2012 00:54:44 +0000 (17:54 -0700)
committerisaacs <i@izs.me>
Thu, 12 Jul 2012 00:54:53 +0000 (17:54 -0700)
Fix #3616

121 files changed:
deps/npm/doc/cli/list.md
deps/npm/html/api/bin.html
deps/npm/html/api/bugs.html
deps/npm/html/api/commands.html
deps/npm/html/api/config.html
deps/npm/html/api/deprecate.html
deps/npm/html/api/docs.html
deps/npm/html/api/edit.html
deps/npm/html/api/explore.html
deps/npm/html/api/help-search.html
deps/npm/html/api/init.html
deps/npm/html/api/install.html
deps/npm/html/api/link.html
deps/npm/html/api/load.html
deps/npm/html/api/ls.html
deps/npm/html/api/npm.html
deps/npm/html/api/outdated.html
deps/npm/html/api/owner.html
deps/npm/html/api/pack.html
deps/npm/html/api/prefix.html
deps/npm/html/api/prune.html
deps/npm/html/api/publish.html
deps/npm/html/api/rebuild.html
deps/npm/html/api/restart.html
deps/npm/html/api/root.html
deps/npm/html/api/run-script.html
deps/npm/html/api/search.html
deps/npm/html/api/shrinkwrap.html
deps/npm/html/api/start.html
deps/npm/html/api/stop.html
deps/npm/html/api/submodule.html
deps/npm/html/api/tag.html
deps/npm/html/api/test.html
deps/npm/html/api/uninstall.html
deps/npm/html/api/unpublish.html
deps/npm/html/api/update.html
deps/npm/html/api/version.html
deps/npm/html/api/view.html
deps/npm/html/api/whoami.html
deps/npm/html/doc/README.html
deps/npm/html/doc/adduser.html
deps/npm/html/doc/bin.html
deps/npm/html/doc/bugs.html
deps/npm/html/doc/build.html
deps/npm/html/doc/bundle.html
deps/npm/html/doc/cache.html
deps/npm/html/doc/changelog.html
deps/npm/html/doc/coding-style.html
deps/npm/html/doc/completion.html
deps/npm/html/doc/config.html
deps/npm/html/doc/deprecate.html
deps/npm/html/doc/developers.html
deps/npm/html/doc/disputes.html
deps/npm/html/doc/docs.html
deps/npm/html/doc/edit.html
deps/npm/html/doc/explore.html
deps/npm/html/doc/faq.html
deps/npm/html/doc/folders.html
deps/npm/html/doc/help-search.html
deps/npm/html/doc/help.html
deps/npm/html/doc/index.html
deps/npm/html/doc/init.html
deps/npm/html/doc/install.html
deps/npm/html/doc/json.html
deps/npm/html/doc/link.html
deps/npm/html/doc/list.html
deps/npm/html/doc/npm.html
deps/npm/html/doc/outdated.html
deps/npm/html/doc/owner.html
deps/npm/html/doc/pack.html
deps/npm/html/doc/prefix.html
deps/npm/html/doc/prune.html
deps/npm/html/doc/publish.html
deps/npm/html/doc/rebuild.html
deps/npm/html/doc/registry.html
deps/npm/html/doc/removing-npm.html
deps/npm/html/doc/restart.html
deps/npm/html/doc/root.html
deps/npm/html/doc/run-script.html
deps/npm/html/doc/scripts.html
deps/npm/html/doc/search.html
deps/npm/html/doc/semver.html
deps/npm/html/doc/shrinkwrap.html
deps/npm/html/doc/star.html
deps/npm/html/doc/start.html
deps/npm/html/doc/stop.html
deps/npm/html/doc/submodule.html
deps/npm/html/doc/tag.html
deps/npm/html/doc/test.html
deps/npm/html/doc/uninstall.html
deps/npm/html/doc/unpublish.html
deps/npm/html/doc/update.html
deps/npm/html/doc/version.html
deps/npm/html/doc/view.html
deps/npm/html/doc/whoami.html
deps/npm/lib/cache.js
deps/npm/lib/ls.js
deps/npm/lib/npm.js
deps/npm/lib/test.js
deps/npm/lib/utils/fetch.js
deps/npm/man/man1/list.1
deps/npm/man/man1/npm.1
deps/npm/man/man3/npm.3
deps/npm/node_modules/couch-login/README.md [new file with mode: 0644]
deps/npm/node_modules/couch-login/couch-login.js [new file with mode: 0644]
deps/npm/node_modules/couch-login/package.json [new file with mode: 0644]
deps/npm/node_modules/graceful-fs/graceful-fs.js
deps/npm/node_modules/graceful-fs/package.json
deps/npm/node_modules/node-gyp/bin/node-gyp.js
deps/npm/node_modules/node-gyp/lib/build.js
deps/npm/node_modules/node-gyp/lib/configure.js
deps/npm/node_modules/node-gyp/lib/install.js
deps/npm/node_modules/node-gyp/lib/node-gyp.js
deps/npm/node_modules/node-gyp/package.json
deps/npm/node_modules/npm-registry-client/index.js
deps/npm/node_modules/npm-registry-client/lib/get.js
deps/npm/node_modules/npm-registry-client/lib/request.js
deps/npm/node_modules/npm-registry-client/package.json
deps/npm/node_modules/read-package-json/package.json
deps/npm/node_modules/read-package-json/read-json.js
deps/npm/package.json

index 93d86cd8380e782048b74f1d8d77d4f695fb3b70..3dd709b62b1a69c3dacab495f81d0b49eff2e33f 100644 (file)
@@ -3,20 +3,26 @@ npm-ls(1) -- List installed packages
 
 ## SYNOPSIS
 
-    npm list
-    npm ls
-    npm la
-    npm ll
+    npm list [<pkg> ...]
+    npm ls [<pkg> ...]
+    npm la [<pkg> ...]
+    npm ll [<pkg> ...]
 
 ## DESCRIPTION
 
 This command will print to stdout all the versions of packages that are
 installed, as well as their dependencies, in a tree-structure.
 
-It does not take positional arguments, though you may set config flags
-like with any other command, such as `-g` to list global packages.
+Positional arguments are `name@version-range` identifiers, which will
+limit the results to only the paths to the packages named.  Note that
+nested packages will *also* show the paths to the specified packages.
+For example, running `npm ls promzard` in npm's source tree will show:
 
-It will print out extraneous, missing, and invalid packages.
+    npm@@VERSION@ /path/to/npm
+    â””─┬ init-package-json@0.0.4
+      â””── promzard@0.1.5
+
+It will show print out extraneous, missing, and invalid packages.
 
 When run as `ll` or `la`, it shows extended information by default.
 
index 9071e7952c508ab74115a5ff1bf11377b68bca06..15821178a84cac5f762a945e955e3605bea3b20a 100644 (file)
@@ -19,7 +19,7 @@
 <p>This function should not be used programmatically.  Instead, just refer
 to the <code>npm.bin</code> member.</p>
 </div>
-<p id="footer">bin &mdash; npm@1.1.36</p>
+<p id="footer">bin &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9e658dbcf824b9bc1008382f93beaf1bff72ae06..b51d61d78a58ab7eb9eb4c217f790b9953a52368 100644 (file)
@@ -25,7 +25,7 @@ optional version number.</p>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">bugs &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 61cdac20d55ce64dd3d208e6dfb1515b973474fc..15b5961d942731d07d49baac4b26df73dd5c1159 100644 (file)
@@ -28,7 +28,7 @@ usage, or <code>man 3 npm-&lt;command&gt;</code> for programmatic usage.</p>
 
 <ul><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer">commands &mdash; npm@1.1.36</p>
+<p id="footer">commands &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7977282027f80b751cf1e715c94b9e99ab0a9f1e..712f290a00a475a43c5b0fd15ccc325ac1f6c6d3 100644 (file)
@@ -33,7 +33,7 @@ functions instead.</p>
 
 <ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
 </div>
-<p id="footer">config &mdash; npm@1.1.36</p>
+<p id="footer">config &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 727aa43733d8a404e838e3d3de9e250da5fc5db6..4f4f02f82c64add848646e2366e7aced24471431 100644 (file)
@@ -30,7 +30,7 @@ install the package.</p></li></ul>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">deprecate &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7c22c55dfc5468cc7778a3b2f80d61d10219ff8d..e1a59d99629ad8cc9446fcd47293cc328bc72a3a 100644 (file)
@@ -25,7 +25,7 @@ optional version number.</p>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">docs &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ce5e41a12acbb9841b3a364e47a3ac9ced54a3bb..33ea95c741bd62adfde382cec4b7f9b4543a7078 100644 (file)
@@ -30,7 +30,7 @@ to open. The package can optionally have a version number attached.</p>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">edit &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cda6d483efb927867c31431b0108047c1191af45..0761a829777fea95f779de322b5e5106e52aef87 100644 (file)
@@ -24,7 +24,7 @@ sure to use <code>npm rebuild &lt;pkg&gt;</code> if you make any changes.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">explore &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fb8ff2c14b34e6e77234ca762a362d0fb249ecaa..8b57f48ab874e88092790415249451739d3f6461 100644 (file)
@@ -32,7 +32,7 @@ Name of the file that matched</li></ul>
 
 <p>The silent parameter is not neccessary not used, but it may in the future.</p>
 </div>
-<p id="footer">help-search &mdash; npm@1.1.36</p>
+<p id="footer">help-search &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7f19cc187c54880d24ef4d4c5b61c3724e2676cf..6acf5c26db458f695b0ab1acc70db85f98341819 100644 (file)
@@ -35,7 +35,7 @@ then go ahead and use this programmatically.</p>
 
 <p><a href="../doc/json.html">json(1)</a></p>
 </div>
-<p id="footer">init &mdash; npm@1.1.36</p>
+<p id="footer">init &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bb3302dc70474db3f4c3031437147d76e2092c4e..f36411805cd068e2fd5a1f1bed0244db09608329 100644 (file)
@@ -25,7 +25,7 @@ the name of a package to be installed.</p>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">install &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1afd31ef4f708a108959ea0e74acd3a373b514f0..507296e9a467973237240584665f2c08161c3e8a 100644 (file)
@@ -39,7 +39,7 @@ npm.commands.link('redis', cb)  # link-install the package</code></pre>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">link &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 71df640782bfe592a3e101c9ab9074a1af60bdfe..b710405e3dad879cd1f9d0473eebef0e11d7cb2a 100644 (file)
@@ -32,7 +32,7 @@ config object.</p>
 
 <p>For a list of all the available command-line configs, see <code>npm help config</code></p>
 </div>
-<p id="footer">load &mdash; npm@1.1.36</p>
+<p id="footer">load &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f067240c3117784293bfd9722a97f13b53bceb28..a54639dfb4e91026b7c3da6287087ba1ea06d971 100644 (file)
@@ -59,7 +59,7 @@ project.</p>
 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 &mdash; npm@1.1.36</p>
+<p id="footer">ls &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a9cf167d5a9a42b6193b09192fd92382dd9e50c2..110ad0d9353559d4dac321c6191c4c9d4e343dab 100644 (file)
@@ -24,7 +24,7 @@ npm.load(configObject, function (er, npm) {
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.1.36</p>
+<p>1.1.39</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -91,7 +91,7 @@ method names.  Use the <code>npm.deref</code> method to find the real name.</p>
 
 <pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre>
 </div>
-<p id="footer">npm &mdash; npm@1.1.36</p>
+<p id="footer">npm &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4e8dae35e314ed1b22f07f243acde7728869041d..2ee552b66343fc7c3e7db344df9e8f3ead2ea452 100644 (file)
@@ -19,7 +19,7 @@ currently outdated.</p>
 
 <p>If the 'packages' parameter is left out, npm will check all packages.</p>
 </div>
-<p id="footer">outdated &mdash; npm@1.1.36</p>
+<p id="footer">outdated &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d40b0f75ee443752aeb857123bf7b37a87967a74..2025d49030d23375446d292b44641404c918998e 100644 (file)
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">owner &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0fcc3b5f8c5d38492732e36d8063c8f35553ac2f..db67feb676f768b6708babc52eb57c73fbf5c9ea 100644 (file)
@@ -25,7 +25,7 @@ overwritten the second time.</p>
 
 <p>If no arguments are supplied, then npm packs the current package folder.</p>
 </div>
-<p id="footer">pack &mdash; npm@1.1.36</p>
+<p id="footer">pack &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b7ad95634f3253e9af5f9914f7416dd2fe1fe698..d18c608f98294cfaf441714bfb3b5202d1c70529 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">prefix &mdash; npm@1.1.36</p>
+<p id="footer">prefix &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1aad29b947a49bbffea88e1c4c7d4c99208ee033..d57d8fe130dadb3f237e7b21279578484665f448 100644 (file)
@@ -23,7 +23,7 @@
 <p>Extraneous packages are packages that are not listed on the parent
 package's dependencies list.</p>
 </div>
-<p id="footer">prune &mdash; npm@1.1.36</p>
+<p id="footer">prune &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a425f377e4b2cc4dc9be86399f7a1547c7bcdf33..9d2decf1b9c56e4f8dac8f355d86b51836d2528c 100644 (file)
@@ -32,7 +32,7 @@ the registry.  Overwrites when the "force" environment variable is set.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">publish &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cc8637118bac00e0d95ae442bbcb5b3f81f457c5..063db4440e177ee28bfee5e554ada449c66c8d8f 100644 (file)
@@ -22,7 +22,7 @@ the new binary. If no 'packages' parameter is specify, every package will be reb
 
 <p>See <code>npm help build</code></p>
 </div>
-<p id="footer">rebuild &mdash; npm@1.1.36</p>
+<p id="footer">rebuild &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 172db36f9abb2e385c61670cda4fc973cba90b02..71523267a8d939c5964f873a9af538d9fd9c90c2 100644 (file)
@@ -27,7 +27,7 @@ in the <code>packages</code> parameter.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">restart &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7437950774b93be332f5ca06399f85082f87e397..6a5d37af12828d47054e00076daa9f36da94023a 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically.</p>
 </div>
-<p id="footer">root &mdash; npm@1.1.36</p>
+<p id="footer">root &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 34cb7ca89d353e6e4e2356350fd2b161af4779f4..9beae5377a81167de59831b60311a99c83891440 100644 (file)
@@ -29,7 +29,7 @@ assumed to be the command to run. All other elements are ignored.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">run-script &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6acf530c506bfc55bbbbb9c8f91751f053025470..b86bbb414743a5895bae4767a3893339d15bf018 100644 (file)
@@ -32,7 +32,7 @@ excluded term (the "searchexclude" config). The search is case insensitive
 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 &mdash; npm@1.1.36</p>
+<p id="footer">search &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 69fd1bd3a4a786ab8d3726a0ceff6c7d3094e921..26d8cbb694b8ce25fef10de77f353e581936efbe 100644 (file)
@@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p>
 <p>Finally, 'callback' is a function that will be called when the shrinkwrap has
 been saved.</p>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.1.36</p>
+<p id="footer">shrinkwrap &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 94a43b82b0eb912237efe97f49227b80089e584c..cd9142c4950fb0502434d06ec066f613d6f7e3c2 100644 (file)
@@ -19,7 +19,7 @@
 <p>npm can run tests on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">start &mdash; npm@1.1.36</p>
+<p id="footer">start &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8d5ab8866e58b7c06c102b6ac64631192464c78b..38baa073534a99c2f042699be94fb6d8b86d3fdb 100644 (file)
@@ -19,7 +19,7 @@
 <p>npm can run stop on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">stop &mdash; npm@1.1.36</p>
+<p id="footer">stop &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 109abda4e9077e7b0127d68b6b4e0d6fa68a3a05..af4b18445acc978f744a31ce14f39880f2cad2a0 100644 (file)
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
 
 <ul><li>npm help json</li><li>git help submodule</li></ul>
 </div>
-<p id="footer">submodule &mdash; npm@1.1.36</p>
+<p id="footer">submodule &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7c349c95b4da0b2b9bbdd954e05c2690eb83e203..01d5c7843cdfe9bdf9efaa8ef5e6fc666de7e203 100644 (file)
@@ -29,7 +29,7 @@ parameter is missing or falsey (empty), the default froom the config will be
 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 &mdash; npm@1.1.36</p>
+<p id="footer">tag &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8cdd76349a8a6d57542aaf5d698d50f7b97b88cb..0021ccabee7a601242cb4e3f58f7eb1151671e15 100644 (file)
@@ -22,7 +22,7 @@ true.</p>
 <p>npm can run tests on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">test &mdash; npm@1.1.36</p>
+<p id="footer">test &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f372bf6b37d697212d68d9cbc64caa6472dc071e..8db52ed18808f262735ae06b9a73e841a17d229a 100644 (file)
@@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">uninstall &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 860c1c531204fe3f2edc767ac3a1b4d70e0800d6..1bb37f02ce8c37a12b57b18df42a1b3cda6afe46 100644 (file)
@@ -26,7 +26,7 @@ is what is meant.</p>
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">unpublish &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f40b264ecfafac6f6b04ce6caa96a7fba944c0ce..b97eb7ea8406986c772ea7316afe19a8316bbfb5 100644 (file)
@@ -18,7 +18,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">update &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e842bb05bbd624820b732fdf0ad720e6bf5424c4..c4ed3a26c28252b03574f20c71cc6ef81c1ad20f 100644 (file)
@@ -24,7 +24,7 @@ fail if the repo is not clean.</p>
 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 &mdash; npm@1.1.36</p>
+<p id="footer">version &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 74e864836b6e99e4204ec61435aa22d4fb2327cb..fe1b993cd4ee782a9a646c52b3662299e0ec8f5f 100644 (file)
@@ -99,7 +99,7 @@ the field name.</p>
 
 <p>corresponding to the list of fields selected.</p>
 </div>
-<p id="footer">view &mdash; npm@1.1.36</p>
+<p id="footer">view &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1a4fb26b2f0996475c6659df66d0f2239bbc2074..1d842778c171bd531149d774ec509a7dabb13cd0 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">whoami &mdash; npm@1.1.36</p>
+<p id="footer">whoami &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a2c01aeb0273cb3d5ce44be216d99e8858a89df0..56a75117b85b1cc818f01e5a15daf229a6b3eb43 100644 (file)
@@ -261,7 +261,7 @@ will no doubt tell you to put the output in a gist or email.</p>
 
 <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> &mdash; npm@1.1.36</p>
+<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1afb3c03ea316d1b1fc235b1d12f41441f9850fd..e38ff53ef16726f2fbd71c5447891fe9f4b0b80d 100644 (file)
@@ -39,7 +39,7 @@ authorize on a new machine.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">adduser &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cd5a94b30cabcb2af17e892bf0dba6e3111ba2d8..646360e0013daa456bc7e398c2e59ea1f930898c 100644 (file)
@@ -20,7 +20,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">bin &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e3def71344e5af61c1744840397c44cf38086b56..8c6176875ad0da6252bb46e1f20cb8d45bcf76a7 100644 (file)
@@ -36,7 +36,7 @@ config param.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">bugs &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9351cdbd7f886224486d1a76f0db5fc3cb4e5533..de61f26034460b0d77931d4f07651fe82b797d5f 100644 (file)
@@ -25,7 +25,7 @@ A folder containing a <code>package.json</code> file in its root.</li></ul>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">build &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 72eade43a3970b5f906590e32eace95dbd749d90..a0cd97ba735520c588e60a9e1ad6cccea2f359ff 100644 (file)
@@ -20,7 +20,7 @@ install packages into the local space.</p>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">bundle &mdash; npm@1.1.36</p>
+<p id="footer">bundle &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5da9402d26ec6c28c992e3ffe2b687e2c78d4b3c..d081ead031dd7ce7d71ce0bbbdd577cb1bbf13d6 100644 (file)
@@ -66,7 +66,7 @@ they do not make an HTTP request to the registry.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">cache &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3c2687f323a382aea87e64618dd010f614763bfe..c536e72956c4ea6d8a3c192e69145f54ee129808 100644 (file)
@@ -65,7 +65,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">changelog &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index df86286851045c2af5aefd3134eb2babf9388538..3f3cfd2ba6d79177662649e7046e13e18810cbd5 100644 (file)
@@ -180,7 +180,7 @@ set to anything."</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">coding-style &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 73501b803fa273dbc2666a60c52ce55779b264b0..5909d8c84e5d30aa271ffa3fb8980971e26cc5d0 100644 (file)
@@ -33,7 +33,7 @@ completions based on the arguments.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">completion &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 27ed281c19b767fb1c1b2dc3b1f8f99ad9564f04..92ccaa2dda3806aad9de74169a6dcb5b936f43eb 100644 (file)
@@ -735,7 +735,7 @@ then answer "no" to any prompt.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">config &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e30db820f70afaa9985e0a387b3c8c4d8a40d151..821ee22a9d86d69e349e82a72ae1918001dde98e 100644 (file)
@@ -29,7 +29,7 @@ something like this:</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">deprecate &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dbd006e815513bb98516d3c4cf6deddf706a1c44..ce482849e7bb2a52e9342eee217e551b0a81770f 100644 (file)
@@ -160,7 +160,7 @@ from a fresh checkout.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">developers &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a229f487937bedffa8397abba955f744547bd59f..a398ad36548499815ad3735dee08cbe62b0c18b7 100644 (file)
@@ -80,7 +80,7 @@ license statement)</li><li>Illegal content.</li></ol>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">disputes &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7e0640aa5c7317f32cb38f5aaa69828e4407242d..5aea2fdc97740cd53b048498c04dc3124188b221 100644 (file)
@@ -37,7 +37,7 @@ config param.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">docs &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d84553e7e06a3006a9f4e2df44b22b143659e941..8ad9ce120d4024a4a538af42410a545f1b39afaf 100644 (file)
@@ -37,7 +37,7 @@ or <code>"notepad"</code> on Windows.</li><li>Type: path</li></ul>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">edit &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 89320f161bd87c9a6cff78a33081c1e283736426..7d8e47918b0d50898bbc67df28de07c37961ed21 100644 (file)
@@ -40,7 +40,7 @@ Windows</li><li>Type: path</li></ul>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">explore &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d8a1a32e22873038f2859f56c406709c66342f39..0aac7c84d7633caf17e4d223175f5057efe2fe41 100644 (file)
@@ -241,7 +241,7 @@ We'll have someone kick it or something.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">faq &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0b6825460fa1265a20731734d8abd6d86ecca7a2..0adeb0522f21734b9907fef218a1b2845b857aa6 100644 (file)
@@ -205,7 +205,7 @@ cannot be found elsewhere.  See <code><a href="../doc/json.html">json(1)</a></co
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">folders &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 61f6ad9bd7bfd00b79f645a2e9f3ba7fc3d66b6b..ec27b93bdd90cfc6241b6805f2b3d6a99429d645 100644 (file)
@@ -38,7 +38,7 @@ where the terms were found in the documentation.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">help-search &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0802f4b106393f67c7e40e797637464106e058ff..442103bae7f741b5a23d8589fb4c9abfee0d53b4 100644 (file)
@@ -36,7 +36,7 @@ matches are equivalent to specifying a topic name.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">help &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9720b928930e1faf2713505ca3fbd5be784985b0..428ade47d06870ebf40d13b006d700f301bf4495 100644 (file)
 
 <p> Display npm username</p>
 </div>
-<p id="footer">index &mdash; npm@1.1.36</p>
+<p id="footer">index &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 433f360ee12b6d971cd2c7556eea1cc4e03ba5f0..8abaa3158174e4807880232f53c0538519b1df71 100644 (file)
@@ -29,7 +29,7 @@ without a really good reason to do so.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">init &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 294ef28c4d27460a53996611ecf6742fd6a270de..c5e8273a5071f514c54f8d988125d583802f47aa 100644 (file)
@@ -133,7 +133,7 @@ affects a real use-case, it will be investigated.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">install &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 082e2bae3f19abcba6b5355fb850028a8f301f7b..2d3c9df9a6bafcd040868460d1d209f97d749eac 100644 (file)
@@ -524,7 +524,7 @@ overridden.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">json &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 18c3f9f7121bcd21162d2decd9e8f25f72a4a05f..5d72c481b18ab6752dcf9516939d1487dcd72edd 100644 (file)
@@ -58,7 +58,7 @@ installation target into your project's <code>node_modules</code> folder.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">link &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5fd5595e18cdaa1e79e4657ca0f5ae8191bf0a55..f275843fc8b2c72b577f132178846dc69c2eb9b7 100644 (file)
 
 <h2 id="SYNOPSIS">SYNOPSIS</h2>
 
-<pre><code>npm list
-npm ls
-npm la
-npm ll</code></pre>
+<pre><code>npm list [&lt;pkg&gt; ...]
+npm ls [&lt;pkg&gt; ...]
+npm la [&lt;pkg&gt; ...]
+npm ll [&lt;pkg&gt; ...]</code></pre>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
 <p>This command will print to stdout all the versions of packages that are
 installed, as well as their dependencies, in a tree-structure.</p>
 
-<p>It does not take positional arguments, though you may set config flags
-like with any other command, such as <code>-g</code> to list global packages.</p>
+<p>Positional arguments are <code>name@version-range</code> identifiers, which will
+limit the results to only the paths to the packages named.  Note that
+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>
 
-<p>It will print out extraneous, missing, and invalid packages.</p>
+<pre><code>npm@1.1.39 /path/to/npm
+└─┬ init-package-json@0.0.4
+  â””── promzard@0.1.5</code></pre>
+
+<p>It will show print out extraneous, missing, and invalid packages.</p>
 
 <p>When run as <code>ll</code> or <code>la</code>, it shows extended information by default.</p>
 
@@ -58,7 +64,7 @@ project.</p>
 
 <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">list &mdash; npm@1.1.36</p>
+<p id="footer">list &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9e8120ca13119c356a4f1ebef9354c6ee3298d27..8773464a769b55f7a9ae40f2c01b609357de801b 100644 (file)
@@ -14,7 +14,7 @@
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.1.36</p>
+<p>1.1.39</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -135,7 +135,7 @@ will no doubt tell you to put the output in a gist or email.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">npm &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b7f4a58e45bbbd0f3db28637875014bf8425ddda..fbd142ada020c57caf136434efa381df2f7fc791 100644 (file)
@@ -21,7 +21,7 @@ packages are currently outdated.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">outdated &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e9f01a5f9cece2ac2017e1777a939bef2c44a4b1..55a4100cd652b8bffc8fa8b4ee20d7005efd92de 100644 (file)
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">owner &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 59902943012cb886c067bbddd20307fe20ddc982..5f834e5953920caa7e07454b637e41d67d814049 100644 (file)
@@ -29,7 +29,7 @@ overwritten the second time.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">pack &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index afa7fdea1d97c7bf8731b18169035815e4bdf434..46bb2cc3373f71c933c1914bc38300bba352a339 100644 (file)
@@ -20,7 +20,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">prefix &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ec678aa9815e4b235c3c8f00479d264c115116e1..4c2e499e92cd344563751ddb12352f3894b270b4 100644 (file)
@@ -25,7 +25,7 @@ package's dependencies list.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">prune &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1b0b4e5b785d284623edf977ebb0e16b5819cebd..7e973fb7ca5f2d6ae1702b680d55c72a399aa558 100644 (file)
@@ -29,7 +29,7 @@ the registry.  Overwrites when the "--force" flag is set.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">publish &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 10b643248a847a68e6a5a7b7a7a2fdc0d742a24b..76f7e2d27e5cfe704ba56cecedf925ab7e34f9ae 100644 (file)
@@ -25,7 +25,7 @@ the new binary.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">rebuild &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e85aacf28a7c6a4e5738946c93b8e9eb9b2780e0..683a255b6c121cb70a497c3e65fd27ddfcdf4953 100644 (file)
@@ -97,7 +97,7 @@ ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">registry &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8fcd3bc71587e0f26d31cc1a033c0a4b0b7d61fd..40bad833f5f740dde7ea77a30b9dbfa1a4bf111c 100644 (file)
@@ -58,7 +58,7 @@ modules.  To track those down, you can do the following:</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">removing-npm &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 33c6f8959f29ce9f2e9e3317d85c9278799e6fee..691a63172b0a0976356ec2379dc0bae93d6f5186 100644 (file)
@@ -24,7 +24,7 @@ the "start" script.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">restart &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9725e590069e92f6841362d1c7581e96587a9231..89fbc09cdb3f57c9b5bb56c483afcbf2a4a4f66d 100644 (file)
@@ -20,7 +20,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">root &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6ebc209df4e0df53b90caebef8a139d997f6d503..cb52814177829f2dc6edb1c73f72af172bdd1d4c 100644 (file)
@@ -23,7 +23,7 @@ called directly, as well.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">run-script &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 053a3b289955390aac23919d8dd366bb4bc2b623..1446b67cdce32f5584437793c9e0bc91ebfff169 100644 (file)
@@ -177,7 +177,7 @@ will sudo the npm command in question.</li></ul>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">scripts &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f9a5bd51bbd42f0bdfcfa56bda24679be9d582ef..3178af14d1b07849194be49bae923446e142867d 100644 (file)
@@ -24,7 +24,7 @@ expression characters must be escaped or quoted in most shells.)</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">search &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b1e6443216eff8187419cdb53a36b656e7cd7826..f0d0d5bc2e1f6aee38e36ac311cd800aa82e5df8 100644 (file)
@@ -104,7 +104,7 @@ that satisfies the range, or null if none of them do.</li></ul>
 
 <ul><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">semver &mdash; npm@1.1.36</p>
+<p id="footer">semver &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 29dd8691ea93436d485b382e9e3f667458a58e13..e1d0288467954a381428177296dd79800f78a1b4 100644 (file)
@@ -169,7 +169,7 @@ versions.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">shrinkwrap &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ef75bf9c292bd6785f2d66013ee6732ecdcea43a..2caa4ffa32d235c7adf9e1bc23c8899f0c337b7f 100644 (file)
@@ -26,7 +26,7 @@ a vaguely positive way to show that you care.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">star &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0a17b06eaf59a045a3915975d96e02b7f22d207e..0ba8e1f398c9bcdd1ea501c504b40ecc7b4fb056 100644 (file)
@@ -20,7 +20,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">start &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 55203f96fe41fa19292376f5f450848e9fa9a9a6..9283cd962878fbe3fb2464c916827d53413bc0c2 100644 (file)
@@ -20,7 +20,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">stop &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c98b0a9af851eefcf1810223ecd7c970a6d73640..68f7324531572205ad83c8978e02265ce47e1d79 100644 (file)
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
 
 <ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
 </div>
-<p id="footer">submodule &mdash; npm@1.1.36</p>
+<p id="footer">submodule &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 81e3afa485611eb7d033944ce20f4da25aa9db90..5c1e539c7b07c81080b78251bf71cd22d43cd15d 100644 (file)
@@ -21,7 +21,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">tag &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 69210089fd93ca44efeb9655f15223fe913d2602..52121941236e39d37db69ad4dcf01c68cb0be7b5 100644 (file)
@@ -23,7 +23,7 @@ true.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">test &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e59fe56dc8735f6f584661447a8aee861545ce81..743629aef9f04010bd2ae17784c397f82a3398a8 100644 (file)
@@ -22,7 +22,7 @@ on its behalf.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">uninstall &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 524fe2ef5cca7ee4b394bebe3bc1f88fb91c1fa5..203f3186e3eb86c23bf85d0cbb6a038e8006a9b1 100644 (file)
@@ -34,7 +34,7 @@ the root package entry is removed from the registry entirely.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">unpublish &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3b84fde7d04e3ed1eb92ba1d5c8a5b57f157dbdb..5778f4d81cc523572c44240565fb856ca7630e9c 100644 (file)
@@ -23,7 +23,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">update &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e9d072606890058f415867c2ff003bb0da685f17..40298eb85be868277fd57f03586c61dbdb68c245 100644 (file)
@@ -31,7 +31,7 @@ will use it as a commit message when creating a version commit.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">version &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fe67a60ba2438e97d87ccc5b08d957eb9cab7c99..0099b83016ba5af46c2bcb05be8f5317483828ad 100644 (file)
@@ -88,7 +88,7 @@ the field name.</p>
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">view &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3824ae56d64e6d68aaca0540acbc540826cda63c..c3c9e0cb050bc8ea132bd87867457995eed944ed 100644 (file)
@@ -20,7 +20,7 @@
 
 <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 &mdash; npm@1.1.36</p>
+<p id="footer">whoami &mdash; npm@1.1.39</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3d77272d630aa7b2d49549d9015ae4f00c1922d5..de7ccadbb7ad83a892ea86b7a967f3c3a4bae1df 100644 (file)
@@ -506,19 +506,6 @@ function addNameRange (name, range, data, cb) {
              , {name:name, range:range, hasData:!!data})
     engineFilter(data)
 
-    if (npm.config.get("registry")) return next_()
-
-    cachedFilter(data, range, function (er) {
-      if (er) return cb(er)
-      if (Object.keys(data.versions).length === 0) {
-        return cb(new Error( "Can't fetch, and not cached: "
-                           + data.name + "@" + range))
-      }
-      next_()
-    })
-  }
-
-  function next_ () {
     log.silly("addNameRange", "versions"
              , [data.name, Object.keys(data.versions || {})])
 
@@ -540,39 +527,6 @@ function addNameRange (name, range, data, cb) {
   }
 }
 
-// filter the versions down based on what's already in cache.
-function cachedFilter (data, range, cb) {
-  log.silly("cachedFilter", data.name)
-  ls_(data.name, 1, function (er, files) {
-    if (er) {
-      log.error("cachedFilter", "Not in cache, can't fetch", data.name)
-      return cb(er)
-    }
-    files = files.map(function (f) {
-      return path.basename(f.replace(/(\\|\/)$/, ""))
-    }).filter(function (f) {
-      return semver.valid(f) && semver.satisfies(f, range)
-    })
-
-    if (files.length === 0) {
-      return cb(new Error("Not in cache, can't fetch: "+data.name+"@"+range))
-    }
-
-    log.silly("cached", [data.name, files])
-    Object.keys(data.versions).forEach(function (v) {
-      if (files.indexOf(v) === -1) delete data.versions[v]
-    })
-
-    if (Object.keys(data.versions).length === 0) {
-      log.error("cachedFilter", "Not in cache, can't fetch", data.name)
-      return cb(new Error("Not in cache, can't fetch: "+data.name+"@"+range))
-    }
-
-    log.silly("filtered", [data.name, Object.keys(data.versions)])
-    cb(null, data)
-  })
-}
-
 function installTargetsError (requested, data) {
   var targets = Object.keys(data["dist-tags"]).filter(function (f) {
     return (data.versions || {}).hasOwnProperty(f)
index 02e7fe274a47f7ecfb055ef5629dce2727d7bf41..2b45ca3dcea1b9676703f798456288fbee142f26 100644 (file)
@@ -13,22 +13,30 @@ var npm = require("./npm.js")
   , log = require("npmlog")
   , path = require("path")
   , archy = require("archy")
+  , semver = require("semver")
 
 ls.usage = "npm ls"
 
+ls.completion = require("./utils/completion/installed-deep.js")
+
 function ls (args, silent, cb) {
   if (typeof cb !== "function") cb = silent, silent = false
 
-  if (args.length) {
-    // TODO: it would actually be nice to maybe show the locally
-    // installed packages only matching the argument names.
-    log.warn("ls doesn't take positional args. Try the 'search' command")
-  }
-
   var dir = path.resolve(npm.dir, "..")
 
+  // npm ls 'foo@~1.3' bar 'baz@<2'
+  if (!args) args = []
+  else args = args.map(function (a) {
+    var nv = a.split("@")
+      , name = nv.shift()
+      , ver = semver.validRange(nv.join("@")) || ""
+
+    return [ name, ver ]
+  })
+
   readInstalled(dir, npm.config.get("depth"), function (er, data) {
-    var lite = getLite(bfsify(data))
+    var bfs = bfsify(data, args)
+      , lite = getLite(bfs)
     if (er || silent) return cb(er, data, lite)
 
     var long = npm.config.get("long")
@@ -36,7 +44,7 @@ function ls (args, silent, cb) {
       , out
     if (json) {
       var seen = []
-      var d = long ? bfsify(data) : lite
+      var d = long ? bfs : lite
       // the raw data can be circular
       out = JSON.stringify(d, function (k, o) {
         if (typeof o === "object") {
@@ -46,14 +54,19 @@ function ls (args, silent, cb) {
         return o
       }, 2)
     } else if (npm.config.get("parseable")) {
-      out = makeParseable(bfsify(data), long, dir)
+      out = makeParseable(bfs, long, dir)
     } else if (data) {
-      out = makeArchy(bfsify(data), long, dir)
+      out = makeArchy(bfs, long, dir)
     }
     output.write(out, function (er) { cb(er, data, lite) })
   })
 }
 
+// only include 
+function filter (data, args) {
+
+}
+
 function alphasort (a, b) {
   a = a.toLowerCase()
   b = b.toLowerCase()
@@ -124,7 +137,7 @@ function getLite (data, noname) {
   return lite
 }
 
-function bfsify (root, current, queue, seen) {
+function bfsify (root, args, current, queue, seen) {
   // walk over the data, and turn it from this:
   // +-- a
   // |   `-- b
@@ -134,6 +147,7 @@ function bfsify (root, current, queue, seen) {
   // +-- a
   // `-- b
   // which looks nicer
+  args = args || []
   current = current || root
   queue = queue || []
   seen = seen || [root]
@@ -153,10 +167,37 @@ function bfsify (root, current, queue, seen) {
     queue.push(dep)
     seen.push(dep)
   })
-  if (!queue.length) return root
-  return bfsify(root, queue.shift(), queue, seen)
+
+  if (!queue.length) {
+    // if there were args, then only show the paths to found nodes.
+    return filterFound(root, args)
+  }
+  return bfsify(root, args, queue.shift(), queue, seen)
 }
 
+function filterFound (root, args) {
+  if (!args.length) return root
+  var deps = root.dependencies
+  if (deps) Object.keys(deps).forEach(function (d) {
+    var dep = filterFound(deps[d], args)
+
+    // see if this one itself matches
+    var found = false
+    for (var i = 0; !found && i < args.length; i ++) {
+      if (d === args[i][0]) {
+        found = semver.satisfies(dep.version, args[i][1])
+      }
+    }
+    // included explicitly
+    if (found) dep._found = true
+    // included because a child was included
+    if (dep._found && !root._found) root._found = 1
+    // not included
+    if (!dep._found) delete deps[d]
+  })
+  if (!root._found) root._found = false
+  return root
+}
 
 function makeArchy (data, long, dir) {
   var out = makeArchy_(data, long, dir, 0)
@@ -178,8 +219,11 @@ function makeArchy_ (data, long, dir, depth, parent, d) {
 
   var out = {}
   // the top level is a bit special.
-  out.label = data._id ? data._id + " " : ""
-  if (data.link) out.label += "-> " + data.link
+  out.label = data._id || ""
+  if (data._found === true && data._id) {
+    out.label = "\033[33;40m" + out.label.trim() + "\033[m "
+  }
+  if (data.link) out.label += " -> " + data.link
 
   if (data.invalid) {
     if (data.realName !== data.name) out.label += " ("+data.realName+")"
@@ -237,10 +281,13 @@ function makeParseable (data, long, dir, depth, parent, d) {
     .sort(alphasort).map(function (d) {
       return makeParseable(data.dependencies[d], long, dir, depth + 1, data, d)
     }))
+  .filter(function (x) { return x })
   .join("\n")
 }
 
 function makeParseable_ (data, long, dir, depth, parent, d) {
+  if (data.hasOwnProperty("_found") && data._found !== true) return ""
+
   if (typeof data === "string") {
     if (data.depth < npm.config.get("depth")) {
       var p = parent.link || parent.path
index 6113604f7047e23a5eb01a4bb0ba42f7f9dc766f..dd85b832b70f16b72f14e956bb52721ad47572c7 100644 (file)
@@ -275,10 +275,15 @@ function load (npm, conf, cb) {
 
       // at this point the configs are all set.
       // go ahead and spin up the registry client.
+      var token
+      try { token = JSON.parse(npm.config.get("_token")) }
+      catch (er) { token = null }
+
       npm.registry = new RegClient(
         { registry: npm.config.get("registry")
         , cache: npm.config.get("cache")
         , auth: npm.config.get("_auth")
+        , token: token
         , alwaysAuth: npm.config.get("always-auth")
         , email: npm.config.get("email")
         , proxy: npm.config.get("proxy")
@@ -293,8 +298,19 @@ function load (npm, conf, cb) {
         , retryFactor: npm.config.get("fetch-retry-factor")
         , retryMinTimeout: npm.config.get("fetch-retry-mintimeout")
         , retryMaxTimeout: npm.config.get("fetch-retry-maxtimeout")
+        , cacheMin: npm.config.get("cache-min")
+        , cacheMax: npm.config.get("cache-max")
         })
 
+      // save the token cookie in the config file
+      if (npm.registry.couchLogin) {
+        npm.registry.couchLogin.tokenSet = function (tok, cb) {
+          ini.set("_token", JSON.stringify(tok), "user")
+          // ignore save error.  best effort.
+          ini.save("user", function () {})
+        }
+      }
+
       var umask = parseInt(conf.umask, 8)
       npm.modes = { exec: 0777 & (~umask)
                   , file: 0666 & (~umask)
index 9a9c6425247e5aa64fd02d33cec244964a5c06dc..d741807e61606e1c660fe56a842d83972bfe92e4 100644 (file)
@@ -6,6 +6,9 @@ var testCmd = require("./utils/lifecycle.js").cmd("test")
 function test (args, cb) {
   testCmd(args, function (er) {
     if (!er) return cb()
-    return cb("Test failed.  See above for more details.")
+    if (er.code === "ELIFECYCLE") {
+      return cb("Test failed.  See above for more details.")
+    }
+    return cb(er)
   })
 }
index f1e004e4ad8761ca21d8bce466b31440b026485e..6042abc5282bd981b2c4fe0e75ee88b791353ece 100644 (file)
@@ -71,7 +71,6 @@ function makeRequest (remote, fstr, headers) {
 
   var opts = { url: remote
              , proxy: proxy
-             , follow: false
              , strictSSL: npm.config.get("strict-ssl")
              , ca: remote.host === regHost ? npm.config.get("ca") : undefined
              , headers: { "user-agent": npm.config.get("user-agent") }}
index 6e84ff43d61cc9ab4f3f8a6d17545b9bdec13802..1eae1dc7e3e54b490e0a58c91e2edbdf1d3317e2 100644 (file)
@@ -9,10 +9,10 @@
 .SH "SYNOPSIS"
 .
 .nf
-npm list
-npm ls
-npm la
-npm ll
+npm list [<pkg> \.\.\.]
+npm ls [<pkg> \.\.\.]
+npm la [<pkg> \.\.\.]
+npm ll [<pkg> \.\.\.]
 .
 .fi
 .
@@ -21,11 +21,24 @@ This command will print to stdout all the versions of packages that are
 installed, as well as their dependencies, in a tree\-structure\.
 .
 .P
-It does not take positional arguments, though you may set config flags
-like with any other command, such as \fB\-g\fR to list global packages\.
+Positional arguments are \fBname@version\-range\fR identifiers, which will
+limit the results to only the paths to the packages named\.  Note that
+nested packages will \fIalso\fR show the paths to the specified packages\.
+For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
+.
+.IP "" 4
+.
+.nf
+npm@1.1.39 /path/to/npm
+└─┬ init\-package\-json@0\.0\.4
+  â””── promzard@0\.1\.5
+.
+.fi
+.
+.IP "" 0
 .
 .P
-It will print out extraneous, missing, and invalid packages\.
+It will show print out extraneous, missing, and invalid packages\.
 .
 .P
 When run as \fBll\fR or \fBla\fR, it shows extended information by default\.
index a6129e0a99c6b5af096647576fc05b60c5bdc11a..f9e6d068cc324f5ef74e4e14a79664a768994dae 100644 (file)
@@ -14,7 +14,7 @@ npm <command> [args]
 .fi
 .
 .SH "VERSION"
-1.1.36
+1.1.39
 .
 .SH "DESCRIPTION"
 npm is the package manager for the Node JavaScript platform\.  It puts
index a6860c919948ea9e2c71aab012a1f5c55e87788e..3e0e3d016d0faabe6575b0abd7903b39eed86cb2 100644 (file)
@@ -21,7 +21,7 @@ npm\.load(configObject, function (er, npm) {
 .fi
 .
 .SH "VERSION"
-1.1.36
+1.1.39
 .
 .SH "DESCRIPTION"
 This is the API documentation for npm\.
diff --git a/deps/npm/node_modules/couch-login/README.md b/deps/npm/node_modules/couch-login/README.md
new file mode 100644 (file)
index 0000000..0b6c75d
--- /dev/null
@@ -0,0 +1,241 @@
+# couch-login
+
+This module lets you log into couchdb to get a session token, then make
+requests using that session.  It is basically just a thin wrapper around
+[@mikeal's request module](https://github.com/mikeal/request).
+
+This is handy if you want a user to take actions in a couchdb database
+on behalf of a user, without having to store their couchdb username and
+password anywhere.  (You do need to store the AuthSession token
+somewhere, though.)
+
+## Usage
+
+```javascript
+var CouchLogin = require('couch-login')
+
+// Nothing about this module is http-server specific of course.
+// You could also use it to do authenticated requests against
+// a couchdb using sessions and storing the token somewhere else.
+
+http.createServer(function (req, res) {
+  var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')
+
+  // .. look up the token in the user's session or whatever ..
+  // Look at couch.decorate(req, res) for more on doing that
+  // automatically, below.
+
+  if (sessionToken) {
+    // this user already logged in.
+    couch.token = sessionToken
+
+    // now we can do things on their behalf, like:
+    // 1. View their session info.
+    // like doing request.get({ uri: couch + '/_session', ... })
+    // but with the cookie and whatnot
+
+    couch.get('/_session', function (er, resp, data) {
+      // er = some kind of communication error.
+      // resp = response object from the couchdb request.
+      // data = parsed JSON response body.
+      if (er || resp.statusCode !== 200) {
+        res.statusCode = resp.statusCode || 403
+        return res.end('Invalid login or something')
+      }
+
+      // now we have the session info, we know who this user is.
+      // hitting couchdb for this on every request is kinda costly,
+      // so maybe you should store the username wherever you're storing
+      // the sessionToken.  RedSess is a good util for this, if you're
+      // into redis.  And if you're not into redis, you're crazy,
+      // because it is awesome.
+
+      // now let's get the user record.
+      // note that this will 404 for anyone other than the user,
+      // unless they're a server admin.
+      couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)
+
+      // PUTs and DELETEs will also use their session, of course, so
+      // your validate_doc_update's will see their info in userCtx
+    })
+
+  } else {
+    // don't have a sessionToken.
+    // get a username and password from the post body or something.
+    // maybe redirect to a /login page or something to ask for that.
+    var login = { name: name, password: password }
+    couch.login(login, function (er, resp, data) {
+      // again, er is an error, resp is the response obj, data is the json
+      if (er || resp.statusCode !== 200) {
+        res.statusCode = resp.statusCode || 403
+        return res.end('Invalid login or something')
+      }
+
+      // the data is something like
+      // {"ok":true,"name":"testuser","roles":[]}
+      // and couch.token is the token you'll need to save somewhere.
+
+      // at this point, you can start making authenticated requests to
+      // couchdb, or save data in their session, or do whatever it is
+      // that you need to do.
+
+      res.statusCode = 200
+      res.write("Who's got two thumbs and just logged you into couch?\n")
+      setTimeout(function () {
+        res.end("THIS GUY!")
+      }, 500)
+    })
+  }
+})
+```
+
+## Class: CouchLogin
+### new CouchLogin(couchdbUrl, token)
+
+Create a new CouchLogin object bound to the couchdb url.
+
+In addition to these, the `get`, `post`, `put`, and `del` methods all
+proxy to the associated method on [request](https://github.com/mikeal/request).
+
+However, as you'll note in the example above, only the pathname portion
+of the url is required.  Urls will be appended to the couchdb url passed
+into the constructor.
+
+If you have to talk to more than one couchdb, then you'll need more than
+one CouchLogin object, for somewhat obvious reasons.
+
+All callbacks get called with the following arguments, which are exactly
+identical to the arguments passed to a `request` callback.
+
+* `er` {Error | null} Set if a communication error happens.
+* `resp` {HTTP Response} The response from the request to couchdb
+* `data` {Object} The parsed JSON data from couch
+
+If the token is the string "anonymous", then it will not attempt to log
+in before making requests.  If the token is not "anonymous", then it
+must be an object with the appropriate fields.
+
+### couch.token
+
+* {Object}
+
+An object representing the couchdb session token.  (Basically just a
+cookie and a timeout.)
+
+If the token has already timed out, then setting it will have no effect.
+
+### couch.tokenSet
+
+If set, this method is called whenever the token is saved.
+
+For example, you could assign a function to this method to save the
+token into a redis session, a cookie, or in some other database.
+
+Takes a callback which should be called when the token is saved.
+
+### couch.tokenGet
+
+If set, this method is called to look up the token on demand.
+
+The inverse of couch.tokenSet.  Takes a callback which is called with
+the `cb(er || null, token)`.
+
+### couch.tokenDel
+
+If set, this method is called to delete the token when it should be
+discarded.
+
+Related to tokenGet and tokenSet.  Takes a callback which should be
+called when the token is deleted.
+
+### couch.anonymous()
+
+Return a new CouchLogin object that points at the same couchdb server,
+but doesn't try to log in before making requests.
+
+This is handy for situations where the user is not logged in at the
+moment, but a request needs to be made anyway, and does not require
+authorization.
+
+### couch.login(auth, callback)
+
+* `auth` {Object} The login details
+  * `name` {String}
+  * `password` {String}
+* `callback` {Function}
+
+When the callback is called, the `couch.token` will already have been
+set (assuming it worked!), so subsequent requests will be done as that
+user.
+
+### couch.get(path, callback)
+
+GET the supplied path from the couchdb using the credentials on the
+token.
+
+Fails if the token is invalid or expired.
+
+### couch.del(path, callback)
+
+DELETE the supplied path from the couchdb using the credentials on the
+token.
+
+Fails if the token is invalid or expired.
+
+### couch.post(path, data, callback)
+
+POST the data to the supplied path in the couchdb, using the credentials
+on the token.
+
+Fails if the token is invalid or expired.
+
+### couch.put(path, data, callback)
+
+PUT the data to the supplied path in the couchdb, using the credentials
+on the token.
+
+Fails if the token is invalid or expired.
+
+### couch.changePass(newAuth, callback)
+
+Must already be logged in.  Updates the `_users` document with new salt
+and hash, and re-logs in with the new credentials.  Callback is called
+with the same arguments as login, or the first step of the process that
+failed.
+
+### couch.signup(userData, callback)
+
+Create a new user account.  The userData must contain at least a `name`
+and `password` field.  Any additional data will be copied to the user
+record.  The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and
+`date` fields are generated.
+
+Also signs in as the newly created user, on successful account creation.
+
+### couch.deleteAccount(name, callback)
+
+Deletes a user account.  If not logged in as the user, or a server
+admin, then the request will fail.
+
+Note that this immediately invalidates any session tokens for the
+deleted user account.  If you are deleting the user's record, then you
+ought to follow this with `couch.logout(callback)` so that it won't try
+to re-use the invalid session.
+
+### couch.logout(callback)
+
+Delete the session out of couchdb.  This makes the token permanently
+invalid, and deletes it.
+
+### couch.decorate(req, res)
+
+Set up `req.couch` and `res.couch` as references to this couch login
+instance.
+
+Additionall, if `req.session` or `res.session` is set, then it'll call
+`session.get('couch_token', cb)` as the tokenGet method,
+`session.set('couch_token', token, cb)` as the tokenSet method, and
+`session.del('couch_token', cb)` as the tokenDel method.
+
+This works really nice with
+[RedSess](https://github.com/isaacs/redsess).
diff --git a/deps/npm/node_modules/couch-login/couch-login.js b/deps/npm/node_modules/couch-login/couch-login.js
new file mode 100644 (file)
index 0000000..d240da0
--- /dev/null
@@ -0,0 +1,287 @@
+var request = require('request')
+, url = require('url')
+, crypto = require('crypto')
+
+module.exports = CouchLogin
+
+function CouchLogin (couch, tok) {
+  if (!(this instanceof CouchLogin)) {
+    return new CouchLogin(couch)
+  }
+
+  if (!couch) throw new Error(
+    "Need to pass a couch url to CouchLogin constructor")
+
+  // having auth completely defeats the purpose
+  couch = url.parse(couch)
+  delete couch.auth
+
+  if (tok === 'anonymous') tok = NaN
+  this.token = tok
+  this.couch = url.format(couch)
+}
+
+CouchLogin.prototype =
+{ get: makeReq('GET')
+, del: makeReq('DELETE')
+, put: makeReq('PUT', true)
+, post: makeReq('POST', true)
+, login: login
+, logout: logout
+, decorate: decorate
+, changePass: changePass
+, signup: signup
+, deleteAccount: deleteAccount
+, anon: anon
+, anonymous: anon
+, valid: valid
+}
+
+Object.defineProperty(CouchLogin.prototype, 'constructor',
+  { value: CouchLogin, enumerable: false })
+
+function decorate (req, res) {
+  req.couch = res.couch = this
+
+  // backed by some sort of set(k,v,cb), get(k,cb) session storage.
+  var session = req.session || res.session || null
+  if (session) {
+    this.tokenGet = function (cb) {
+      session.get('couch_token', cb)
+    }
+
+    // don't worry about it failing.  it'll just mean a login next time.
+    this.tokenSet = function (tok, cb) {
+      session.set('couch_token', tok, cb || function () {})
+    }
+
+    this.tokenDel = function (cb) {
+      session.del('couch_token', cb || function () {})
+    }
+  }
+
+  return this
+}
+
+function anon () {
+  return new CouchLogin(this.couch, NaN)
+}
+
+function makeReq (meth, body, f) { return function madeReq (p, d, cb) {
+  f = f || (this.token !== this.token)
+  if (!f && !valid(this.token)) {
+    // lazily get the token.
+    if (this.tokenGet) return this.tokenGet(function (er, tok) {
+      if (er || !valid(tok)) {
+        if (!body) cb = d, d = null
+        return cb(new Error('auth token expired or invalid'))
+      }
+      this.token = tok
+      return madeReq.call(this, p, d, cb)
+    }.bind(this))
+
+    // no getter, no token, no business.
+    return process.nextTick(function () {
+      if (!body) cb = d, d = null
+      cb(new Error('auth token expired or invalid'))
+    })
+  }
+
+  if (!body) cb = d, d = null
+
+  var h = {}
+  , u = url.resolve(this.couch, p)
+  , req = { uri: u, headers: h, json: true, body: d, method: meth }
+
+  if (this.token) {
+    h.cookie = 'AuthSession=' + this.token.AuthSession
+  }
+
+  request(req, function (er, res, data) {
+    // update cookie.
+    if (er || res.statusCode !== 200) return cb(er, res, data)
+    addToken.call(this, res)
+    return cb(er, res, data)
+  }.bind(this))
+}}
+
+function login (auth, cb) {
+  var a = { name: auth.name, password: auth.password }
+  makeReq('post', true, true).call(this, '/_session', a, cb)
+}
+
+function changePass (auth, cb) {
+  if (!auth.name || !auth.password) return cb(new Error('invalid auth'))
+
+  var u = '/_users/org.couchdb.user:' + auth.name
+  this.get(u, function (er, res, data) {
+    if (er || res.statusCode !== 200) return cb(er, res, data)
+
+    // copy any other keys we're setting here.
+    // note that name, password_sha, salt, and date
+    // are all set explicitly below.
+    Object.keys(auth).filter(function (k) {
+      return k.charAt(0) !== '_'
+          && k !== 'password'
+          && k !== 'password_sha'
+          && k !== 'salt'
+    }).forEach(function (k) {
+      data[k] = auth[k]
+    })
+
+    var newSalt = crypto.randomBytes(30).toString('hex')
+    , newPass = auth.password
+    , newSha = sha(newPass + newSalt)
+
+    data.password_sha = newSha
+    data.salt = newSalt
+    data.date = new Date().toISOString()
+
+    this.put(u + '?rev=' + data._rev, data, function (er, res, data) {
+      if (er || res.statusCode >= 400) return cb(er, res, data)
+      this.login(auth, cb)
+    }.bind(this))
+  }.bind(this))
+}
+
+// They said that there should probably be a warning before
+// deleting the user's whole account, so here it is:
+//
+// WATCH OUT!
+function deleteAccount (name, cb) {
+  var u = '/_users/org.couchdb.user:' + name
+  this.get(u, thenPut.bind(this))
+
+  function thenPut (er, res, data) {
+    if (er || res.statusCode !== 200) {
+      return cb(er, res, data)
+    }
+
+    // user accts can't be just DELETE'd by non-admins
+    // so we take the existing doc and just slap a _deleted
+    // flag on it to fake it.  Works the same either way
+    // in couch.
+    data._deleted = true
+    this.put(u + '?rev=' + data._rev, data, cb)
+  }
+}
+
+
+
+function signup (auth, cb) {
+  if (this.token) return this.logout(function (er, res, data) {
+    if (er || res.statusCode !== 200) {
+      return cb(er, res, data)
+    }
+
+    if (this.token) {
+      return cb(new Error('failed to delete token'), res, data)
+    }
+
+    this.signup(auth, cb)
+  }.bind(this))
+
+  // make a new user record.
+  var newSalt = crypto.randomBytes(30).toString('hex')
+  , newSha = sha(auth.password + newSalt)
+  , user = { _id: 'org.couchdb.user:' + auth.name
+           , name: auth.name
+           , roles: []
+           , type: 'user'
+           , password_sha: newSha
+           , salt: newSalt
+           , date: new Date().toISOString() }
+
+  Object.keys(auth).forEach(function (k) {
+    if (k === 'name' || k === 'password') return
+    user[k] = auth[k]
+  })
+
+  var u = '/_users/' + user._id
+  makeReq('put', true, true).call(this, u, user, function (er, res, data) {
+    if (er || res.statusCode >= 400) {
+      return cb(er, res, data)
+    }
+
+    // it worked! log in as that user and get their record
+    this.login(auth, function (er, res, data) {
+      if (er || (res && res.statusCode >= 400) || data && data.error) {
+        return cb(er, res, data)
+      }
+      this.get(u, cb)
+    }.bind(this))
+  }.bind(this))
+}
+
+function addToken (res) {
+  // attach the token, if a new one was provided.
+  var sc = res.headers['set-cookie']
+  if (!sc) return
+  if (!Array.isArray(sc)) sc = [sc]
+
+  sc = sc.filter(function (c) {
+    return c.match(/^AuthSession=/)
+  })[0]
+
+  if (!sc.length) return
+
+  sc = sc.split(/\s*;\s*/).map(function (p) {
+    return p.split('=')
+  }).reduce(function (set, p) {
+    var k = p[0] === 'AuthSession' ? p[0] : p[0].toLowerCase()
+    , v = k === 'expires' ? Date.parse(p[1])
+        : p[1] === '' || p[1] === undefined ? true // HttpOnly
+        : p[1]
+    set[k] = v
+    return set
+  }, {})
+
+  if (sc.hasOwnProperty('max-age')) {
+    var ma = sc['max-age']
+    sc.expires = (ma <= 0) ? 0 : Date.now() + (ma * 1000)
+    delete sc['max-age']
+  }
+
+  this.token = sc
+  if (this.tokenSet) this.tokenSet(this.token)
+}
+
+
+function logout (cb) {
+  if (!this.token && this.tokenGet) {
+    return this.tokenGet(function (er, tok) {
+      if (er || !tok) return cb()
+      this.token = tok
+      this.logout(cb)
+    }.bind(this))
+  }
+
+  if (!valid(this.token)) {
+    this.token = null
+    if (this.tokenDel) this.tokenDel()
+    return process.nextTick(cb)
+  }
+
+  var h = { cookie: 'AuthSession=' + this.token.AuthSession }
+  , u = url.resolve(this.couch, '/_session')
+  , req = { uri: u, headers: h, json: true }
+
+  request.del(req, function (er, res, data) {
+    if (er || res.statusCode !== 200) {
+      return cb(er, res, data)
+    }
+
+    this.token = null
+    if (this.tokenDel) this.tokenDel()
+    cb(er, res, data)
+  }.bind(this))
+}
+
+function valid (token) {
+  var d = token && token.expires
+  return token && token.expires > Date.now()
+}
+
+function sha (s) {
+  return crypto.createHash("sha1").update(s).digest("hex")
+}
diff --git a/deps/npm/node_modules/couch-login/package.json b/deps/npm/node_modules/couch-login/package.json
new file mode 100644 (file)
index 0000000..f39660a
--- /dev/null
@@ -0,0 +1,27 @@
+{
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "i@izs.me",
+    "url": "http://blog.izs.me/"
+  },
+  "name": "couch-login",
+  "description": "A module for doing logged-in requests to a couchdb server",
+  "version": "0.1.6",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/couch-login.git"
+  },
+  "main": "couch-login.js",
+  "scripts": {
+    "test": "tap test/*.js"
+  },
+  "dependencies": {
+    "request": "~2.9.202"
+  },
+  "devDependencies": {
+    "tap": "~0.2.4"
+  },
+  "readme": "# couch-login\n\nThis module lets you log into couchdb to get a session token, then make\nrequests using that session.  It is basically just a thin wrapper around\n[@mikeal's request module](https://github.com/mikeal/request).\n\nThis is handy if you want a user to take actions in a couchdb database\non behalf of a user, without having to store their couchdb username and\npassword anywhere.  (You do need to store the AuthSession token\nsomewhere, though.)\n\n## Usage\n\n```javascript\nvar CouchLogin = require('couch-login')\n\n// Nothing about this module is http-server specific of course.\n// You could also use it to do authenticated requests against\n// a couchdb using sessions and storing the token somewhere else.\n\nhttp.createServer(function (req, res) {\n  var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')\n\n  // .. look up the token in the user's session or whatever ..\n  // Look at couch.decorate(req, res) for more on doing that\n  // automatically, below.\n\n  if (sessionToken) {\n    // this user already logged in.\n    couch.token = sessionToken\n\n    // now we can do things on their behalf, like:\n    // 1. View their session info.\n    // like doing request.get({ uri: couch + '/_session', ... })\n    // but with the cookie and whatnot\n\n    couch.get('/_session', function (er, resp, data) {\n      // er = some kind of communication error.\n      // resp = response object from the couchdb request.\n      // data = parsed JSON response body.\n      if (er || resp.statusCode !== 200) {\n        res.statusCode = resp.statusCode || 403\n        return res.end('Invalid login or something')\n      }\n\n      // now we have the session info, we know who this user is.\n      // hitting couchdb for this on every request is kinda costly,\n      // so maybe you should store the username wherever you're storing\n      // the sessionToken.  RedSess is a good util for this, if you're\n      // into redis.  And if you're not into redis, you're crazy,\n      // because it is awesome.\n\n      // now let's get the user record.\n      // note that this will 404 for anyone other than the user,\n      // unless they're a server admin.\n      couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)\n\n      // PUTs and DELETEs will also use their session, of course, so\n      // your validate_doc_update's will see their info in userCtx\n    })\n\n  } else {\n    // don't have a sessionToken.\n    // get a username and password from the post body or something.\n    // maybe redirect to a /login page or something to ask for that.\n    var login = { name: name, password: password }\n    couch.login(login, function (er, resp, data) {\n      // again, er is an error, resp is the response obj, data is the json\n      if (er || resp.statusCode !== 200) {\n        res.statusCode = resp.statusCode || 403\n        return res.end('Invalid login or something')\n      }\n\n      // the data is something like\n      // {\"ok\":true,\"name\":\"testuser\",\"roles\":[]}\n      // and couch.token is the token you'll need to save somewhere.\n\n      // at this point, you can start making authenticated requests to\n      // couchdb, or save data in their session, or do whatever it is\n      // that you need to do.\n\n      res.statusCode = 200\n      res.write(\"Who's got two thumbs and just logged you into couch?\\n\")\n      setTimeout(function () {\n        res.end(\"THIS GUY!\")\n      }, 500)\n    })\n  }\n})\n```\n\n## Class: CouchLogin\n### new CouchLogin(couchdbUrl, token)\n\nCreate a new CouchLogin object bound to the couchdb url.\n\nIn addition to these, the `get`, `post`, `put`, and `del` methods all\nproxy to the associated method on [request](https://github.com/mikeal/request).\n\nHowever, as you'll note in the example above, only the pathname portion\nof the url is required.  Urls will be appended to the couchdb url passed\ninto the constructor.\n\nIf you have to talk to more than one couchdb, then you'll need more than\none CouchLogin object, for somewhat obvious reasons.\n\nAll callbacks get called with the following arguments, which are exactly\nidentical to the arguments passed to a `request` callback.\n\n* `er` {Error | null} Set if a communication error happens.\n* `resp` {HTTP Response} The response from the request to couchdb\n* `data` {Object} The parsed JSON data from couch\n\nIf the token is the string \"anonymous\", then it will not attempt to log\nin before making requests.  If the token is not \"anonymous\", then it\nmust be an object with the appropriate fields.\n\n### couch.token\n\n* {Object}\n\nAn object representing the couchdb session token.  (Basically just a\ncookie and a timeout.)\n\nIf the token has already timed out, then setting it will have no effect.\n\n### couch.tokenSet\n\nIf set, this method is called whenever the token is saved.\n\nFor example, you could assign a function to this method to save the\ntoken into a redis session, a cookie, or in some other database.\n\nTakes a callback which should be called when the token is saved.\n\n### couch.tokenGet\n\nIf set, this method is called to look up the token on demand.\n\nThe inverse of couch.tokenSet.  Takes a callback which is called with\nthe `cb(er || null, token)`.\n\n### couch.tokenDel\n\nIf set, this method is called to delete the token when it should be\ndiscarded.\n\nRelated to tokenGet and tokenSet.  Takes a callback which should be\ncalled when the token is deleted.\n\n### couch.anonymous()\n\nReturn a new CouchLogin object that points at the same couchdb server,\nbut doesn't try to log in before making requests.\n\nThis is handy for situations where the user is not logged in at the\nmoment, but a request needs to be made anyway, and does not require\nauthorization.\n\n### couch.login(auth, callback)\n\n* `auth` {Object} The login details\n  * `name` {String}\n  * `password` {String}\n* `callback` {Function}\n\nWhen the callback is called, the `couch.token` will already have been\nset (assuming it worked!), so subsequent requests will be done as that\nuser.\n\n### couch.get(path, callback)\n\nGET the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.del(path, callback)\n\nDELETE the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.post(path, data, callback)\n\nPOST the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.put(path, data, callback)\n\nPUT the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.changePass(newAuth, callback)\n\nMust already be logged in.  Updates the `_users` document with new salt\nand hash, and re-logs in with the new credentials.  Callback is called\nwith the same arguments as login, or the first step of the process that\nfailed.\n\n### couch.signup(userData, callback)\n\nCreate a new user account.  The userData must contain at least a `name`\nand `password` field.  Any additional data will be copied to the user\nrecord.  The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and\n`date` fields are generated.\n\nAlso signs in as the newly created user, on successful account creation.\n\n### couch.deleteAccount(name, callback)\n\nDeletes a user account.  If not logged in as the user, or a server\nadmin, then the request will fail.\n\nNote that this immediately invalidates any session tokens for the\ndeleted user account.  If you are deleting the user's record, then you\nought to follow this with `couch.logout(callback)` so that it won't try\nto re-use the invalid session.\n\n### couch.logout(callback)\n\nDelete the session out of couchdb.  This makes the token permanently\ninvalid, and deletes it.\n\n### couch.decorate(req, res)\n\nSet up `req.couch` and `res.couch` as references to this couch login\ninstance.\n\nAdditionall, if `req.session` or `res.session` is set, then it'll call\n`session.get('couch_token', cb)` as the tokenGet method,\n`session.set('couch_token', token, cb)` as the tokenSet method, and\n`session.del('couch_token', cb)` as the tokenDel method.\n\nThis works really nice with\n[RedSess](https://github.com/isaacs/redsess).\n",
+  "_id": "couch-login@0.1.6",
+  "_from": "couch-login@~0.1.6"
+}
index ecbda31a5a5da09d3d33c39fcb3aea1864255bfb..856fc66bf7ea7dc2e75f919c62d48ce7910d68d0 100644 (file)
@@ -151,14 +151,6 @@ if (constants.hasOwnProperty('O_SYMLINK') &&
 }
 
 
-// lstat on windows, missing from early 0.5 versions
-// replacing with stat isn't quite perfect, but good enough to get by.
-if (process.platform === "win32" && !process.binding("fs").lstat) {
-  fs.lstat = fs.stat
-  fs.lstatSync = fs.statSync
-}
-
-
 // lutimes implementation, or no-op
 if (!fs.lutimes) {
   if (constants.hasOwnProperty("O_SYMLINK")) {
@@ -255,6 +247,22 @@ function chownErOk (er) {
 }
 
 
+// if lchmod/lchown do not exist, then make them no-ops
+if (!fs.lchmod) {
+  fs.lchmod = function (path, mode, cb) {
+    process.nextTick(cb)
+  }
+  fs.lchmodSync = function () {}
+}
+if (!fs.lchown) {
+  fs.lchown = function (path, uid, gid, cb) {
+    process.nextTick(cb)
+  }
+  fs.lchownSync = function () {}
+}
+
+
+
 
 // on Windows, A/V software can lock the directory, causing this
 // to fail with an EACCES or EPERM if the directory contains newly
index 757d3014c8614265c1e93ddd9a6f577f227c91fa..fe4de9e585ded594903a6340a69fd5439494e21a 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "graceful-fs",
   "description": "fs monkey-patching to avoid EMFILE and other problems",
-  "version": "1.1.8",
+  "version": "1.1.9",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-graceful-fs.git"
     "node": ">=0.4.0"
   },
   "devDependencies": {},
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
-  "_id": "graceful-fs@1.1.8",
-  "dependencies": {},
-  "optionalDependencies": {},
-  "_engineSupported": true,
-  "_npmVersion": "1.1.10",
-  "_nodeVersion": "v0.7.7-pre",
-  "_defaultsLoaded": true,
+  "readme": "Just like node's `fs` module, but it does an incremental back-off when\nEMFILE is encountered.\n\nUseful in asynchronous situations where one needs to try to open lots\nand lots of files.\n",
+  "_id": "graceful-fs@1.1.9",
   "_from": "graceful-fs@~1.1.1"
 }
index 7b7d6215011f99d9666618656e7afbb9bba5488e..1f0f2c0447f58bded26bb8f8f2eaf80c51ee3f22 100755 (executable)
@@ -25,8 +25,9 @@ if (prog.todo.length === 0) {
 }
 
 log.info('it worked if it ends with', 'ok')
+log.verbose('cli', process.argv)
 log.info('using', 'node-gyp@%s', prog.version)
-log.info('using', 'node@%s', process.versions.node)
+log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform, process.arch)
 
 
 /**
@@ -61,7 +62,7 @@ function run () {
   if (prog.todo.length === 0) {
     // done!
     completed = true
-    log.info('done', 'ok')
+    log.info('ok')
     return
   }
   var command = prog.todo.shift()
index c29b97e63c775f1f9de04debb4e4bc360216cc75..f38ec993a47364c171bef7e48819df45434b9eb2 100644 (file)
@@ -6,19 +6,20 @@ module.exports = exports = build
  */
 
 var fs = require('graceful-fs')
+  , rm = require('rimraf')
   , path = require('path')
   , glob = require('glob')
   , log = require('npmlog')
   , which = require('which')
   , mkdirp = require('mkdirp')
   , win = process.platform == 'win32'
-  , openbsd = process.platform == 'openbsd'
 
 exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
 
 function build (gyp, argv, callback) {
 
-  var makeCommand = openbsd ? 'gmake' : 'make'
+  var makeCommand = gyp.opts.make || process.env.MAKE
+    || (process.platform.indexOf('bsd') != -1 ? 'gmake' : 'make')
   var command = win ? 'msbuild' : makeCommand
     , buildDir = path.resolve('build')
     , configPath = path.resolve(buildDir, 'config.gypi')
@@ -216,7 +217,47 @@ function build (gyp, argv, callback) {
     if (signal) {
       return callback(new Error('`' + command + '` got signal: ' + signal))
     }
+    //symlinkNodeBinding()
     callback()
   }
 
+  function symlinkNodeBinding () {
+    var buildDir = path.join('build', buildType, '*.node')
+    log.verbose('globbing for files', buildDir)
+    glob(buildDir, function (err, nodeFiles) {
+      if (err) return callback(err)
+      function link () {
+        var file = nodeFiles.shift()
+        if (!file) {
+          // no more files to link... done!
+          return callback()
+        }
+        var dest = path.join('build', path.basename(file))
+        log.info('symlink', 'creating link %j pointing to %j', file, dest)
+        var rel = path.relative('build', file)
+        log.verbose('symlink data', rel)
+        fs.symlink(rel, dest, 'file', function (err) {
+          if (err) {
+            if (err.code === 'EEXIST') {
+              log.verbose('destination already exists; deleting', dest)
+              rm(dest, function (err) {
+                if (err) return callback(err)
+                log.verbose('delete successful; trying symlink again')
+                nodeFiles.unshift(file)
+                link()
+              })
+            } else {
+              callback(err)
+            }
+            return
+          }
+          // process the next file, if any
+          link()
+        })
+      }
+      // start linking
+      link()
+    })
+  }
+
 }
index 1cdd32037d8607810ab62b82396b12695ae2e9a0..3dbd418794516c8a9684f2e6481e76e66749d7bb 100644 (file)
@@ -47,7 +47,7 @@ function configure (gyp, argv, callback) {
   // We're gonna glob C:\python2*
   function guessPython () {
     log.verbose('could not find "' + python + '". guessing location')
-    var rootDir = process.env.HOMEDRIVE || process.env.SystemDrive || 'C:\\'
+    var rootDir = process.env.SystemDrive || 'C:\\'
     if (rootDir[rootDir.length - 1] !== '\\') {
       rootDir += '\\'
     }
@@ -72,11 +72,21 @@ function configure (gyp, argv, callback) {
       if (err) {
         return callback(err)
       }
+      log.verbose('check python version', '`python --version` returned: %j', stderr)
       var version = stderr.trim().replace(/[^\d\.]+/g, '')
-      if (semver.lt(version, '3.0.0')) {
+      var numDots = 0
+      version.replace(/\./g, function () {
+        numDots++
+      })
+      while (numDots < 2) {
+        version += '.0'
+        numDots++
+      }
+      log.verbose('check python version', 'using version %j to check', version)
+      if (semver.gte(version, '2.5.0') && semver.lt(version, '3.0.0')) {
         getNodeDir()
       } else {
-        failPython3()
+        failPythonVersion(version)
       }
     })
   }
@@ -86,10 +96,10 @@ function configure (gyp, argv, callback) {
           + '", you can set the PYTHON env variable.'))
   }
 
-  function failPython3 () {
+  function failPythonVersion (badVersion) {
     callback(new Error('Python executable "' + python
-          + '" is Python 3, which is not supported.\n'
-          + 'You can set the PYTHON env variable to point to a Python 2 interpreter.'))
+          + '" is v' + badVersion + ', which is not supported by gyp.\n'
+          + 'You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.'))
   }
 
   function getNodeDir () {
index 4932b8f3bf9cbfbb6001bb2efdc456df884c2352..2bcc72bf8bdfc83dd7c452141ab285067f728e3c 100644 (file)
@@ -8,6 +8,7 @@ exports.usage = 'Install node development files for the specified node version.'
  */
 
 var fs = require('graceful-fs')
+  , osenv = require('osenv')
   , tar = require('tar')
   , rm = require('rimraf')
   , path = require('path')
@@ -41,7 +42,7 @@ function install (gyp, argv, callback) {
 
   // Determine which node dev files version we are installing
   var versionStr = argv[0] || gyp.opts.target || process.version
-  log.verbose('install', 'input version string', versionStr)
+  log.verbose('install', 'input version string %j', versionStr)
 
   // parse the version to normalize and ensure it's valid
   var version = semver.parse(versionStr)
@@ -57,11 +58,16 @@ function install (gyp, argv, callback) {
     return callback(new Error('Minimum target version is `0.6.0` or greater. Got: ' + versionStr))
   }
 
-  // 0.x.y-pre versions are not published yet. Use previous release.
+  // 0.x.y-pre versions are not published yet and cannot be installed. Bail.
   if (version[5] === '-pre') {
-    version[3] = +version[3] - 1
-    version[5] = null
-    log.verbose('-pre version detected, adjusting patch version')
+    log.verbose('detected "pre" node version', versionStr)
+    if (gyp.opts.nodedir) {
+      log.verbose('--nodedir flag was passed; skipping install', gyp.opts.nodedir)
+      callback()
+    } else {
+      callback(new Error('"pre" versions of node cannot be installed, use the --nodedir flag instead'))
+    }
+    return
   }
 
   // flatten version into String
@@ -107,12 +113,11 @@ function install (gyp, argv, callback) {
     go()
   }
 
-  function download (url, onError) {
+  function download (url) {
     log.http('GET', url)
 
     var requestOpts = {
         uri: url
-      , onResponse: true
     }
 
     // basic support for a proxy server
@@ -124,7 +129,7 @@ function install (gyp, argv, callback) {
       log.verbose('proxy', proxyUrl)
       requestOpts.proxy = proxyUrl
     }
-    var req = request(requestOpts, onError)
+    var req = request(requestOpts)
     req.on('response', function (res) {
       log.http(res.statusCode, url)
     })
@@ -133,181 +138,210 @@ function install (gyp, argv, callback) {
 
   function go () {
 
-  log.verbose('ensuring nodedir is created', devDir)
+    log.verbose('ensuring nodedir is created', devDir)
 
-  // first create the dir for the node dev files
-  mkdir(devDir, function (err, created) {
-    if (err) return cb(err)
-
-    if (created) {
-      log.verbose('created nodedir', created)
-    }
+    // first create the dir for the node dev files
+    mkdir(devDir, function (err, created) {
+      if (err) {
+        if (err.code == 'EACCES') {
+          // this EACCES fallback is a workaround for npm's `sudo` behavior, where
+          // it drops the permissions before invoking any child processes (like
+          // node-gyp). So what happens is the "nobody" user doesn't have
+          // permission to create the dev dir. As a fallback, make the tmpdir() be
+          // the dev dir for this installation. This is not ideal, but at least
+          // the compilation will succeed...
+          gyp.devDir = path.resolve(osenv.tmpdir(), '.node-gyp')
+          log.warn(err.code, 'user "%s" does not have permission to create dev dir "%s"', osenv.user(), devDir)
+          log.warn(err.code, 'attempting to reinstall using temporary dev dir "%s"', gyp.devDir)
+          gyp.commands.install(argv, cb)
+        } else {
+          cb(err)
+        }
+        return
+      }
 
-    // now download the node tarball
-    var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz'
-      , badDownload = false
-      , extractCount = 0
-      , gunzip = zlib.createGunzip()
-      , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid })
-
-    // checks if a file to be extracted from the tarball is valid.
-    // only .h header files and the gyp files get extracted
-    function isValid () {
-      var name = this.path.substring(devDir.length + 1)
-      var isValid = valid(name)
-      if (name === '' && this.type === 'Directory') {
-        // the first directory entry is ok
-        return true
+      if (created) {
+        log.verbose('created nodedir', created)
       }
-      if (isValid) {
-        log.verbose('extracted file from tarball', name)
-        extractCount++
-      } else {
-        // invalid
-        log.silly('ignoring from tarball', name)
+
+      // now download the node tarball
+      var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz'
+        , badDownload = false
+        , extractCount = 0
+        , gunzip = zlib.createGunzip()
+        , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid })
+
+      // checks if a file to be extracted from the tarball is valid.
+      // only .h header files and the gyp files get extracted
+      function isValid () {
+        var name = this.path.substring(devDir.length + 1)
+        var isValid = valid(name)
+        if (name === '' && this.type === 'Directory') {
+          // the first directory entry is ok
+          return true
+        }
+        if (isValid) {
+          log.verbose('extracted file from tarball', name)
+          extractCount++
+        } else {
+          // invalid
+          log.silly('ignoring from tarball', name)
+        }
+        return isValid
       }
-      return isValid
-    }
 
-    gunzip.on('error', cb)
-    extracter.on('error', cb)
-    extracter.on('end', afterTarball)
+      gunzip.on('error', cb)
+      extracter.on('error', cb)
+      extracter.on('end', afterTarball)
 
-    // download the tarball, gunzip and extract!
-    var req = download(tarballUrl, downloadError)
-      .pipe(gunzip)
-      .pipe(extracter)
+      // download the tarball, gunzip and extract!
+      var req = download(tarballUrl)
 
-    // something went wrong downloading the tarball?
-    function downloadError (err, res) {
-      if (err || res.statusCode != 200) {
+      // something went wrong downloading the tarball?
+      req.on('error', function (err) {
         badDownload = true
-        cb(err || new Error(res.statusCode + ' status code downloading tarball'))
-      }
-    }
+        cb(err)
+      })
 
-    // invoked after the tarball has finished being extracted
-    function afterTarball () {
-      if (badDownload) return
-      if (extractCount === 0) {
-        return cb(new Error('There was a fatal problem while downloading/extracting the tarball'))
-      }
-      log.verbose('tarball', 'done parsing tarball')
-      var async = 0
+      req.on('close', function () {
+        if (extractCount === 0) {
+          cb(new Error('Connection closed while downloading tarball file'))
+        }
+      })
 
-      if (isLegacy) {
-        // copy over the files from the `legacy` dir
-        async++
-        copyLegacy(deref)
-      }
+      req.on('response', function (res) {
+        if (res.statusCode !== 200) {
+          badDownload = true
+          cb(new Error(res.statusCode + ' status code downloading tarball'))
+          return
+        }
+        // start unzipping and untaring
+        req.pipe(gunzip).pipe(extracter)
+      })
 
-      if (win) {
-        // need to download node.lib
-        async++
-        downloadNodeLib(deref)
-      }
+      // invoked after the tarball has finished being extracted
+      function afterTarball () {
+        if (badDownload) return
+        if (extractCount === 0) {
+          return cb(new Error('There was a fatal problem while downloading/extracting the tarball'))
+        }
+        log.verbose('tarball', 'done parsing tarball')
+        var async = 0
 
-      // write the "installVersion" file
-      async++
-      var installVersionPath = path.resolve(devDir, 'installVersion')
-      fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref)
+        if (isLegacy) {
+          // copy over the files from the `legacy` dir
+          async++
+          copyLegacy(deref)
+        }
 
-      if (async === 0) {
-        // no async tasks required
-        cb()
-      }
+        if (win) {
+          // need to download node.lib
+          async++
+          downloadNodeLib(deref)
+        }
 
-      function deref (err) {
-        if (err) return cb(err)
-        --async || cb()
-      }
-    }
+        // write the "installVersion" file
+        async++
+        var installVersionPath = path.resolve(devDir, 'installVersion')
+        fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref)
 
-    function copyLegacy (done) {
-      // legacy versions of node (< 0.8) require the legacy files to be copied
-      // over since they contain many bugfixes from the current node build system
-      log.verbose('legacy', 'copying "legacy" gyp configuration files for version', version)
+        if (async === 0) {
+          // no async tasks required
+          cb()
+        }
 
-      var legacyDir = path.resolve(__dirname, '..', 'legacy')
-      log.verbose('legacy', 'using "legacy" dir', legacyDir)
-      log.verbose('legacy', 'copying to "dev" dir', devDir)
+        function deref (err) {
+          if (err) return cb(err)
+          --async || cb()
+        }
+      }
 
-      var reader = fstream.Reader({ path: legacyDir, type: 'Directory' })
-      var writer = fstream.Writer({ path: devDir, type: 'Directory' })
+      function copyLegacy (done) {
+        // legacy versions of node (< 0.8) require the legacy files to be copied
+        // over since they contain many bugfixes from the current node build system
+        log.verbose('legacy', 'copying "legacy" gyp configuration files for version', version)
 
-      reader.on('entry', function onEntry (entry) {
-        log.verbose('legacy', 'reading entry:', entry.path)
-        entry.on('entry', onEntry)
-      })
+        var legacyDir = path.resolve(__dirname, '..', 'legacy')
+        log.verbose('legacy', 'using "legacy" dir', legacyDir)
+        log.verbose('legacy', 'copying to "dev" dir', devDir)
 
-      reader.on('error', done)
-      writer.on('error', done)
+        var reader = fstream.Reader({ path: legacyDir, type: 'Directory' })
+        var writer = fstream.Writer({ path: devDir, type: 'Directory' })
 
-      // Like `cp -rpf`
-      reader.pipe(writer)
+        reader.on('entry', function onEntry (entry) {
+          log.verbose('legacy', 'reading entry:', entry.path)
+          entry.on('entry', onEntry)
+        })
 
-      reader.on('end', done)
-    }
+        reader.on('error', done)
+        writer.on('error', done)
 
-    function downloadNodeLib (done) {
-      log.verbose('on Windows; need to download `node.lib`...')
-      var dir32 = path.resolve(devDir, 'ia32')
-        , dir64 = path.resolve(devDir, 'x64')
-        , nodeLibPath32 = path.resolve(dir32, 'node.lib')
-        , nodeLibPath64 = path.resolve(dir64, 'node.lib')
-        , nodeLibUrl32 = distUrl + '/v' + version + '/node.lib'
-        , nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib'
-
-      log.verbose('32-bit node.lib dir', dir32)
-      log.verbose('64-bit node.lib dir', dir64)
-      log.verbose('`node.lib` 32-bit url', nodeLibUrl32)
-      log.verbose('`node.lib` 64-bit url', nodeLibUrl64)
-
-      var async = 2
-      mkdir(dir32, function (err) {
-        if (err) return done(err)
-        log.verbose('streaming 32-bit node.lib to:', nodeLibPath32)
-
-        var req = download(nodeLibUrl32)
-        req.on('error', done)
-        req.on('response', function (res) {
-          if (res.statusCode !== 200) {
-            done(new Error(res.statusCode + ' status code downloading 32-bit node.lib'))
-          }
-        })
-        req.on('end', function () {
-          --async || done()
-        })
+        // Like `cp -rpf`
+        reader.pipe(writer)
 
-        var ws = fs.createWriteStream(nodeLibPath32)
-        ws.on('error', cb)
-        req.pipe(ws)
-      })
-      mkdir(dir64, function (err) {
-        if (err) return done(err)
-        log.verbose('streaming 64-bit node.lib to:', nodeLibPath64)
-
-        var req = download(nodeLibUrl64)
-        req.on('error', done)
-        req.on('response', function (res) {
-          if (res.statusCode !== 200) {
-            done(new Error(res.statusCode + ' status code downloading 64-bit node.lib'))
-          }
+        reader.on('end', done)
+      }
+
+      function downloadNodeLib (done) {
+        log.verbose('on Windows; need to download `node.lib`...')
+        var dir32 = path.resolve(devDir, 'ia32')
+          , dir64 = path.resolve(devDir, 'x64')
+          , nodeLibPath32 = path.resolve(dir32, 'node.lib')
+          , nodeLibPath64 = path.resolve(dir64, 'node.lib')
+          , nodeLibUrl32 = distUrl + '/v' + version + '/node.lib'
+          , nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib'
+
+        log.verbose('32-bit node.lib dir', dir32)
+        log.verbose('64-bit node.lib dir', dir64)
+        log.verbose('`node.lib` 32-bit url', nodeLibUrl32)
+        log.verbose('`node.lib` 64-bit url', nodeLibUrl64)
+
+        var async = 2
+        mkdir(dir32, function (err) {
+          if (err) return done(err)
+          log.verbose('streaming 32-bit node.lib to:', nodeLibPath32)
+
+          var req = download(nodeLibUrl32)
+          req.on('error', done)
+          req.on('response', function (res) {
+            if (res.statusCode !== 200) {
+              done(new Error(res.statusCode + ' status code downloading 32-bit node.lib'))
+              return
+            }
+
+            var ws = fs.createWriteStream(nodeLibPath32)
+            ws.on('error', cb)
+            req.pipe(ws)
+          })
+          req.on('end', function () {
+            --async || done()
+          })
         })
-        req.on('end', function () {
-          --async || done()
+        mkdir(dir64, function (err) {
+          if (err) return done(err)
+          log.verbose('streaming 64-bit node.lib to:', nodeLibPath64)
+
+          var req = download(nodeLibUrl64)
+          req.on('error', done)
+          req.on('response', function (res) {
+            if (res.statusCode !== 200) {
+              done(new Error(res.statusCode + ' status code downloading 64-bit node.lib'))
+              return
+            }
+
+            var ws = fs.createWriteStream(nodeLibPath64)
+            ws.on('error', cb)
+            req.pipe(ws)
+          })
+          req.on('end', function () {
+            --async || done()
+          })
         })
+      } // downloadNodeLib()
 
-        var ws = fs.createWriteStream(nodeLibPath64)
-        ws.on('error', cb)
-        req.pipe(ws)
-      })
-    }
-
-
-  })
+    }) // mkdir()
 
-  }
+  } // go()
 
   /**
    * Checks if a given filename is "valid" for this installation.
index 61e9dd1d76e6dea25192d8dff4b1e127a6307dc9..9b2282520dfdc3e3c929260f9b8447f16303901e 100644 (file)
@@ -72,16 +72,17 @@ proto.package = require('../package')
  */
 
 proto.configDefs = {
-    help: Boolean    // everywhere
-  , arch: String     // 'configure'
-  , debug: Boolean   // 'build'
+    help: Boolean     // everywhere
+  , arch: String      // 'configure'
+  , debug: Boolean    // 'build'
   , directory: String // bin
+  , make: String      // 'build'
   , msvs_version: String // 'configure'
-  , ensure: Boolean  // 'install'
-  , solution: String // 'build' (windows only)
-  , proxy: String // 'install'
-  , nodedir: String // 'configure'
-  , loglevel: String // everywhere
+  , ensure: Boolean   // 'install'
+  , solution: String  // 'build' (windows only)
+  , proxy: String     // 'install'
+  , nodedir: String   // 'configure'
+  , loglevel: String  // everywhere
 }
 
 /**
index f3fc6862936b3341ea128b10f22301f40e324dc5..07c9178041a38cbe291dca533b9998eb1d8247b0 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "node-gyp",
-  "description": "`node-gyp` is a cross-platform command-line tool written in Node.js for compiling",
+  "description": "Node.js native addon build tool",
   "keywords": [
     "native",
     "addon",
@@ -10,7 +10,7 @@
     "bindings",
     "gyp"
   ],
-  "version": "0.5.2",
+  "version": "0.5.8",
   "installVersion": 9,
   "author": {
     "name": "Nathan Rajlich",
@@ -34,6 +34,7 @@
     "mkdirp": "0.3",
     "nopt": "1",
     "npmlog": "0",
+    "osenv": "0",
     "request": "2.9",
     "rimraf": "2",
     "semver": "1",
@@ -44,9 +45,9 @@
     "node": ">= 0.6.0"
   },
   "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.2`][windows-python-v2.7.2] recommended, `v3.x.x` not yet supported)\n    * Microsoft Visual C++ ([Express][msvc] 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\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 * `build` - Invokes `make`/`msbuild.exe` and builds the native addon\n * `clean` - Removes any generated project files and the `out` dir\n * `configure` - Generates project build files for the current platform\n * `rebuild` - Runs \"clean\", \"configure\" and \"build\" all at once\n * `install` - Installs node development files for the given version.\n * `list` - Lists the currently installed node development file versions\n * `remove` - Removes a node development files for a given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;\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.2]: http://www.python.org/download/releases/2.7.2#download\n[msvc]: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express\n[win7sdk]: http://www.microsoft.com/download/en/details.aspx?displayLang=en&id=8279\n",
-  "_id": "node-gyp@0.5.2",
+  "_id": "node-gyp@0.5.8",
   "dist": {
-    "shasum": "7410e3dd9d950592ee80d09c7e5ef22286f79c0f"
+    "shasum": "2e6cdb28159c9bdd3fe484c7db81f119ee17e594"
   },
-  "_from": "node-gyp@0.5.2"
+  "_from": "node-gyp@~0.5"
 }
index 673789f9b07831da5c393f469c142889978d95d0..c7bc21efcb55b3c42d2bfa021a42810b63938f51 100644 (file)
@@ -6,24 +6,34 @@ module.exports = RegClient
 var fs = require('fs')
 , url = require('url')
 , path = require('path')
+, CouchLogin = require('couch-login')
 , npmlog
 
 try {
   npmlog = require("npmlog")
 } catch (er) {
   npmlog = { error: noop, warn: noop, info: noop,
-             verbose: noop, silly: noop, http: silly,
+             verbose: noop, silly: noop, http: noop,
              pause: noop, resume: noop }
 }
 
 function noop () {}
 
 function RegClient (options) {
-  // a registry url must be provided.
-  var registry = url.parse(options.registry)
-  if (!registry.protocol) throw new Error(
-    'Invalid registry: ' + registry.url)
-  this.registry = registry.href
+  // if provided, then the registry needs to be a url.
+  // if it's not provided, then we're just using the cache only.
+  var registry = options.registry
+  if (registry) {
+    registry = url.parse(registry)
+    if (!registry.protocol) throw new Error(
+      'Invalid registry: ' + registry.url)
+    this.registry = registry.href
+    if (this.registry.slice(-1) !== '/') {
+      this.registry += '/'
+    }
+  } else {
+    this.registry = null
+  }
 
   this.retries = options.retries || 2
   this.retryFactor = options.retryFactor || 10
@@ -41,7 +51,25 @@ function RegClient (options) {
     a = a.split(":")
     this.username = a.shift()
     this.password = a.join(":")
+  } else {
+    this.username = options.username
+    this.password = options.password
+
+    // if username and password are set, but auth isn't, use them.
+    if (this.username && this.password) {
+      var a = this.username + ":" + this.password
+      this.auth = new Buffer(a, "utf8").toString("base64")
+    }
+  }
+
+  if (this.auth && !this.alwaysAuth && this.registry) {
+    // if we're always authing, then we just send the
+    // user/pass on every thing.  otherwise, create a
+    // session, and use that.
+    this.token = options.token
+    this.couchLogin = new CouchLogin(this.registry, this.token)
   }
+
   this.email = options.email || null
   this.defaultTag = options.tag || "latest"
 
index b56fefcc6343d58743a4f290876b04d5e17bb82d..835eb4ce5169e7462343689d53a0bf5f0d76c0d7 100644 (file)
@@ -15,6 +15,8 @@ function get (uri, timeout, nofollow, staleOk, cb) {
   timeout = Math.min(timeout, this.cacheMax)
   timeout = Math.max(timeout, this.cacheMin)
 
+  if (!this.registry) timeout = Infinity
+
   if ( process.env.COMP_CWORD !== undefined
     && process.env.COMP_LINE !== undefined
     && process.env.COMP_POINT !== undefined
index 1c6eb35e116964da93059c7090b0824d71438df9..384b0d89d5344db7e2f182593b67f4193d510b24 100644 (file)
@@ -13,6 +13,9 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   if (typeof cb_ !== "function") cb_ = etag, etag = null
   if (typeof cb_ !== "function") cb_ = what, what = null
 
+  if (!this.registry) return cb(new Error(
+    "No registry url provided: " + method + " " + where))
+
   // Since there are multiple places where an error could occur,
   // don't let the cb be called more than once.
   var errState = null
@@ -29,11 +32,12 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   var registry = this.registry
 
   var adduserChange = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)\/-rev/
-    , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/
-    , authRequired = (what || this.alwaysAuth)
-                      && !where.match(adduserNew)
-                   || where.match(adduserChange)
-                   || method === "DELETE"
+  , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/
+  , nu = where.match(adduserNew)
+  , uc = where.match(adduserChange)
+  , isUpload = what || this.alwaysAuth
+  , isDel = method === "DELETE"
+  , authRequired = isUpload && !nu || uc || isDel
 
   // resolve to a full url on the registry
   if (!where.match(/^https?:\/\//)) {
@@ -58,20 +62,39 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   }
 
   var remote = url.parse(where)
-    , auth = authRequired && this.auth
-
-  if (authRequired && !auth && this.username && this.password) {
-    var a = this.username + ":" + this.password
-    a = new Buffer(a, "utf8").toString("base64")
-    auth = this.auth = a
+  , auth = this.auth
+
+  if (authRequired && !this.alwaysAuth) {
+    var couch = this.couchLogin
+    , token = couch && (this.token || couch.token)
+    , validToken = token && couch.valid(token)
+
+    if (!validToken) token = null
+    else this.token = token
+
+    if (couch && !token) {
+      // login to get a valid token
+      var a = { name: this.username, password: this.password }
+      var args = arguments
+      return this.couchLogin.login(a, function (er, cr, data) {
+        if (er || !couch.valid(couch.token)) {
+          er = er || new Error('login error')
+          return cb(er, cr, data)
+        }
+        this.token = this.couchLogin.token
+        return regRequest.call(this, method, where, what, etag, nofollow, cb_)
+      }.bind(this))
+    }
   }
 
-  if (authRequired && !auth) {
+  // now we either have a valid token, or an auth.
+
+  if (authRequired && !auth && !token) {
     return cb(new Error(
       "Cannot insert data into the registry without auth"))
   }
 
-  if (auth) {
+  if (auth && !token) {
     remote.auth = new Buffer(auth, "base64").toString("utf8")
   }
 
@@ -87,7 +110,7 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   operation.attempt(function (currentAttempt) {
     self.log.info("retry", "registry request attempt " + currentAttempt
         + " at " + (new Date()).toLocaleTimeString())
-    makeRequest.call(self, method, remote, where, what, etag, nofollow
+    makeRequest.call(self, method, remote, where, what, etag, nofollow, token
                      , function (er, parsed, raw, response) {
       // Only retry on 408, 5xx or no `response`.
       var statusCode = response && response.statusCode
@@ -101,7 +124,7 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   })
 }
 
-function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
+function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) {
   var cbCalled = false
   function cb () {
     if (cbCalled) return
@@ -112,7 +135,6 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
   var opts = { url: remote
              , method: method
              , ca: this.ca
-             , follow: false
              , strictSSL: this.strictSSL }
     , headers = opts.headers = {}
   if (etag) {
@@ -120,6 +142,10 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
     headers[method === "GET" ? "if-none-match" : "if-match"] = etag
   }
 
+  if (tok) {
+    headers.cookie = 'AuthSession=' + tok.AuthSession
+  }
+
   headers.accept = "application/json"
 
   headers["user-agent"] = this.userAgent
index 08ecd7ef965bc245dce793a81092097bf79cc654..47b6dc4b7f224cb9b555204b755d91d1cba0bc88 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "npm-registry-client",
   "description": "Client for the npm registry",
-  "version": "0.0.8",
+  "version": "0.0.10",
   "repository": {
     "url": "git://github.com/isaacs/npm-registry-client"
   },
@@ -24,6 +24,7 @@
     "mkdirp": "~0.3.3",
     "rimraf": "~2.0.1",
     "retry": "0.6.0",
+    "couch-login": "~0.1.6",
     "npmlog": ""
   },
   "devDependencies": {
@@ -34,6 +35,6 @@
   },
   "license": "BSD",
   "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(options)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n  // error is an error if there was a problem.\n  // data is the parsed data object\n  // raw is the json string\n  // res is the response from couch\n})\n```\n\n# Options\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `alwaysAuth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n  Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strictSSL` {Boolean} Whether or not to be strict with SSL\n  certificates.  Default = `true`\n* `userAgent` {String} User agent header to send.  Default =\n  `\"node/{process.version}\"`\n* `log` {Object} The logger to use.  Defaults to `require(\"npmlog\")` if\n  that works, otherwise logs are disabled.\n* `retries` {Number} Number of times to retry on GET failures.\n  Default=2\n* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10\n* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.\n  Default=10000 (10 seconds)\n* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n  Default=60000 (60 seconds)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body.  Objects\n  that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n  * `error` {Error | null}\n  * `data` {Object} the parsed data object\n  * `raw` {String} the json\n  * `res` {Response Object} response from couch\n\nMake a request to the registry.  All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n  before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n  to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder.  However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n  versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry.  When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment.  Mostly used by `client.publish()`.\n",
-  "_id": "npm-registry-client@0.0.8",
+  "_id": "npm-registry-client@0.0.10",
   "_from": "npm-registry-client@0"
 }
index e147c242b98fb18874aef586ee25c4bff1412c2f..c3b300038f4db5d0c759d7aaf957bcb38b6febf5 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "read-package-json",
-  "version": "0.0.12",
+  "version": "0.1.1",
   "author": {
     "name": "Isaac Z. Schlueter",
     "email": "i@izs.me",
@@ -31,6 +31,6 @@
     "graceful-fs": "~1.1.8"
   },
   "readme": "# read-package-json\n\nThis is the thing that npm uses to read package.json files.  It\nvalidates some stuff, and loads some default things.\n\nIt keeps a cache of the files you've read, so that you don't end\nup reading the same package.json file multiple times.\n\nNote that if you just want to see what's literally in the package.json\nfile, you can usually do `var data = require('some-module/package.json')`.\n\nThis module is basically only needed by npm, but it's handy to see what\nnpm will see when it looks at your package.\n\n## Usage\n\n```javascript\nvar readJson = require('read-package-json')\n\nreadJson('/path/to/package.json', function (er, data) {\n  if (er) {\n    console.error(\"There was an error reading the file\")\n    return\n  }\n\n  console.error('the package data is', data)\n}\n```\n\n## readJson(file, cb)\n\n* `file` {String} The path to the package.json file\n* `cb` {Function}\n\nReads the JSON file and does the things.\n\n## `package.json` Fields\n\nSee `man 5 package.json` or `npm help json`.\n\n## readJson.log\n\nBy default this is a reference to the `npmlog` module.  But if that\nmodule can't be found, then it'll be set to just a dummy thing that does\nnothing.\n\nReplace with your own `{log,warn,error}` object for fun loggy time.\n\n## readJson.extras(file, data, cb)\n\nRun all the extra stuff relative to the file, with the parsed data.\n\nModifies the data as it does stuff.  Calls the cb when it's done.\n\n## readJson.extraSet = [fn, fn, ...]\n\nArray of functions that are called by `extras`.  Each one receives the\narguments `fn(file, data, cb)` and is expected to call `cb(er, data)`\nwhen done or when an error occurs.\n\nOrder is indeterminate, so each function should be completely\nindependent.\n\nMix and match!\n\n## readJson.cache\n\nThe `lru-cache` object that readJson uses to not read the same file over\nand over again.  See\n[lru-cache](https://github.com/isaacs/node-lru-cache) for details.\n\n## Other Relevant Files Besides `package.json`\n\nSome other files have an effect on the resulting data object, in the\nfollowing ways:\n\n### `README?(.*)`\n\nIf there is a `README` or `README.*` file present, then npm will attach\na `readme` field to the data with the contents of this file.\n\nOwing to the fact that roughly 100% of existing node modules have\nMarkdown README files, it will generally be assumed to be Markdown,\nregardless of the extension.  Please plan accordingly.\n\n### `server.js`\n\nIf there is a `server.js` file, and there is not already a\n`scripts.start` field, then `scripts.start` will be set to `node\nserver.js`.\n\n### `AUTHORS`\n\nIf there is not already a `contributors` field, then the `contributors`\nfield will be set to the contents of the `AUTHORS` file, split by lines,\nand parsed.\n\n### `bindings.gyp`\n\nIf a bindings.gyp file exists, and there is not already a\n`scripts.install` field, then the `scripts.install` field will be set to\n`node-gyp rebuild`.\n\n### `wscript`\n\nIf a wscript file exists, and there is not already a `scripts.install`\nfield, then the `scripts.install` field will be set to `node-waf clean ;\nnode-waf configure build`.\n\nNote that the `bindings.gyp` file supercedes this, since node-waf has\nbeen deprecated in favor of node-gyp.\n\n### `index.js`\n\nIf the json file does not exist, but there is a `index.js` file\npresent instead, and that file has a package comment, then it will try\nto parse the package comment, and use that as the data instead.\n\nA package comment looks like this:\n\n```javascript\n/**package\n * { \"name\": \"my-bare-module\"\n * , \"version\": \"1.2.3\"\n * , \"description\": \"etc....\" }\n **/\n\n// or...\n\n/**package\n{ \"name\": \"my-bare-module\"\n, \"version\": \"1.2.3\"\n, \"description\": \"etc....\" }\n**/\n```\n\nThe important thing is that it starts with `/**package`, and ends with\n`**/`.  If the package.json file exists, then the index.js is not\nparsed.\n\n### `{directories.man}/*.[0-9]`\n\nIf there is not already a `man` field defined as an array of files or a\nsingle file, and\nthere is a `directories.man` field defined, then that directory will\nbe searched for manpages.\n\nAny valid manpages found in that directory will be assigned to the `man`\narray, and installed in the appropriate man directory at package install\ntime, when installed globally on a Unix system.\n\n### `{directories.bin}/*`\n\nIf there is not already a `bin` field defined as a string filename or a\nhash of `<name> : <filename>` pairs, then the `directories.bin`\ndirectory will be searched and all the files within it will be linked as\nexecutables at install time.\n\nWhen installing locally, npm links bins into `node_modules/.bin`, which\nis in the `PATH` environ when npm runs scripts.  When\ninstalling globally, they are linked into `{prefix}/bin`, which is\npresumably in the `PATH` environment variable.\n",
-  "_id": "read-package-json@0.0.12",
-  "_from": "read-package-json@0"
+  "_id": "read-package-json@0.1.1",
+  "_from": "read-package-json@~0.1.0"
 }
index ec3bf709b5d156265fb33bdf8468c1fd41408032..bb1c952628cf2a7730deaec08dfaba157c66f179 100644 (file)
@@ -223,7 +223,8 @@ function readmeDescription (file, data) {
 function readme (file, data, cb) {
                 if (data.readme) return cb(null, data);
                 var dir = path.dirname(file)
-                glob("README?(.*)", { cwd: dir }, function (er, files) {
+                var globOpts = { cwd: dir, nocase: true }
+                glob("README?(.*)", globOpts, function (er, files) {
                                 if (er) return cb(er);
                                 if (!files.length) return cb()
                                 var rm = path.resolve(dir, files[0])
@@ -340,6 +341,13 @@ function typoWarn (file, data) {
                 })
                 bugsTypoWarn(file, data)
                 scriptTypoWarn(file, data)
+                noreadmeWarn(file, data)
+}
+
+function noreadmeWarn (file, data) {
+                if (data.readme) return;
+                warn(file, data, "No README.md file found!")
+                data.readme = "ERROR: No README.md file found!"
 }
 
 function checkTypo (file, data, d) {
index 3ead8aac844b332b70d7a7650472d20d8fe87acc..1ef86b8362c56da526c8159c162bd44afea86b3f 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "version": "1.1.36",
+  "version": "1.1.39",
   "name": "npm",
   "publishConfig": {
     "proprietary-attribs": false
     "npmlog": "0",
     "ansi": "~0.1.2",
     "npm-registry-client": "0",
-    "read-package-json": "0",
+    "read-package-json": "~0.1.1",
     "read-installed": "0",
     "glob": "~3.1.9",
     "init-package-json": "0",
     "osenv": "0",
     "lockfile": ">=0.2",
-    "retry": "~0.6.0"
+    "retry": "~0.6.0",
+    "couch-login": "~0.1.6"
   },
   "bundleDependencies": [
     "semver",
     "init-package-json",
     "osenv",
     "lockfile",
-    "retry"
+    "retry",
+    "couch-login"
   ],
   "devDependencies": {
     "ronn": "https://github.com/isaacs/ronnjs/tarball/master",
     "tap": "~0.2.5"
   },
   "engines": {
-    "node": "0.6 || 0.7 || 0.8",
+    "node": ">0.6",
     "npm": "1"
   },
   "scripts": {