npm: Upgrade to v1.2.3
authorisaacs <i@izs.me>
Thu, 24 Jan 2013 17:06:31 +0000 (09:06 -0800)
committerisaacs <i@izs.me>
Thu, 24 Jan 2013 17:10:01 +0000 (09:10 -0800)
139 files changed:
deps/npm/AUTHORS
deps/npm/doc/api/npm.md
deps/npm/doc/cli/config.md
deps/npm/doc/cli/global.md [new file with mode: 0644]
deps/npm/doc/cli/index.md
deps/npm/doc/cli/rm.md [new file with mode: 0644]
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/dedupe.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/global.html [new file with mode: 0644]
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/ls.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/rm.html [new file with mode: 0644]
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/build.js
deps/npm/lib/cache.js
deps/npm/lib/dedupe.js
deps/npm/lib/install.js
deps/npm/lib/link.js
deps/npm/lib/outdated.js
deps/npm/lib/publish.js
deps/npm/lib/run-script.js
deps/npm/lib/uninstall.js
deps/npm/lib/unpublish.js
deps/npm/man/man1/config.1
deps/npm/man/man1/global.1
deps/npm/man/man1/index.1
deps/npm/man/man1/ls.1
deps/npm/man/man1/npm.1
deps/npm/man/man1/rm.1
deps/npm/man/man3/npm.3
deps/npm/node_modules/glob/glob.js
deps/npm/node_modules/glob/package.json
deps/npm/node_modules/glob/test/00-setup.js
deps/npm/node_modules/glob/test/bash-comparison.js
deps/npm/node_modules/glob/test/bash-results.json [new file with mode: 0644]
deps/npm/node_modules/glob/test/mark.js
deps/npm/node_modules/glob/test/pause-resume.js
deps/npm/node_modules/glob/test/root.js
deps/npm/node_modules/node-gyp/addon.gypi
deps/npm/node_modules/node-gyp/package.json
deps/npm/node_modules/npm-registry-client/README.md
deps/npm/node_modules/npm-registry-client/package.json
deps/npm/node_modules/npmconf/config-defs.js
deps/npm/node_modules/npmconf/package.json
deps/npm/node_modules/read-installed/package.json
deps/npm/node_modules/read-installed/read-installed.js
deps/npm/node_modules/rimraf/package.json
deps/npm/node_modules/rimraf/rimraf.js
deps/npm/package.json

index 4a5f1ef..4d964f4 100644 (file)
@@ -88,3 +88,5 @@ Ian Livingstone <ianl@cs.dal.ca>
 Patrick Pfeiffer <patrick@buzzle.at>
 Paul Miller <paul@paulmillr.com>
 seebees <seebees@gmail.com>
+Carl Lange <carl@flax.ie>
+Jan Lehnardt <jan@apache.org>
index a2f034c..8c7a816 100644 (file)
@@ -4,7 +4,7 @@ npm(3) -- node package manager
 ## SYNOPSIS
 
     var npm = require("npm")
-    npm.load(configObject, function (er, npm) {
+    npm.load([configObject,] function (er, npm) {
       // use the npm object, now that it's loaded.
 
       npm.config.set(key, val)
@@ -25,12 +25,13 @@ This is the API documentation for npm.
 To find documentation of the command line
 client, see `npm(1)`.
 
-Prior to using npm's commands,
-`npm.load()` must be called with an object hash of
-top-level configs.  In the npm command line client,
-this set of configs is parsed from the command line options.  Additional
-configuration params are loaded from two configuration files.  See
-`npm-config(1)` for more information.
+Prior to using npm's commands, `npm.load()` must be called.
+If you provide `configObject` as an object hash of top-level
+configs, they override the values stored in the various config
+locations. In the npm command line client, this set of configs
+is parsed from the command line options. Additional configuration
+params are loaded from two configuration files. See `npm-config(1)`
+for more information.
 
 After that, each of the functions are accessible in the
 commands object: `npm.commands.<cmd>`.  See `npm-index(1)` for a list of
index 9f051a0..626a2e8 100644 (file)
@@ -398,7 +398,7 @@ A proxy to use for outgoing https requests.
 
 ### user-agent
 
-* Default: npm/{npm.version} node/{process.version}
+* Default: node/{process.version} {process.platform} {process.arch}
 * Type: String
 
 Sets a User-Agent to the request header
diff --git a/deps/npm/doc/cli/global.md b/deps/npm/doc/cli/global.md
new file mode 100644 (file)
index 0000000..2035861
--- /dev/null
@@ -0,0 +1,209 @@
+npm-folders(1) -- Folder Structures Used by npm
+===============================================
+
+## DESCRIPTION
+
+npm puts various things on your computer.  That's its job.
+
+This document will tell you what it puts where.
+
+### tl;dr
+
+* Local install (default): puts stuff in `./node_modules` of the current
+  package root.
+* Global install (with `-g`): puts stuff in /usr/local or wherever node
+  is installed.
+* Install it **locally** if you're going to `require()` it.
+* Install it **globally** if you're going to run it on the command line.
+* If you need both, then install it in both places, or use `npm link`.
+
+### prefix Configuration
+
+The `prefix` config defaults to the location where node is installed.
+On most systems, this is `/usr/local`, and most of the time is the same
+as node's `process.installPrefix`.
+
+On windows, this is the exact location of the node.exe binary.  On Unix
+systems, it's one level up, since node is typically installed at
+`{prefix}/bin/node` rather than `{prefix}/node.exe`.
+
+When the `global` flag is set, npm installs things into this prefix.
+When it is not set, it uses the root of the current package, or the
+current working directory if not in a package already.
+
+### Node Modules
+
+Packages are dropped into the `node_modules` folder under the `prefix`.
+When installing locally, this means that you can
+`require("packagename")` to load its main module, or
+`require("packagename/lib/path/to/sub/module")` to load other modules.
+
+Global installs on Unix systems go to `{prefix}/lib/node_modules`.
+Global installs on Windows go to `{prefix}/node_modules` (that is, no
+`lib` folder.)
+
+If you wish to `require()` a package, then install it locally.
+
+### Executables
+
+When in global mode, executables are linked into `{prefix}/bin` on Unix,
+or directly into `{prefix}` on Windows.
+
+When in local mode, executables are linked into
+`./node_modules/.bin` so that they can be made available to scripts run
+through npm.  (For example, so that a test runner will be in the path
+when you run `npm test`.)
+
+### Man Pages
+
+When in global mode, man pages are linked into `{prefix}/share/man`.
+
+When in local mode, man pages are not installed.
+
+Man pages are not installed on Windows systems.
+
+### Cache
+
+See `npm-cache(1)`.  Cache files are stored in `~/.npm` on Posix, or
+`~/npm-cache` on Windows.
+
+This is controlled by the `cache` configuration param.
+
+### Temp Files
+
+Temporary files are stored by default in the folder specified by the
+`tmp` config, which defaults to the TMPDIR, TMP, or TEMP environment
+variables, or `/tmp` on Unix and `c:\windows\temp` on Windows.
+
+Temp files are given a unique folder under this root for each run of the
+program, and are deleted upon successful exit.
+
+## More Information
+
+When installing locally, npm first tries to find an appropriate
+`prefix` folder.  This is so that `npm install foo@1.2.3` will install
+to the sensible root of your package, even if you happen to have `cd`ed
+into some other folder.
+
+Starting at the $PWD, npm will walk up the folder tree checking for a
+folder that contains either a `package.json` file, or a `node_modules`
+folder.  If such a thing is found, then that is treated as the effective
+"current directory" for the purpose of running npm commands.  (This
+behavior is inspired by and similar to git's .git-folder seeking
+logic when running git commands in a working dir.)
+
+If no package root is found, then the current folder is used.
+
+When you run `npm install foo@1.2.3`, then the package is loaded into
+the cache, and then unpacked into `./node_modules/foo`.  Then, any of
+foo's dependencies are similarly unpacked into
+`./node_modules/foo/node_modules/...`.
+
+Any bin files are symlinked to `./node_modules/.bin/`, so that they may
+be found by npm scripts when necessary.
+
+### Global Installation
+
+If the `global` configuration is set to true, then npm will
+install packages "globally".
+
+For global installation, packages are installed roughly the same way,
+but using the folders described above.
+
+### Cycles, Conflicts, and Folder Parsimony
+
+Cycles are handled using the property of node's module system that it
+walks up the directories looking for `node_modules` folders.  So, at every
+stage, if a package is already installed in an ancestor `node_modules`
+folder, then it is not installed at the current location.
+
+Consider the case above, where `foo -> bar -> baz`.  Imagine if, in
+addition to that, baz depended on bar, so you'd have:
+`foo -> bar -> baz -> bar -> baz ...`.  However, since the folder
+structure is: `foo/node_modules/bar/node_modules/baz`, there's no need to
+put another copy of bar into `.../baz/node_modules`, since when it calls
+require("bar"), it will get the copy that is installed in
+`foo/node_modules/bar`.
+
+This shortcut is only used if the exact same
+version would be installed in multiple nested `node_modules` folders.  It
+is still possible to have `a/node_modules/b/node_modules/a` if the two
+"a" packages are different versions.  However, without repeating the
+exact same package multiple times, an infinite regress will always be
+prevented.
+
+Another optimization can be made by installing dependencies at the
+highest level possible, below the localized "target" folder.
+
+#### Example
+
+Consider this dependency graph:
+
+    foo
+    +-- blerg@1.2.5
+    +-- bar@1.2.3
+    |   +-- blerg@1.x (latest=1.3.7)
+    |   +-- baz@2.x
+    |   |   `-- quux@3.x
+    |   |       `-- bar@1.2.3 (cycle)
+    |   `-- asdf@*
+    `-- baz@1.2.3
+        `-- quux@3.x
+            `-- bar
+
+In this case, we might expect a folder structure like this:
+
+    foo
+    +-- node_modules
+        +-- blerg (1.2.5) <---[A]
+        +-- bar (1.2.3) <---[B]
+        |   +-- node_modules
+        |   |   `-- baz (2.0.2) <---[C]
+        |   |       `-- node_modules
+        |   |           `-- quux (3.2.0)
+        |   `-- asdf (2.3.4)
+        `-- baz (1.2.3) <---[D]
+            `-- node_modules
+                `-- quux (3.2.0) <---[E]
+
+Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are
+installed in foo's `node_modules` folder.
+
+Even though the latest copy of blerg is 1.3.7, foo has a specific
+dependency on version 1.2.5.  So, that gets installed at [A].  Since the
+parent installation of blerg satisfie's bar's dependency on blerg@1.x,
+it does not install another copy under [B].
+
+Bar [B] also has dependencies on baz and asdf, so those are installed in
+bar's `node_modules` folder.  Because it depends on `baz@2.x`, it cannot
+re-use the `baz@1.2.3` installed in the parent `node_modules` folder [D],
+and must install its own copy [C].
+
+Underneath bar, the `baz->quux->bar` dependency creates a cycle.
+However, because `bar` is already in `quux`'s ancestry [B], it does not
+unpack another copy of bar into that folder.
+
+Underneath `foo->baz` [D], quux's [E] folder tree is empty, because its
+dependency on bar is satisfied by the parent folder copy installed at [B].
+
+For a graphical breakdown of what is installed where, use `npm ls`.
+
+### Publishing
+
+Upon publishing, npm will look in the `node_modules` folder.  If any of
+the items there are not in the `bundledDependencies` array, then they will
+not be included in the package tarball.
+
+This allows a package maintainer to install all of their dependencies
+(and dev dependencies) locally, but only re-publish those items that
+cannot be found elsewhere.  See `npm-json(1)` for more information.
+
+## SEE ALSO
+
+* npm-faq(1)
+* npm-json(1)
+* npm-install(1)
+* npm-pack(1)
+* npm-cache(1)
+* npm-config(1)
+* npm-publish(1)
index f8fde25..04852ce 100644 (file)
@@ -82,6 +82,10 @@ npm-index(1) -- Index of all npm documentation
 
  Folder Structures Used by npm
 
+## npm-global(1)
+
+ Folder Structures Used by npm
+
 ## npm-help-search(1)
 
  Search npm help documentation
@@ -154,6 +158,10 @@ npm-index(1) -- Index of all npm documentation
 
  Start a package
 
+## npm-rm(1)
+
+ Remove a package
+
 ## npm-root(1)
 
  Display npm root
diff --git a/deps/npm/doc/cli/rm.md b/deps/npm/doc/cli/rm.md
new file mode 100644 (file)
index 0000000..f7f743f
--- /dev/null
@@ -0,0 +1,19 @@
+npm-rm(1) -- Remove a package
+=============================
+
+## SYNOPSIS
+
+    npm rm <name>
+    npm uninstall <name>
+
+## DESCRIPTION
+
+This uninstalls a package, completely removing everything npm installed
+on its behalf.
+
+## SEE ALSO
+
+* npm-prune(1)
+* npm-install(1)
+* npm-folders(1)
+* npm-config(1)
index 15168f2..4e7d490 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.2.2</p>
+<p id="footer">bin &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3ed4011..e1c9e57 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.2.2</p>
+<p id="footer">bugs &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 789ea04..f182ecf 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.2.2</p>
+<p id="footer">commands &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 62f256f..d4c8874 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.2.2</p>
+<p id="footer">config &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c3b0244..fbc49ad 100644 (file)
@@ -32,7 +32,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.2.2</p>
+<p id="footer">deprecate &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1a13aaf..a8c2168 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.2.2</p>
+<p id="footer">docs &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1f1d178..332a760 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.2.2</p>
+<p id="footer">edit &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 77e5b8e..937fd2f 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 &#39;args&#39; 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.2.2</p>
+<p id="footer">explore &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a2f3c70..ba94b4f 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.2.2</p>
+<p id="footer">help-search &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 39dc68d..25a5f83 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.2.2</p>
+<p id="footer">init &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3ad0f7a..d7a1715 100644 (file)
@@ -25,7 +25,7 @@ the name of a package to be installed.</p>
 <p>Finally, &#39;callback&#39; 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.2.2</p>
+<p id="footer">install &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4209687..d72c213 100644 (file)
@@ -39,7 +39,7 @@ npm.commands.link(&#39;redis&#39;, 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.2.2</p>
+<p id="footer">link &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 02d20ad..1eca8e9 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.2.2</p>
+<p id="footer">load &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3029db2..380c9c4 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.2.2</p>
+<p id="footer">ls &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b761b6f..aa49fe3 100644 (file)
@@ -11,7 +11,7 @@
 <h2 id="SYNOPSIS">SYNOPSIS</h2>
 
 <pre><code>var npm = require(&quot;npm&quot;)
-npm.load(configObject, function (er, npm) {
+npm.load([configObject,] function (er, npm) {
   // use the npm object, now that it&#39;s loaded.
 
   npm.config.set(key, val)
@@ -24,7 +24,7 @@ npm.load(configObject, function (er, npm) {
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.2.2</p>
+<p>1.2.3</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -32,12 +32,13 @@ npm.load(configObject, function (er, npm) {
 To find documentation of the command line
 client, see <code><a href="../doc/npm.html">npm(1)</a></code>.</p>
 
-<p>Prior to using npm&#39;s commands,
-<code>npm.load()</code> must be called with an object hash of
-top-level configs.  In the npm command line client,
-this set of configs is parsed from the command line options.  Additional
-configuration params are loaded from two configuration files.  See
-<code><a href="../doc/config.html">config(1)</a></code> for more information.</p>
+<p>Prior to using npm&#39;s commands, <code>npm.load()</code> must be called.
+If you provide <code>configObject</code> as an object hash of top-level
+configs, they override the values stored in the various config
+locations. In the npm command line client, this set of configs
+is parsed from the command line options. Additional configuration
+params are loaded from two configuration files. See <code><a href="../doc/config.html">config(1)</a></code>
+for more information.</p>
 
 <p>After that, each of the functions are accessible in the
 commands object: <code>npm.commands.&lt;cmd&gt;</code>.  See <code><a href="../doc/index.html">index(1)</a></code> for a list of
@@ -91,7 +92,7 @@ method names.  Use the <code>npm.deref</code> method to find the real name.</p>
 
 <pre><code>var cmd = npm.deref(&quot;unp&quot;) // cmd === &quot;unpublish&quot;</code></pre>
 </div>
-<p id="footer">npm &mdash; npm@1.2.2</p>
+<p id="footer">npm &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b27dd86..ff699f4 100644 (file)
@@ -19,7 +19,7 @@ currently outdated.</p>
 
 <p>If the &#39;packages&#39; parameter is left out, npm will check all packages.</p>
 </div>
-<p id="footer">outdated &mdash; npm@1.2.2</p>
+<p id="footer">outdated &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index eedbed3..d587ae7 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.2.2</p>
+<p id="footer">owner &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6f60696..aab872a 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.2.2</p>
+<p id="footer">pack &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9bfb96e..0a91cf5 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">prefix &mdash; npm@1.2.2</p>
+<p id="footer">prefix &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cf0f067..a550851 100644 (file)
@@ -23,7 +23,7 @@
 <p>Extraneous packages are packages that are not listed on the parent
 package&#39;s dependencies list.</p>
 </div>
-<p id="footer">prune &mdash; npm@1.2.2</p>
+<p id="footer">prune &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 71e9060..159310a 100644 (file)
@@ -32,7 +32,7 @@ the registry.  Overwrites when the &quot;force&quot; environment variable is set
 
 <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.2.2</p>
+<p id="footer">publish &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e9b6e61..72cd8e1 100644 (file)
@@ -22,7 +22,7 @@ the new binary. If no &#39;packages&#39; parameter is specify, every package wil
 
 <p>See <code>npm help build</code></p>
 </div>
-<p id="footer">rebuild &mdash; npm@1.2.2</p>
+<p id="footer">rebuild &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 54801f1..7b1233c 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.2.2</p>
+<p id="footer">restart &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c88eac9..368f990 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically.</p>
 </div>
-<p id="footer">root &mdash; npm@1.2.2</p>
+<p id="footer">root &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6551e50..4b25884 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.2.2</p>
+<p id="footer">run-script &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 811b2f8..0bfaef3 100644 (file)
@@ -32,7 +32,7 @@ excluded term (the &quot;searchexclude&quot; config). The search is case insensi
 and doesn&#39;t try to read your mind (it doesn&#39;t do any verb tense matching or the
 like).</p>
 </div>
-<p id="footer">search &mdash; npm@1.2.2</p>
+<p id="footer">search &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7267240..3a8f3d9 100644 (file)
@@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p>
 <p>Finally, &#39;callback&#39; is a function that will be called when the shrinkwrap has
 been saved.</p>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.2.2</p>
+<p id="footer">shrinkwrap &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5b3aafe..4021aa8 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.2.2</p>
+<p id="footer">start &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b95ef54..f34ef5f 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.2.2</p>
+<p id="footer">stop &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cf2fda8..fd7263a 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.2.2</p>
+<p id="footer">submodule &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3ce716e..e3dfe01 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.2.2</p>
+<p id="footer">tag &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b4c41ca..2290370 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.2.2</p>
+<p id="footer">test &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7c86d6b..eebcce9 100644 (file)
@@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p>
 <p>Finally, &#39;callback&#39; 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.2.2</p>
+<p id="footer">uninstall &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7a9a507..d05fbb3 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.2.2</p>
+<p id="footer">unpublish &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 52894e6..1f24855 100644 (file)
@@ -18,7 +18,7 @@
 
 <p>The &#39;packages&#39; argument is an array of packages to update. The &#39;callback&#39; parameter will be called when done or when an error occurs.</p>
 </div>
-<p id="footer">update &mdash; npm@1.2.2</p>
+<p id="footer">update &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 717950b..9c3577c 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.2.2</p>
+<p id="footer">version &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c8547f2..f4f5b7a 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.2.2</p>
+<p id="footer">view &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5110105..ca8d6ee 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">whoami &mdash; npm@1.2.2</p>
+<p id="footer">whoami &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 87960d4..c098cab 100644 (file)
@@ -240,7 +240,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.2.2</p>
+<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 701242c..764f9b3 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.2.2</p>
+<p id="footer">adduser &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 247a8f2..ef92187 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.2.2</p>
+<p id="footer">bin &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ee0c256..ab398d2 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.2.2</p>
+<p id="footer">bugs &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 46ae979..b5b9959 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.2.2</p>
+<p id="footer">build &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fa6a05d..5a7f618 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.2.2</p>
+<p id="footer">bundle &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5e2cf71..6c799ed 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.2.2</p>
+<p id="footer">cache &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0b0c1ae..0a078f0 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.2.2</p>
+<p id="footer">changelog &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dc1e30b..f13118a 100644 (file)
@@ -182,7 +182,7 @@ set to anything.&quot;</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.2.2</p>
+<p id="footer">coding-style &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 23b5318..09a08fd 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.2.2</p>
+<p id="footer">completion &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 43604e1..92b97ae 100644 (file)
@@ -352,7 +352,7 @@ user.</p>
 
 <h3 id="user-agent">user-agent</h3>
 
-<ul><li>Default: npm/{npm.version} node/{process.version}</li><li>Type: String</li></ul>
+<ul><li>Default: node/{process.version} {process.platform} {process.arch}</li><li>Type: String</li></ul>
 
 <p>Sets a User-Agent to the request header</p>
 
@@ -756,7 +756,7 @@ then answer &quot;no&quot; 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.2.2</p>
+<p id="footer">config &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a921cd6..b979f40 100644 (file)
@@ -57,7 +57,7 @@ registry.</p>
 
 <ul><li><a href="../doc/ls.html">ls(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">dedupe &mdash; npm@1.2.2</p>
+<p id="footer">dedupe &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c461327..6363fff 100644 (file)
@@ -31,7 +31,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.2.2</p>
+<p id="footer">deprecate &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 450ddca..88e3908 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.2.2</p>
+<p id="footer">developers &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 43a9da1..7f2cc90 100644 (file)
@@ -86,7 +86,7 @@ an empty tarball, you&#39;re going to be evicted.</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.2.2</p>
+<p id="footer">disputes &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 02663c0..1bb55dc 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.2.2</p>
+<p id="footer">docs &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9a89749..ab1e572 100644 (file)
@@ -37,7 +37,7 @@ or <code>&quot;notepad&quot;</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.2.2</p>
+<p id="footer">edit &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0b7f3ef..9bca0df 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.2.2</p>
+<p id="footer">explore &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4cc7000..d147705 100644 (file)
@@ -250,7 +250,7 @@ There is not sufficient need to impose namespace rules on everyone.</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.2.2</p>
+<p id="footer">faq &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7868c2f..86ca644 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.2.2</p>
+<p id="footer">folders &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/global.html b/deps/npm/html/doc/global.html
new file mode 100644 (file)
index 0000000..0512c9e
--- /dev/null
@@ -0,0 +1,240 @@
+<!doctype html>
+<html>
+  <title>global</title>
+  <meta http-equiv="content-type" value="text/html;utf-8">
+  <link rel="stylesheet" type="text/css" href="../static/style.css">
+
+  <body>
+    <div id="wrapper">
+<h1><a href="../doc/folders.html">folders</a></h1> <p>Folder Structures Used by npm</p>
+
+<h2 id="DESCRIPTION">DESCRIPTION</h2>
+
+<p>npm puts various things on your computer.  That&#39;s its job.</p>
+
+<p>This document will tell you what it puts where.</p>
+
+<h3 id="tl-dr">tl;dr</h3>
+
+<ul><li>Local install (default): puts stuff in <code>./node_modules</code> of the current
+package root.</li><li>Global install (with <code>-g</code>): puts stuff in /usr/local or wherever node
+is installed.</li><li>Install it <strong>locally</strong> if you&#39;re going to <code>require()</code> it.</li><li>Install it <strong>globally</strong> if you&#39;re going to run it on the command line.</li><li>If you need both, then install it in both places, or use <code>npm link</code>.</li></ul>
+
+<h3 id="prefix-Configuration">prefix Configuration</h3>
+
+<p>The <code>prefix</code> config defaults to the location where node is installed.
+On most systems, this is <code>/usr/local</code>, and most of the time is the same
+as node&#39;s <code>process.installPrefix</code>.</p>
+
+<p>On windows, this is the exact location of the node.exe binary.  On Unix
+systems, it&#39;s one level up, since node is typically installed at
+<code>{prefix}/bin/node</code> rather than <code>{prefix}/node.exe</code>.</p>
+
+<p>When the <code>global</code> flag is set, npm installs things into this prefix.
+When it is not set, it uses the root of the current package, or the
+current working directory if not in a package already.</p>
+
+<h3 id="Node-Modules">Node Modules</h3>
+
+<p>Packages are dropped into the <code>node_modules</code> folder under the <code>prefix</code>.
+When installing locally, this means that you can
+<code>require(&quot;packagename&quot;)</code> to load its main module, or
+<code>require(&quot;packagename/lib/path/to/sub/module&quot;)</code> to load other modules.</p>
+
+<p>Global installs on Unix systems go to <code>{prefix}/lib/node_modules</code>.
+Global installs on Windows go to <code>{prefix}/node_modules</code> (that is, no
+<code>lib</code> folder.)</p>
+
+<p>If you wish to <code>require()</code> a package, then install it locally.</p>
+
+<h3 id="Executables">Executables</h3>
+
+<p>When in global mode, executables are linked into <code>{prefix}/bin</code> on Unix,
+or directly into <code>{prefix}</code> on Windows.</p>
+
+<p>When in local mode, executables are linked into
+<code>./node_modules/.bin</code> so that they can be made available to scripts run
+through npm.  (For example, so that a test runner will be in the path
+when you run <code>npm test</code>.)</p>
+
+<h3 id="Man-Pages">Man Pages</h3>
+
+<p>When in global mode, man pages are linked into <code>{prefix}/share/man</code>.</p>
+
+<p>When in local mode, man pages are not installed.</p>
+
+<p>Man pages are not installed on Windows systems.</p>
+
+<h3 id="Cache">Cache</h3>
+
+<p>See <code><a href="../doc/cache.html">cache(1)</a></code>.  Cache files are stored in <code>~/.npm</code> on Posix, or
+<code>~/npm-cache</code> on Windows.</p>
+
+<p>This is controlled by the <code>cache</code> configuration param.</p>
+
+<h3 id="Temp-Files">Temp Files</h3>
+
+<p>Temporary files are stored by default in the folder specified by the
+<code>tmp</code> config, which defaults to the TMPDIR, TMP, or TEMP environment
+variables, or <code>/tmp</code> on Unix and <code>c:\windows\temp</code> on Windows.</p>
+
+<p>Temp files are given a unique folder under this root for each run of the
+program, and are deleted upon successful exit.</p>
+
+<h2 id="More-Information">More Information</h2>
+
+<p>When installing locally, npm first tries to find an appropriate
+<code>prefix</code> folder.  This is so that <code>npm install foo@1.2.3</code> will install
+to the sensible root of your package, even if you happen to have <code>cd</code>ed
+into some other folder.</p>
+
+<p>Starting at the $PWD, npm will walk up the folder tree checking for a
+folder that contains either a <code>package.json</code> file, or a <code>node_modules</code>
+folder.  If such a thing is found, then that is treated as the effective
+&quot;current directory&quot; for the purpose of running npm commands.  (This
+behavior is inspired by and similar to git&#39;s .git-folder seeking
+logic when running git commands in a working dir.)</p>
+
+<p>If no package root is found, then the current folder is used.</p>
+
+<p>When you run <code>npm install foo@1.2.3</code>, then the package is loaded into
+the cache, and then unpacked into <code>./node_modules/foo</code>.  Then, any of
+foo&#39;s dependencies are similarly unpacked into
+<code>./node_modules/foo/node_modules/...</code>.</p>
+
+<p>Any bin files are symlinked to <code>./node_modules/.bin/</code>, so that they may
+be found by npm scripts when necessary.</p>
+
+<h3 id="Global-Installation">Global Installation</h3>
+
+<p>If the <code>global</code> configuration is set to true, then npm will
+install packages &quot;globally&quot;.</p>
+
+<p>For global installation, packages are installed roughly the same way,
+but using the folders described above.</p>
+
+<h3 id="Cycles-Conflicts-and-Folder-Parsimony">Cycles, Conflicts, and Folder Parsimony</h3>
+
+<p>Cycles are handled using the property of node&#39;s module system that it
+walks up the directories looking for <code>node_modules</code> folders.  So, at every
+stage, if a package is already installed in an ancestor <code>node_modules</code>
+folder, then it is not installed at the current location.</p>
+
+<p>Consider the case above, where <code>foo -&gt; bar -&gt; baz</code>.  Imagine if, in
+addition to that, baz depended on bar, so you&#39;d have:
+<code>foo -&gt; bar -&gt; baz -&gt; bar -&gt; baz ...</code>.  However, since the folder
+structure is: <code>foo/node_modules/bar/node_modules/baz</code>, there&#39;s no need to
+put another copy of bar into <code>.../baz/node_modules</code>, since when it calls
+require(&quot;bar&quot;), it will get the copy that is installed in
+<code>foo/node_modules/bar</code>.</p>
+
+<p>This shortcut is only used if the exact same
+version would be installed in multiple nested <code>node_modules</code> folders.  It
+is still possible to have <code>a/node_modules/b/node_modules/a</code> if the two
+&quot;a&quot; packages are different versions.  However, without repeating the
+exact same package multiple times, an infinite regress will always be
+prevented.</p>
+
+<p>Another optimization can be made by installing dependencies at the
+highest level possible, below the localized &quot;target&quot; folder.</p>
+
+<h4 id="Example">Example</h4>
+
+<p>Consider this dependency graph:</p>
+
+<pre><code>foo
++-- blerg@1.2.5
++-- bar@1.2.3
+|   +-- blerg@1.x (latest=1.3.7)
+|   +-- baz@2.x
+|   |   `-- quux@3.x
+|   |       `-- bar@1.2.3 (cycle)
+|   `-- asdf@*
+`-- baz@1.2.3
+    `-- quux@3.x
+        `-- bar</code></pre>
+
+<p>In this case, we might expect a folder structure like this:</p>
+
+<pre><code>foo
++-- node_modules
+    +-- blerg (1.2.5) &lt;---[A]
+    +-- bar (1.2.3) &lt;---[B]
+    |   +-- node_modules
+    |   |   `-- baz (2.0.2) &lt;---[C]
+    |   |       `-- node_modules
+    |   |           `-- quux (3.2.0)
+    |   `-- asdf (2.3.4)
+    `-- baz (1.2.3) &lt;---[D]
+        `-- node_modules
+            `-- quux (3.2.0) &lt;---[E]</code></pre>
+
+<p>Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are
+installed in foo&#39;s <code>node_modules</code> folder.</p>
+
+<p>Even though the latest copy of blerg is 1.3.7, foo has a specific
+dependency on version 1.2.5.  So, that gets installed at [A].  Since the
+parent installation of blerg satisfie&#39;s bar&#39;s dependency on blerg@1.x,
+it does not install another copy under [B].</p>
+
+<p>Bar [B] also has dependencies on baz and asdf, so those are installed in
+bar&#39;s <code>node_modules</code> folder.  Because it depends on <code>baz@2.x</code>, it cannot
+re-use the <code>baz@1.2.3</code> installed in the parent <code>node_modules</code> folder [D],
+and must install its own copy [C].</p>
+
+<p>Underneath bar, the <code>baz-&gt;quux-&gt;bar</code> dependency creates a cycle.
+However, because <code>bar</code> is already in <code>quux</code>&#39;s ancestry [B], it does not
+unpack another copy of bar into that folder.</p>
+
+<p>Underneath <code>foo-&gt;baz</code> [D], quux&#39;s [E] folder tree is empty, because its
+dependency on bar is satisfied by the parent folder copy installed at [B].</p>
+
+<p>For a graphical breakdown of what is installed where, use <code>npm ls</code>.</p>
+
+<h3 id="Publishing">Publishing</h3>
+
+<p>Upon publishing, npm will look in the <code>node_modules</code> folder.  If any of
+the items there are not in the <code>bundledDependencies</code> array, then they will
+not be included in the package tarball.</p>
+
+<p>This allows a package maintainer to install all of their dependencies
+(and dev dependencies) locally, but only re-publish those items that
+cannot be found elsewhere.  See <code><a href="../doc/json.html">json(1)</a></code> for more information.</p>
+
+<h2 id="SEE-ALSO">SEE ALSO</h2>
+
+<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">global &mdash; npm@1.2.3</p>
+<script>
+;(function () {
+var wrapper = document.getElementById("wrapper")
+var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0)
+  .filter(function (el) {
+    return el.parentNode === wrapper
+        && el.tagName.match(/H[1-6]/)
+        && el.id
+  })
+var l = 2
+  , toc = document.createElement("ul")
+toc.innerHTML = els.map(function (el) {
+  var i = el.tagName.charAt(1)
+    , out = ""
+  while (i > l) {
+    out += "<ul>"
+    l ++
+  }
+  while (i < l) {
+    out += "</ul>"
+    l --
+  }
+  out += "<li><a href='#" + el.id + "'>" +
+    ( el.innerText || el.text || el.innerHTML)
+    + "</a>"
+  return out
+}).join("\n")
+toc.id = "toc"
+document.body.appendChild(toc)
+})()
+</script>
+</body></html>
index 2866c45..20ce72d 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.2.2</p>
+<p id="footer">help-search &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e07da58..072dca5 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.2.2</p>
+<p id="footer">help &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a9edf49..bebf26d 100644 (file)
 
 <p> Folder Structures Used by npm</p>
 
+<h2 id="npm-global-1"><a href="../doc/global.html">global(1)</a></h2>
+
+<p> Folder Structures Used by npm</p>
+
 <h2 id="npm-help-search-1"><a href="../doc/help-search.html">help-search(1)</a></h2>
 
 <p> Search npm help documentation</p>
 
 <p> Start a package</p>
 
+<h2 id="npm-rm-1"><a href="../doc/rm.html">rm(1)</a></h2>
+
+<p> Remove a package</p>
+
 <h2 id="npm-root-1"><a href="../doc/root.html">root(1)</a></h2>
 
 <p> Display npm root</p>
 
 <p> Display npm username</p>
 </div>
-<p id="footer">index &mdash; npm@1.2.2</p>
+<p id="footer">index &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 37664a6..bbb0846 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.2.2</p>
+<p id="footer">init &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 534ba26..1045642 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.2.2</p>
+<p id="footer">install &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1ea27fc..aeef70a 100644 (file)
@@ -525,7 +525,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.2.2</p>
+<p id="footer">json &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1107004..7302de4 100644 (file)
@@ -58,7 +58,7 @@ installation target into your project&#39;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.2.2</p>
+<p id="footer">link &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2930a94..41cf384 100644 (file)
@@ -25,7 +25,7 @@ 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&#39;s source tree will show:</p>
 
-<pre><code>npm@1.2.2 /path/to/npm
+<pre><code>npm@1.2.3 /path/to/npm
 â””─┬ init-package-json@0.0.4
   â””── promzard@0.1.5</code></pre>
 
@@ -64,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">ls &mdash; npm@1.2.2</p>
+<p id="footer">ls &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9eb30a9..1a36a71 100644 (file)
@@ -14,7 +14,7 @@
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.2.2</p>
+<p>1.2.3</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.2.2</p>
+<p id="footer">npm &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b3c1606..30e2283 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.2.2</p>
+<p id="footer">outdated &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8228fb0..7d020ad 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.2.2</p>
+<p id="footer">owner &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3dc318d..4ba38ca 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.2.2</p>
+<p id="footer">pack &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bdde2a5..7ddaaa0 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.2.2</p>
+<p id="footer">prefix &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bc97027..4707d92 100644 (file)
@@ -25,7 +25,7 @@ package&#39;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.2.2</p>
+<p id="footer">prune &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a24ca2d..5bf3485 100644 (file)
@@ -29,7 +29,7 @@ the registry.  Overwrites when the &quot;--force&quot; 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.2.2</p>
+<p id="footer">publish &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2c6a4e1..c4cb422 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.2.2</p>
+<p id="footer">rebuild &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7e618b7..19945f3 100644 (file)
@@ -95,7 +95,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.2.2</p>
+<p id="footer">registry &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 36f1c62..ffc9e82 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.2.2</p>
+<p id="footer">removing-npm &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fd21f56..064642d 100644 (file)
@@ -24,7 +24,7 @@ the &quot;start&quot; 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.2.2</p>
+<p id="footer">restart &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/rm.html b/deps/npm/html/doc/rm.html
new file mode 100644 (file)
index 0000000..4a12251
--- /dev/null
@@ -0,0 +1,57 @@
+<!doctype html>
+<html>
+  <title>rm</title>
+  <meta http-equiv="content-type" value="text/html;utf-8">
+  <link rel="stylesheet" type="text/css" href="../static/style.css">
+
+  <body>
+    <div id="wrapper">
+<h1><a href="../doc/rm.html">rm</a></h1> <p>Remove a package</p>
+
+<h2 id="SYNOPSIS">SYNOPSIS</h2>
+
+<pre><code>npm rm &lt;name&gt;
+npm uninstall &lt;name&gt;</code></pre>
+
+<h2 id="DESCRIPTION">DESCRIPTION</h2>
+
+<p>This uninstalls a package, completely removing everything npm installed
+on its behalf.</p>
+
+<h2 id="SEE-ALSO">SEE ALSO</h2>
+
+<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">rm &mdash; npm@1.2.3</p>
+<script>
+;(function () {
+var wrapper = document.getElementById("wrapper")
+var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0)
+  .filter(function (el) {
+    return el.parentNode === wrapper
+        && el.tagName.match(/H[1-6]/)
+        && el.id
+  })
+var l = 2
+  , toc = document.createElement("ul")
+toc.innerHTML = els.map(function (el) {
+  var i = el.tagName.charAt(1)
+    , out = ""
+  while (i > l) {
+    out += "<ul>"
+    l ++
+  }
+  while (i < l) {
+    out += "</ul>"
+    l --
+  }
+  out += "<li><a href='#" + el.id + "'>" +
+    ( el.innerText || el.text || el.innerHTML)
+    + "</a>"
+  return out
+}).join("\n")
+toc.id = "toc"
+document.body.appendChild(toc)
+})()
+</script>
+</body></html>
index 0973dd8..6749fd9 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.2.2</p>
+<p id="footer">root &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b353786..277ae85 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.2.2</p>
+<p id="footer">run-script &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d6beacf..60dec81 100644 (file)
@@ -218,7 +218,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.2.2</p>
+<p id="footer">scripts &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0554e40..a34dd7e 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.2.2</p>
+<p id="footer">search &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c0206e1..e756c04 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.2.2</p>
+<p id="footer">semver &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7389ebf..1f924bc 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.2.2</p>
+<p id="footer">shrinkwrap &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b896fae..07fb019 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.2.2</p>
+<p id="footer">star &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bcc3dbb..cad77cd 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.2.2</p>
+<p id="footer">start &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 59a3a3f..0f797f9 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.2.2</p>
+<p id="footer">stop &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9eadc8b..204e3a0 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.2.2</p>
+<p id="footer">submodule &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8ff5d51..7d97b27 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.2.2</p>
+<p id="footer">tag &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ee09bfe..2af4157 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.2.2</p>
+<p id="footer">test &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index de8dc5f..2028955 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.2.2</p>
+<p id="footer">uninstall &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8766a0a..f8ecdb6 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.2.2</p>
+<p id="footer">unpublish &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bec6bcb..cc90c23 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.2.2</p>
+<p id="footer">update &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c1d13a2..c0eb74d 100644 (file)
@@ -40,7 +40,7 @@ in your git config for this to work properly.</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.2.2</p>
+<p id="footer">version &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0fcc49c..364d786 100644 (file)
@@ -90,7 +90,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.2.2</p>
+<p id="footer">view &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a0ee7b9..ba3fba5 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.2.2</p>
+<p id="footer">whoami &mdash; npm@1.2.3</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 815739c..9cd4c4c 100644 (file)
@@ -109,7 +109,7 @@ function rebuildBundles (pkg, folder, parent, gtop, cb) {
     chain(files.filter(function (file) {
       // rebuild if:
       // not a .folder, like .bin or .hooks
-      return file.charAt(0) !== "."
+      return !file.match(/^[\._-]/)
           // not some old 0.x style bundle
           && file.indexOf("@") === -1
           // either not a dep, or explicitly bundled
index 7b83350..e371bc1 100644 (file)
@@ -139,7 +139,7 @@ function read (name, ver, forceBypass, cb) {
   }
 
   readJson(jsonFile, function (er, data) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     if (er) return addNamed(name, ver, c)
     deprCheck(data)
     c(er, data)
@@ -712,7 +712,7 @@ function addNameVersion (name, ver, data, cb) {
       if (!er) readJson( path.join( npm.cache, name, ver
                                   , "package", "package.json" )
                        , function (er, data) {
-          if (er && er.code !== "ENOENT") return cb(er)
+          if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
           if (er) return fetchit()
           return cb(null, data)
         })
index 51c6fca..a73a69d 100644 (file)
@@ -265,7 +265,7 @@ function readInstalled (dir, counter, parent, cb) {
   })
 
   readJson(path.resolve(dir, "package.json"), function (er, data) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     if (er) return cb() // not a package, probably.
     counter[data.name] = counter[data.name] || 0
     counter[data.name]++
@@ -294,6 +294,9 @@ function readInstalled (dir, counter, parent, cb) {
 
   fs.readdir(path.resolve(dir, "node_modules"), function (er, c) {
     children = c || [] // error is ok, just means no children.
+    children = children.filter(function (p) {
+      return !p.match(/^[\._-]/)
+    })
     next()
   })
 
index ef5ef14..da16c1a 100644 (file)
@@ -148,7 +148,7 @@ function install (args, cb_) {
     // initial "family" is the name:version of the root, if it's got
     // a package.json file.
     readJson(path.resolve(where, "package.json"), function (er, data) {
-      if (er && er.code !== "ENOENT") return cb(er)
+      if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
       if (er) data = null
       var context = { family: {}
                     , ancestors: {}
@@ -456,7 +456,7 @@ function installManyTop_ (what, where, context, cb) {
       return path.resolve(nm, p, "package.json")
     }), function (jsonfile, cb) {
       readJson(jsonfile, function (er, data) {
-        if (er && er.code !== "ENOENT") return cb(er)
+        if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
         if (er) return cb(null, [])
         return cb(null, [[data.name, data.version]])
       })
@@ -536,9 +536,15 @@ function targetResolver (where, context, deps) {
 
   if (!context.explicit) fs.readdir(nm, function (er, inst) {
     if (er) return alreadyInstalledManually = []
+
+    // don't even mess with non-package looking things
+    inst = inst.filter(function (p) {
+      return !p.match(/^[\._-]/)
+    })
+
     asyncMap(inst, function (pkg, cb) {
       readJson(path.resolve(nm, pkg, "package.json"), function (er, d) {
-        if (er && er.code !== "ENOENT") return cb(er)
+        if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
         // error means it's not a package, most likely.
         if (er) return cb(null, [])
 
@@ -657,7 +663,7 @@ function localLink (target, where, context, cb) {
     , parent = context.parent
 
   readJson(jsonFile, function (er, data) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     if (er || data._id === target._id) {
       if (er) {
         install( path.resolve(npm.globalDir, "..")
index e912796..4ecd64a 100644 (file)
@@ -20,7 +20,7 @@ link.completion = function (opts, cb) {
   var dir = npm.globalDir
   fs.readdir(dir, function (er, files) {
     cb(er, files.filter(function (f) {
-      return f.charAt(0) !== "."
+      return !f.match(/^[\._-]/)
     }))
   })
 }
index bb9f93e..e3ef5b1 100644 (file)
@@ -76,7 +76,7 @@ function outdated_ (args, dir, parentHas, cb) {
 
   var deps = null
   readJson(path.resolve(dir, "package.json"), function (er, d) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     deps = (er) ? true : (d.dependencies || {})
     return next()
   })
@@ -87,10 +87,13 @@ function outdated_ (args, dir, parentHas, cb) {
       has = Object.create(parentHas)
       return next()
     }
+    pkgs = pkgs.filter(function (p) {
+      return !p.match(/^[\._-]/)
+    })
     asyncMap(pkgs, function (pkg, cb) {
       var jsonFile = path.resolve(dir, "node_modules", pkg, "package.json")
       readJson(jsonFile, function (er, d) {
-        if (er && er.code !== "ENOENT") return cb(er)
+        if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
         cb(null, er ? [] : [[d.name, d.version]])
       })
     }, function (er, pvs) {
index e22719f..8de09e5 100644 (file)
@@ -32,7 +32,7 @@ function publish (args, isRetry, cb) {
   var arg = args[0]
   // if it's a local folder, then run the prepublish there, first.
   readJson(path.resolve(arg, "package.json"), function (er, data) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     // error is ok.  could be publishing a url or tarball
     // however, that means that we will not have automatically run
     // the prepublish script, since that gets run when adding a folder
index d509cc8..0808f2e 100644 (file)
@@ -25,7 +25,7 @@ runScript.completion = function (opts, cb) {
     // or a package, in which case, complete against its scripts
     var json = path.join(npm.prefix, "package.json")
     return readJson(json, function (er, d) {
-      if (er && er.code !== "ENOENT") return cb(er)
+      if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
       if (er) d = {}
       var scripts = Object.keys(d.scripts || {})
       console.error("local scripts", scripts)
@@ -36,7 +36,7 @@ runScript.completion = function (opts, cb) {
       var pkgDir = path.resolve( pref, "node_modules"
                                , argv[2], "package.json" )
       readJson(pkgDir, function (er, d) {
-        if (er && er.code !== "ENOENT") return cb(er)
+        if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
         if (er) d = {}
         var scripts = Object.keys(d.scripts || {})
         return cb(null, scripts)
@@ -57,7 +57,7 @@ runScript.completion = function (opts, cb) {
 
   if (npm.config.get("global")) scripts = [], next()
   else readJson(path.join(npm.prefix, "package.json"), function (er, d) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     d = d || {}
     scripts = Object.keys(d.scripts || {})
     next()
index 275088e..bebc230 100644 (file)
@@ -30,7 +30,7 @@ function uninstall (args, cb) {
   // remove this package from the global space, if it's installed there
   if (npm.config.get("global")) return cb(uninstall.usage)
   readJson(path.resolve(npm.prefix, "package.json"), function (er, pkg) {
-    if (er && er.code !== "ENOENT") return cb(er)
+    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
     if (er) return cb(uninstall.usage)
     uninstall_( [pkg.name]
               , npm.dir
index c0056e7..0e48ab7 100644 (file)
@@ -56,7 +56,7 @@ function unpublish (args, cb) {
     // read the package name and version out of that.
     var cwdJson = path.join(process.cwd(), "package.json")
     return readJson(cwdJson, function (er, data) {
-      if (er && er.code !== "ENOENT") return cb(er)
+      if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
       if (er) return cb("Usage:\n"+unpublish.usage)
       gotProject(data.name, data.version, cb)
     })
index 8041285..83bd40d 100644 (file)
@@ -683,7 +683,7 @@ A proxy to use for outgoing https requests\.
 .SS "user\-agent"
 .
 .IP "\(bu" 4
-Default: npm/{npm\.version} node/{process\.version}
+Default: node/{process\.version} {process\.platform} {process\.arch}
 .
 .IP "\(bu" 4
 Type: String
index 070d40c..abef276 100644 (file)
@@ -1,7 +1,7 @@
-.\" Generated with Ronnjs/v0.1
+.\" Generated with Ronnjs 0.3.8
 .\" http://github.com/kapouer/ronnjs/
 .
-.TH "NPM\-FOLDERS" "1" "November 2011" "" ""
+.TH "NPM\-FOLDERS" "1" "January 2013" "" ""
 .
 .SH "NAME"
 \fBnpm-folders\fR \-\- Folder Structures Used by npm
@@ -148,9 +148,8 @@ prevented\.
 Another optimization can be made by installing dependencies at the
 highest level possible, below the localized "target" folder\.
 .
-.TP
-Example
-.Consider this dependency graph:
+.SS "\fIExample\fR"
+Consider this dependency graph:
 .
 .IP "" 4
 .
index 0065d78..b2e1258 100644 (file)
@@ -66,6 +66,9 @@
 .SH "npm help folders"
  Folder Structures Used by npm
 .
+.SH "npm help global"
+ Folder Structures Used by npm
+.
 .SH "npm help help\-search"
  Search npm help documentation
 .
 .SH "npm help restart"
  Start a package
 .
+.SH "npm help rm"
+ Remove a package
+.
 .SH "npm help root"
  Display npm root
 .
index 272e451..1439aa7 100644 (file)
@@ -29,7 +29,7 @@ For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
 .IP "" 4
 .
 .nf
-npm@1.2.2 /path/to/npm
+npm@1.2.3 /path/to/npm
 â””─┬ init\-package\-json@0\.0\.4
   â””── promzard@0\.1\.5
 .
index 93fc999..214a8a1 100644 (file)
@@ -14,7 +14,7 @@ npm <command> [args]
 .fi
 .
 .SH "VERSION"
-1.2.2
+1.2.3
 .
 .SH "DESCRIPTION"
 npm is the package manager for the Node JavaScript platform\.  It puts
index 5df9588..7c188fc 100644 (file)
@@ -1,7 +1,7 @@
-.\" Generated with Ronnjs/v0.1
+.\" Generated with Ronnjs 0.3.8
 .\" http://github.com/kapouer/ronnjs/
 .
-.TH "NPM\-RM" "1" "November 2011" "" ""
+.TH "NPM\-RM" "1" "January 2013" "" ""
 .
 .SH "NAME"
 \fBnpm-rm\fR \-\- Remove a package
index a02644c..43be0a0 100644 (file)
@@ -10,7 +10,7 @@
 .
 .nf
 var npm = require("npm")
-npm\.load(configObject, function (er, npm) {
+npm\.load([configObject,] function (er, npm) {
   // use the npm object, now that it\'s loaded\.
   npm\.config\.set(key, val)
   val = npm\.config\.get(key)
@@ -21,7 +21,7 @@ npm\.load(configObject, function (er, npm) {
 .fi
 .
 .SH "VERSION"
-1.2.2
+1.2.3
 .
 .SH "DESCRIPTION"
 This is the API documentation for npm\.
@@ -29,10 +29,13 @@ To find documentation of the command line
 client, see \fBnpm help npm\fR\|\.
 .
 .P
-Prior to using npm\'s commands, \fBnpm\.load()\fR must be called with an object hash of
-top\-level configs\.  In the npm command line client,
-this set of configs is parsed from the command line options\.  Additional
-configuration params are loaded from two configuration files\.  See \fBnpm help config\fR for more information\.
+Prior to using npm\'s commands, \fBnpm\.load()\fR must be called\.
+If you provide \fBconfigObject\fR as an object hash of top\-level
+configs, they override the values stored in the various config
+locations\. In the npm command line client, this set of configs
+is parsed from the command line options\. Additional configuration
+params are loaded from two configuration files\. See \fBnpm help config\fR
+for more information\.
 .
 .P
 After that, each of the functions are accessible in the
index 10c87bc..b26e7ff 100644 (file)
@@ -22,7 +22,7 @@
 //
 //   else // not globstar
 //     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
-//       Test ENTRY against pattern[n+1]
+//       Test ENTRY against pattern[n]
 //       If fails, continue
 //       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
 //
@@ -87,7 +87,6 @@ function Glob (pattern, options, cb) {
   if (typeof cb === "function") {
     this.on("error", cb)
     this.on("end", function (matches) {
-      // console.error("cb with matches", matches)
       cb(null, matches)
     })
   }
@@ -111,6 +110,8 @@ function Glob (pattern, options, cb) {
 
   this.root = options.root || path.resolve(this.cwd, "/")
   this.root = path.resolve(this.root)
+  if (process.platform === "win32")
+    this.root = this.root.replace(/\\/g, "/")
 
   this.nomount = !!options.nomount
 
@@ -126,6 +127,7 @@ function Glob (pattern, options, cb) {
     pattern = "**/" + pattern
   }
 
+  this.strict = options.strict !== false
   this.dot = !!options.dot
   this.mark = !!options.mark
   this.sync = !!options.sync
@@ -134,7 +136,11 @@ function Glob (pattern, options, cb) {
   this.nosort = !!options.nosort
   this.nocase = !!options.nocase
   this.stat = !!options.stat
+
   this.debug = !!options.debug || !!options.globDebug
+  if (this.debug)
+    this.log = console.error
+
   this.silent = !!options.silent
 
   var mm = this.minimatch = new Minimatch(pattern, options)
@@ -164,6 +170,8 @@ function Glob (pattern, options, cb) {
   }
 }
 
+Glob.prototype.log = function () {}
+
 Glob.prototype._finish = function () {
   assert(this instanceof Glob)
 
@@ -172,7 +180,7 @@ Glob.prototype._finish = function () {
 
   for (var i = 0, l = this.matches.length; i < l; i ++) {
     var matches = this.matches[i]
-    if (this.debug) console.error("matches[%d] =", i, matches)
+    this.log("matches[%d] =", i, matches)
     // do like the shell, and spit out the literal glob
     if (!matches) {
       if (this.nonull) {
@@ -213,7 +221,7 @@ Glob.prototype._finish = function () {
     }, this)
   }
 
-  if (this.debug) console.error("emitting end", all)
+  this.log("emitting end", all)
 
   this.EOF = this.found = all
   this.emitMatch(this.EOF)
@@ -266,9 +274,9 @@ Glob.prototype._processEmitQueue = function (m) {
       this._processingEmitQueue = false
       break
     }
-    if (this.debug) {
-      console.error('emit!', m === this.EOF ? "end" : "match")
-    }
+
+    this.log('emit!', m === this.EOF ? "end" : "match")
+
     this.emit(m === this.EOF ? "end" : "match", m)
     this._processingEmitQueue = false
   }
@@ -318,6 +326,10 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
           if (prefix.charAt(0) === "/" && !this.nomount) {
             prefix = path.join(this.root, prefix)
           }
+
+          if (process.platform === "win32")
+            prefix = prefix.replace(/\\/g, "/")
+
           this.matches[index] = this.matches[index] || {}
           this.matches[index][prefix] = true
           this.emitMatch(prefix)
@@ -344,12 +356,17 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
   // get the list of entries.
   var read
   if (prefix === null) read = "."
-  else if (isAbsolute(prefix)) {
-    read = prefix = path.resolve("/", prefix)
-    if (this.debug) console.error('absolute: ', prefix, this.root, pattern)
+  else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
+    read = prefix = path.resolve(path.join("/", prefix))
+
+    if (process.platform === "win32")
+      read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
+
+    this.log('absolute: ', prefix, this.root, pattern)
   } else read = prefix
 
-  if (this.debug) console.error('readdir(%j)', read, this.cwd, this.root)
+  this.log('readdir(%j)', read, this.cwd, this.root)
+
   return this._readdir(read, function (er, entries) {
     if (er) {
       // not a directory!
@@ -417,6 +434,9 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
           e = path.join(this.root, e)
         }
 
+        if (process.platform === "win32")
+          e = e.replace(/\\/g, "/")
+
         this.matches[index] = this.matches[index] || {}
         this.matches[index][e] = true
         this.emitMatch(e)
@@ -450,7 +470,7 @@ Glob.prototype._stat = function (f, cb) {
   } else if (this.changedCwd) {
     abs = path.resolve(this.cwd, f)
   }
-  if (this.debug) console.error('stat', [this.cwd, f, '=', abs])
+  this.log('stat', [this.cwd, f, '=', abs])
   if (f.length > this.maxLength) {
     var er = new Error("Path name too long")
     er.code = "ENAMETOOLONG"
@@ -481,6 +501,16 @@ Glob.prototype._stat = function (f, cb) {
 Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
   var exists
   assert(this instanceof Glob)
+
+  if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
+    this.log("should be ENOTDIR, fake it")
+
+    er = new Error("ENOTDIR, not a directory '" + abs + "'")
+    er.path = abs
+    er.code = "ENOTDIR"
+    stat = null
+  }
+
   if (er || !stat) {
     exists = false
   } else {
@@ -501,7 +531,7 @@ Glob.prototype._readdir = function (f, cb) {
     abs = path.resolve(this.cwd, f)
   }
 
-  if (this.debug) console.error('readdir', [this.cwd, f, abs])
+  this.log('readdir', [this.cwd, f, abs])
   if (f.length > this.maxLength) {
     var er = new Error("Path name too long")
     er.code = "ENAMETOOLONG"
@@ -522,7 +552,7 @@ Glob.prototype._readdir = function (f, cb) {
       , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
       er.path = f
       er.code = code
-      if (this.debug) console.error(f, er)
+      this.log(f, er)
       if (this.sync) return cb.call(this, er)
       return process.nextTick(cb.bind(this, er))
     }
@@ -590,7 +620,7 @@ function absWin (p) {
   // pull off the device/UNC bit from a windows path.
   // from node's lib/path.js
   var splitDeviceRe =
-        /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
+      /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
     , result = splitDeviceRe.exec(p)
     , device = result[1] || ''
     , isUnc = device && device.charAt(1) !== ':'
index c684b80..a964479 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "glob",
   "description": "a little globber",
-  "version": "3.1.14",
+  "version": "3.1.17",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"
@@ -21,7 +21,7 @@
     "inherits": "1"
   },
   "devDependencies": {
-    "tap": "~0.3",
+    "tap": "~0.4.0",
     "mkdirp": "0",
     "rimraf": "1"
   },
@@ -31,9 +31,6 @@
   "license": "BSD",
   "readme": "# Glob\n\nThis is a glob implementation in JavaScript.  It uses the `minimatch`\nlibrary to do its matching.\n\n## Attention: node-glob users!\n\nThe API has changed dramatically between 2.x and 3.x. This library is\nnow 100% JavaScript, and the integer flags have been replaced with an\noptions object.\n\nAlso, there's an event emitter class, proper tests, and all the other\nthings you've come to expect from node modules.\n\nAnd best of all, no compilation!\n\n## Usage\n\n```javascript\nvar glob = require(\"glob\")\n\n// options is optional\nglob(\"**/*.js\", options, function (er, files) {\n  // files is an array of filenames.\n  // If the `nonull` option is set, and nothing\n  // was found, then files is [\"**/*.js\"]\n  // er is an error object or null.\n})\n```\n\n## Features\n\nPlease see the [minimatch\ndocumentation](https://github.com/isaacs/minimatch) for more details.\n\nSupports these glob features:\n\n* Brace Expansion\n* Extended glob matching\n* \"Globstar\" `**` matching\n\nSee:\n\n* `man sh`\n* `man bash`\n* `man 3 fnmatch`\n* `man 5 gitignore`\n* [minimatch documentation](https://github.com/isaacs/minimatch)\n\n## glob(pattern, [options], cb)\n\n* `pattern` {String} Pattern to be matched\n* `options` {Object}\n* `cb` {Function}\n  * `err` {Error | null}\n  * `matches` {Array<String>} filenames found matching the pattern\n\nPerform an asynchronous glob search.\n\n## glob.sync(pattern, [options]\n\n* `pattern` {String} Pattern to be matched\n* `options` {Object}\n* return: {Array<String>} filenames found matching the pattern\n\nPerform a synchronous glob search.\n\n## Class: glob.Glob\n\nCreate a Glob object by instanting the `glob.Glob` class.\n\n```javascript\nvar Glob = require(\"glob\").Glob\nvar mg = new Glob(pattern, options, cb)\n```\n\nIt's an EventEmitter, and starts walking the filesystem to find matches\nimmediately.\n\n### new glob.Glob(pattern, [options], [cb])\n\n* `pattern` {String} pattern to search for\n* `options` {Object}\n* `cb` {Function} Called when an error occurs, or matches are found\n  * `err` {Error | null}\n  * `matches` {Array<String>} filenames found matching the pattern\n\nNote that if the `sync` flag is set in the options, then matches will\nbe immediately available on the `g.found` member.\n\n### Properties\n\n* `minimatch` The minimatch object that the glob uses.\n* `options` The options object passed in.\n* `error` The error encountered.  When an error is encountered, the\n  glob object is in an undefined state, and should be discarded.\n* `aborted` Boolean which is set to true when calling `abort()`.  There\n  is no way at this time to continue a glob search after aborting, but\n  you can re-use the statCache to avoid having to duplicate syscalls.\n\n### Events\n\n* `end` When the matching is finished, this is emitted with all the\n  matches found.  If the `nonull` option is set, and no match was found,\n  then the `matches` list contains the original pattern.  The matches\n  are sorted, unless the `nosort` flag is set.\n* `match` Every time a match is found, this is emitted with the matched.\n* `error` Emitted when an unexpected error is encountered, or whenever\n  any fs error occurs if `options.strict` is set.\n* `abort` When `abort()` is called, this event is raised.\n\n### Methods\n\n* `abort` Stop the search.\n\n### Options\n\nAll the options that can be passed to Minimatch can also be passed to\nGlob to change pattern matching behavior.  Also, some have been added,\nor have glob-specific ramifications.\n\nAll options are false by default, unless otherwise noted.\n\nAll options are added to the glob object, as well.\n\n* `cwd` The current working directory in which to search.  Defaults\n  to `process.cwd()`.\n* `root` The place where patterns starting with `/` will be mounted\n  onto.  Defaults to `path.resolve(options.cwd, \"/\")` (`/` on Unix\n  systems, and `C:\\` or some such on Windows.)\n* `nomount` By default, a pattern starting with a forward-slash will be\n  \"mounted\" onto the root setting, so that a valid filesystem path is\n  returned.  Set this flag to disable that behavior.\n* `mark` Add a `/` character to directory matches.  Note that this\n  requires additional stat calls.\n* `nosort` Don't sort the results.\n* `stat` Set to true to stat *all* results.  This reduces performance\n  somewhat, and is completely unnecessary, unless `readdir` is presumed\n  to be an untrustworthy indicator of file existence.  It will cause\n  ELOOP to be triggered one level sooner in the case of cyclical\n  symbolic links.\n* `silent` When an unusual error is encountered\n  when attempting to read a directory, a warning will be printed to\n  stderr.  Set the `silent` option to true to suppress these warnings.\n* `strict` When an unusual error is encountered\n  when attempting to read a directory, the process will just continue on\n  in search of other matches.  Set the `strict` option to raise an error\n  in these cases.\n* `statCache` A cache of results of filesystem information, to prevent\n  unnecessary stat calls.  While it should not normally be necessary to\n  set this, you may pass the statCache from one glob() call to the\n  options object of another, if you know that the filesystem will not\n  change between calls.  (See \"Race Conditions\" below.)\n* `sync` Perform a synchronous glob search.\n* `nounique` In some cases, brace-expanded patterns can result in the\n  same file showing up multiple times in the result set.  By default,\n  this implementation prevents duplicates in the result set.\n  Set this flag to disable that behavior.\n* `nonull` Set to never return an empty set, instead returning a set\n  containing the pattern itself.  This is the default in glob(3).\n* `nocase` Perform a case-insensitive match.  Note that case-insensitive\n  filesystems will sometimes result in glob returning results that are\n  case-insensitively matched anyway, since readdir and stat will not\n  raise an error.\n* `debug` Set to enable debug logging in minimatch and glob.\n* `globDebug` Set to enable debug logging in glob, but not minimatch.\n\n## Comparisons to other fnmatch/glob implementations\n\nWhile strict compliance with the existing standards is a worthwhile\ngoal, some discrepancies exist between node-glob and other\nimplementations, and are intentional.\n\nIf the pattern starts with a `!` character, then it is negated.  Set the\n`nonegate` flag to suppress this behavior, and treat leading `!`\ncharacters normally.  This is perhaps relevant if you wish to start the\npattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`\ncharacters at the start of a pattern will negate the pattern multiple\ntimes.\n\nIf a pattern starts with `#`, then it is treated as a comment, and\nwill not match anything.  Use `\\#` to match a literal `#` at the\nstart of a line, or set the `nocomment` flag to suppress this behavior.\n\nThe double-star character `**` is supported by default, unless the\n`noglobstar` flag is set.  This is supported in the manner of bsdglob\nand bash 4.1, where `**` only has special significance if it is the only\nthing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but\n`a/**b` will not.  **Note that this is different from the way that `**` is\nhandled by ruby's `Dir` class.**\n\nIf an escaped pattern has no matches, and the `nonull` flag is set,\nthen glob returns the pattern as-provided, rather than\ninterpreting the character escapes.  For example,\n`glob.match([], \"\\\\*a\\\\?\")` will return `\"\\\\*a\\\\?\"` rather than\n`\"*a?\"`.  This is akin to setting the `nullglob` option in bash, except\nthat it does not resolve escaped pattern characters.\n\nIf brace expansion is not disabled, then it is performed before any\nother interpretation of the glob pattern.  Thus, a pattern like\n`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded\n**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are\nchecked for validity.  Since those two are valid, matching proceeds.\n\n## Windows\n\n**Please only use forward-slashes in glob expressions.**\n\nThough windows uses either `/` or `\\` as its path separator, only `/`\ncharacters are used by this glob implementation.  You must use\nforward-slashes **only** in glob expressions.  Back-slashes will always\nbe interpreted as escape characters, not path separators.\n\nResults from absolute patterns such as `/foo/*` are mounted onto the\nroot setting using `path.join`.  On windows, this will by default result\nin `/foo/*` matching `C:\\foo\\bar.txt`.\n\n## Race Conditions\n\nGlob searching, by its very nature, is susceptible to race conditions,\nsince it relies on directory walking and such.\n\nAs a result, it is possible that a file that exists when glob looks for\nit may have been deleted or modified by the time it returns the result.\n\nAs part of its internal implementation, this program caches all stat\nand readdir calls that it makes, in order to cut down on system\noverhead.  However, this also makes it even more susceptible to races,\nespecially if the statCache object is reused between glob calls.\n\nUsers are thus advised not to use a glob result as a\nguarantee of filesystem state in the face of rapid changes.\nFor the vast majority of operations, this is never a problem.\n",
   "readmeFilename": "README.md",
-  "_id": "glob@3.1.14",
-  "dist": {
-    "shasum": "f97a731c41da6695dc83944bbb2177e9a29b363d"
-  },
-  "_from": "glob@3.1.14"
+  "_id": "glob@3.1.17",
+  "_from": "glob@~3.1.14"
 }
index 2b60643..245afaf 100644 (file)
@@ -48,14 +48,129 @@ files.forEach(function (f) {
   })
 })
 
-tap.test("symlinky", function (t) {
-  var d = path.dirname(symlinkTo)
-  console.error("mkdirp", d)
-  mkdirp(d, 0755, function (er) {
-    t.ifError(er)
-    fs.symlink(symlinkFrom, symlinkTo, function (er) {
-      t.ifError(er, "make symlink")
+if (process.platform !== "win32") {
+  tap.test("symlinky", function (t) {
+    var d = path.dirname(symlinkTo)
+    console.error("mkdirp", d)
+    mkdirp(d, 0755, function (er) {
+      t.ifError(er)
+      fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) {
+        t.ifError(er, "make symlink")
+        t.end()
+      })
+    })
+  })
+}
+
+;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) {
+  w = "/tmp/glob-test/" + w
+  tap.test("create " + w, function (t) {
+    mkdirp(w, function (er) {
+      if (er)
+        throw er
+      t.pass(w)
       t.end()
     })
   })
 })
+
+
+// generate the bash pattern test-fixtures if possible
+if (process.platform === "win32" || !process.env.TEST_REGEN) {
+  console.error("Windows, or TEST_REGEN unset.  Using cached fixtures.")
+  return
+}
+
+var spawn = require("child_process").spawn;
+var globs =
+  // put more patterns here.
+  // anything that would be directly in / should be in /tmp/glob-test
+  ["test/a/*/+(c|g)/./d"
+  ,"test/a/**/[cg]/../[cg]"
+  ,"test/a/{b,c,d,e,f}/**/g"
+  ,"test/a/b/**"
+  ,"test/**/g"
+  ,"test/a/abc{fed,def}/g/h"
+  ,"test/a/abc{fed/g,def}/**/"
+  ,"test/a/abc{fed/g,def}/**///**/"
+  ,"test/**/a/**/"
+  ,"test/+(a|b|c)/a{/,bc*}/**"
+  ,"test/*/*/*/f"
+  ,"test/**/f"
+  ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
+  ,"{./*/*,/tmp/glob-test/*}"
+  ,"{/tmp/glob-test/*,*}" // evil owl face!  how you taunt me!
+  ,"test/a/!(symlink)/**"
+  ]
+var bashOutput = {}
+var fs = require("fs")
+
+globs.forEach(function (pattern) {
+  tap.test("generate fixture " + pattern, function (t) {
+    var cmd = "shopt -s globstar && " +
+              "shopt -s extglob && " +
+              "shopt -s nullglob && " +
+              // "shopt >&2; " +
+              "eval \'for i in " + pattern + "; do echo $i; done\'"
+    var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) })
+    var out = []
+    cp.stdout.on("data", function (c) {
+      out.push(c)
+    })
+    cp.stderr.pipe(process.stderr)
+    cp.on("close", function (code) {
+      out = flatten(out)
+      if (!out)
+        out = []
+      else
+        out = cleanResults(out.split(/\r*\n/))
+
+      bashOutput[pattern] = out
+      t.notOk(code, "bash test should finish nicely")
+      t.end()
+    })
+  })
+})
+
+tap.test("save fixtures", function (t) {
+  var fname = path.resolve(__dirname, "bash-results.json")
+  var data = JSON.stringify(bashOutput, null, 2) + "\n"
+  fs.writeFile(fname, data, function (er) {
+    t.ifError(er)
+    t.end()
+  })
+})
+
+function cleanResults (m) {
+  // normalize discrepancies in ordering, duplication,
+  // and ending slashes.
+  return m.map(function (m) {
+    return m.replace(/\/+/g, "/").replace(/\/$/, "")
+  }).sort(alphasort).reduce(function (set, f) {
+    if (f !== set[set.length - 1]) set.push(f)
+    return set
+  }, []).sort(alphasort).map(function (f) {
+    // de-windows
+    return (process.platform !== 'win32') ? f
+           : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
+  })
+}
+
+function flatten (chunks) {
+  var s = 0
+  chunks.forEach(function (c) { s += c.length })
+  var out = new Buffer(s)
+  s = 0
+  chunks.forEach(function (c) {
+    c.copy(out, s)
+    s += c.length
+  })
+
+  return out.toString().trim()
+}
+
+function alphasort (a, b) {
+  a = a.toLowerCase()
+  b = b.toLowerCase()
+  return a > b ? 1 : a < b ? -1 : 0
+}
index a052ae8..239ed1a 100644 (file)
@@ -2,25 +2,8 @@
 // show that it does the same thing by default as the shell.
 var tap = require("tap")
 , child_process = require("child_process")
-
-// put more patterns here.
-, globs =
-  ["test/a/*/+(c|g)/./d"
-  ,"test/a/**/[cg]/../[cg]"
-  ,"test/a/{b,c,d,e,f}/**/g"
-  ,"test/a/b/**"
-  ,"test/**/g"
-  ,"test/a/abc{fed,def}/g/h"
-  ,"test/a/abc{fed/g,def}/**/"
-  ,"test/a/abc{fed/g,def}/**///**/"
-  ,"test/**/a/**/"
-  ,"test/+(a|b|c)/a{/,bc*}/**"
-  ,"test/*/*/*/f"
-  ,"test/**/f"
-  ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
-  ,"{./*/*,/usr/local/*}"
-  ,"{/*,*}" // evil owl face!  how you taunt me!
-  ]
+, bashResults = require("./bash-results.json")
+, globs = Object.keys(bashResults)
 , glob = require("../")
 , path = require("path")
 
@@ -35,84 +18,46 @@ function alphasort (a, b) {
 }
 
 globs.forEach(function (pattern) {
-  var echoOutput
-  tap.test(pattern, function (t) {
-    var bashPattern = pattern
-    , cmd = "shopt -s globstar && " +
-            "shopt -s extglob && " +
-            "shopt -s nullglob && " +
-            // "shopt >&2; " +
-            "eval \'for i in " + bashPattern + "; do echo $i; done\'"
-    , cp = child_process.spawn("bash", ["-c",cmd])
-    , out = []
-    , globResult
-    cp.stdout.on("data", function (c) {
-      out.push(c)
-    })
-    cp.stderr.on("data", function (c) {
-      process.stderr.write(c)
-    })
-    cp.on("close", function () {
-      echoOutput = flatten(out)
-      if (!echoOutput) echoOutput = []
-      else {
-        echoOutput = echoOutput.split(/\r*\n/).map(function (m) {
-          // Bash is a oddly inconsistent with slashes in the
-          // the results.  This implementation is a bit more
-          // normalized.  Account for this in the test results.
-          return m.replace(/\/+/g, "/").replace(/\/$/, "")
-        }).sort(alphasort).reduce(function (set, f) {
-          if (f !== set[set.length - 1]) set.push(f)
-          return set
-        }, []).sort(alphasort)
-      }
-      next()
-    })
+  var expect = bashResults[pattern]
+  // anything regarding the symlink thing will fail on windows, so just skip it
+  if (process.platform === "win32" &&
+      expect.some(function (m) {
+        return /\/symlink\//.test(m)
+      }))
+    return
 
+  tap.test(pattern, function (t) {
     glob(pattern, function (er, matches) {
-      // sort and unpark, just to match the shell results
-      matches = matches.map(function (m) {
-        return m.replace(/\/+/g, "/").replace(/\/$/, "")
-      }).sort(alphasort).reduce(function (set, f) {
-        if (f !== set[set.length - 1]) set.push(f)
-        return set
-      }, []).sort(alphasort)
-
-      t.ifError(er, pattern + " should not error")
-      globResult = matches
-      next()
-    })
+      if (er)
+        throw er
 
-    function next () {
-      if (!echoOutput || !globResult) return
+      // sort and unmark, just to match the shell results
+      matches = cleanResults(matches)
 
-      t.deepEqual(globResult, echoOutput, "should match shell")
+      t.deepEqual(matches, expect, pattern)
       t.end()
-    }
+    })
   })
 
   tap.test(pattern + " sync", function (t) {
-    var matches = glob.sync(pattern).map(function (m) {
-        return m.replace(/\/+/g, "/").replace(/\/$/, "")
-      }).sort(alphasort).reduce(function (set, f) {
-        if (f !== set[set.length - 1]) set.push(f)
-        return set
-      }, []).sort(alphasort)
+    var matches = cleanResults(glob.sync(pattern))
 
-    t.deepEqual(matches, echoOutput, "should match shell")
+    t.deepEqual(matches, expect, "should match shell")
     t.end()
   })
 })
 
-function flatten (chunks) {
-  var s = 0
-  chunks.forEach(function (c) { s += c.length })
-  var out = new Buffer(s)
-  s = 0
-  chunks.forEach(function (c) {
-    c.copy(out, s)
-    s += c.length
+function cleanResults (m) {
+  // normalize discrepancies in ordering, duplication,
+  // and ending slashes.
+  return m.map(function (m) {
+    return m.replace(/\/+/g, "/").replace(/\/$/, "")
+  }).sort(alphasort).reduce(function (set, f) {
+    if (f !== set[set.length - 1]) set.push(f)
+    return set
+  }, []).sort(alphasort).map(function (f) {
+    // de-windows
+    return (process.platform !== 'win32') ? f
+           : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/')
   })
-
-  return out.toString().trim()
 }
diff --git a/deps/npm/node_modules/glob/test/bash-results.json b/deps/npm/node_modules/glob/test/bash-results.json
new file mode 100644 (file)
index 0000000..8c341db
--- /dev/null
@@ -0,0 +1,347 @@
+{
+  "test/a/*/+(c|g)/./d": [
+    "test/a/b/c/./d"
+  ],
+  "test/a/**/[cg]/../[cg]": [
+    "test/a/abcdef/g/../g",
+    "test/a/abcfed/g/../g",
+    "test/a/b/c/../c",
+    "test/a/c/../c",
+    "test/a/c/d/c/../c",
+    "test/a/symlink/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c"
+  ],
+  "test/a/{b,c,d,e,f}/**/g": [],
+  "test/a/b/**": [
+    "test/a/b",
+    "test/a/b/c",
+    "test/a/b/c/d"
+  ],
+  "test/**/g": [
+    "test/a/abcdef/g",
+    "test/a/abcfed/g"
+  ],
+  "test/a/abc{fed,def}/g/h": [
+    "test/a/abcdef/g/h",
+    "test/a/abcfed/g/h"
+  ],
+  "test/a/abc{fed/g,def}/**/": [
+    "test/a/abcdef",
+    "test/a/abcdef/g",
+    "test/a/abcfed/g"
+  ],
+  "test/a/abc{fed/g,def}/**///**/": [
+    "test/a/abcdef",
+    "test/a/abcdef/g",
+    "test/a/abcfed/g"
+  ],
+  "test/**/a/**/": [
+    "test/a",
+    "test/a/abcdef",
+    "test/a/abcdef/g",
+    "test/a/abcfed",
+    "test/a/abcfed/g",
+    "test/a/b",
+    "test/a/b/c",
+    "test/a/bc",
+    "test/a/bc/e",
+    "test/a/c",
+    "test/a/c/d",
+    "test/a/c/d/c",
+    "test/a/cb",
+    "test/a/cb/e",
+    "test/a/symlink",
+    "test/a/symlink/a",
+    "test/a/symlink/a/b",
+    "test/a/symlink/a/b/c",
+    "test/a/symlink/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b"
+  ],
+  "test/+(a|b|c)/a{/,bc*}/**": [
+    "test/a/abcdef",
+    "test/a/abcdef/g",
+    "test/a/abcdef/g/h",
+    "test/a/abcfed",
+    "test/a/abcfed/g",
+    "test/a/abcfed/g/h"
+  ],
+  "test/*/*/*/f": [
+    "test/a/bc/e/f",
+    "test/a/cb/e/f"
+  ],
+  "test/**/f": [
+    "test/a/bc/e/f",
+    "test/a/cb/e/f"
+  ],
+  "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c"
+  ],
+  "{./*/*,/tmp/glob-test/*}": [
+    "./examples/g.js",
+    "./examples/usr-local.js",
+    "./node_modules/graceful-fs",
+    "./node_modules/inherits",
+    "./node_modules/minimatch",
+    "./node_modules/mkdirp",
+    "./node_modules/rimraf",
+    "./node_modules/tap",
+    "./test/00-setup.js",
+    "./test/a",
+    "./test/bash-comparison.js",
+    "./test/bash-results.json",
+    "./test/cwd-test.js",
+    "./test/mark.js",
+    "./test/pause-resume.js",
+    "./test/root-nomount.js",
+    "./test/root.js",
+    "./test/zz-cleanup.js",
+    "/tmp/glob-test/asdf",
+    "/tmp/glob-test/bar",
+    "/tmp/glob-test/baz",
+    "/tmp/glob-test/foo",
+    "/tmp/glob-test/quux",
+    "/tmp/glob-test/qwer",
+    "/tmp/glob-test/rewq"
+  ],
+  "{/tmp/glob-test/*,*}": [
+    "/tmp/glob-test/asdf",
+    "/tmp/glob-test/bar",
+    "/tmp/glob-test/baz",
+    "/tmp/glob-test/foo",
+    "/tmp/glob-test/quux",
+    "/tmp/glob-test/qwer",
+    "/tmp/glob-test/rewq",
+    "examples",
+    "glob.js",
+    "LICENSE",
+    "node_modules",
+    "package.json",
+    "README.md",
+    "test"
+  ],
+  "test/a/!(symlink)/**": [
+    "test/a/abcdef",
+    "test/a/abcdef/g",
+    "test/a/abcdef/g/h",
+    "test/a/abcfed",
+    "test/a/abcfed/g",
+    "test/a/abcfed/g/h",
+    "test/a/b",
+    "test/a/b/c",
+    "test/a/b/c/d",
+    "test/a/bc",
+    "test/a/bc/e",
+    "test/a/bc/e/f",
+    "test/a/c",
+    "test/a/c/d",
+    "test/a/c/d/c",
+    "test/a/c/d/c/b",
+    "test/a/cb",
+    "test/a/cb/e",
+    "test/a/cb/e/f"
+  ]
+}
index fda66f8..ed68a33 100644 (file)
@@ -6,13 +6,17 @@ test("mark, no / on pattern", function (t) {
   glob("a/*", {mark: true}, function (er, results) {
     if (er)
       throw er
-    t.same(results, [ 'a/abcdef/',
-                      'a/abcfed/',
-                      'a/b/',
-                      'a/bc/',
-                      'a/c/',
-                      'a/cb/',
-                      'a/symlink/' ])
+    var expect = [ 'a/abcdef/',
+                   'a/abcfed/',
+                   'a/b/',
+                   'a/bc/',
+                   'a/c/',
+                   'a/cb/' ]
+
+    if (process.platform !== "win32")
+      expect.push('a/symlink/')
+
+    t.same(results, expect)
     t.end()
   })
 })
@@ -21,13 +25,16 @@ test("mark=false, no / on pattern", function (t) {
   glob("a/*", function (er, results) {
     if (er)
       throw er
-    t.same(results, [ 'a/abcdef',
-                      'a/abcfed',
-                      'a/b',
-                      'a/bc',
-                      'a/c',
-                      'a/cb',
-                      'a/symlink' ])
+    var expect = [ 'a/abcdef',
+                   'a/abcfed',
+                   'a/b',
+                   'a/bc',
+                   'a/c',
+                   'a/cb' ]
+
+    if (process.platform !== "win32")
+      expect.push('a/symlink')
+    t.same(results, expect)
     t.end()
   })
 })
@@ -36,13 +43,15 @@ test("mark=true, / on pattern", function (t) {
   glob("a/*/", {mark: true}, function (er, results) {
     if (er)
       throw er
-    t.same(results, [ 'a/abcdef/',
-                      'a/abcfed/',
-                      'a/b/',
-                      'a/bc/',
-                      'a/c/',
-                      'a/cb/',
-                      'a/symlink/' ])
+    var expect = [ 'a/abcdef/',
+                    'a/abcfed/',
+                    'a/b/',
+                    'a/bc/',
+                    'a/c/',
+                    'a/cb/' ]
+    if (process.platform !== "win32")
+      expect.push('a/symlink/')
+    t.same(results, expect)
     t.end()
   })
 })
@@ -51,13 +60,15 @@ test("mark=false, / on pattern", function (t) {
   glob("a/*/", function (er, results) {
     if (er)
       throw er
-    t.same(results, [ 'a/abcdef/',
-                      'a/abcfed/',
-                      'a/b/',
-                      'a/bc/',
-                      'a/c/',
-                      'a/cb/',
-                      'a/symlink/' ])
+    var expect = [ 'a/abcdef/',
+                   'a/abcfed/',
+                   'a/b/',
+                   'a/bc/',
+                   'a/c/',
+                   'a/cb/' ]
+    if (process.platform !== "win32")
+      expect.push('a/symlink/')
+    t.same(results, expect)
     t.end()
   })
 })
index c848ed2..e1ffbab 100644 (file)
@@ -3,6 +3,8 @@ var tap = require("tap")
 , child_process = require("child_process")
 // just some gnarly pattern with lots of matches
 , pattern = "test/a/!(symlink)/**"
+, bashResults = require("./bash-results.json")
+, patterns = Object.keys(bashResults)
 , glob = require("../")
 , Glob = glob.Glob
 , path = require("path")
@@ -25,54 +27,19 @@ function cleanResults (m) {
   }).sort(alphasort).reduce(function (set, f) {
     if (f !== set[set.length - 1]) set.push(f)
     return set
-  }, []).sort(alphasort)
-}
-
-function flatten (chunks) {
-  var s = 0
-  chunks.forEach(function (c) { s += c.length })
-  var out = new Buffer(s)
-  s = 0
-  chunks.forEach(function (c) {
-    c.copy(out, s)
-    s += c.length
+  }, []).sort(alphasort).map(function (f) {
+    // de-windows
+    return (process.platform !== 'win32') ? f
+           : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
   })
-
-  return out.toString().trim()
 }
-var bashResults
-tap.test("get bash output", function (t) {
-  var bashPattern = pattern
-  , cmd = "shopt -s globstar && " +
-          "shopt -s extglob && " +
-          "shopt -s nullglob && " +
-          // "shopt >&2; " +
-          "eval \'for i in " + bashPattern + "; do echo $i; done\'"
-  , cp = child_process.spawn("bash", ["-c",cmd])
-  , out = []
-  , globResult
-  cp.stdout.on("data", function (c) {
-    out.push(c)
-  })
-  cp.stderr.on("data", function (c) {
-    process.stderr.write(c)
-  })
-  cp.on("close", function () {
-    bashResults = flatten(out)
-    if (!bashResults) return t.fail("Didn't get results from bash")
-    else {
-      bashResults = cleanResults(bashResults.split(/\r*\n/))
-    }
-    t.ok(bashResults.length, "got some results")
-    t.end()
-  })
-})
 
 var globResults = []
 tap.test("use a Glob object, and pause/resume it", function (t) {
   var g = new Glob(pattern)
   , paused = false
   , res = []
+  , expect = bashResults[pattern]
 
   g.on("pause", function () {
     console.error("pause")
@@ -97,7 +64,7 @@ tap.test("use a Glob object, and pause/resume it", function (t) {
     t.deepEqual(matches, globResults,
       "end event matches should be the same as match events")
 
-    t.deepEqual(matches, bashResults,
+    t.deepEqual(matches, expect,
       "glob matches should be the same as bash results")
 
     t.end()
index 5ccdd0e..95c23f9 100644 (file)
@@ -1,43 +1,46 @@
-var tap = require("tap")
+var t = require("tap")
 
 var origCwd = process.cwd()
 process.chdir(__dirname)
 
-tap.test("changing root and searching for /b*/**", function (t) {
-  var glob = require('../')
-  var path = require('path')
-  t.test('.', function (t) {
-    glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
-      t.ifError(er)
-      t.like(matches, [])
-      t.end()
-    })
-  })
+var glob = require('../')
+var path = require('path')
 
-  t.test('a', function (t) {
-    glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
-      t.ifError(er)
-      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
-        return path.join(path.resolve('a'), m)
-      }))
-      t.end()
-    })
+t.test('.', function (t) {
+  glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
+    t.ifError(er)
+    t.like(matches, [])
+    t.end()
   })
+})
+
 
-  t.test('root=a, cwd=a/b', function (t) {
-    glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
-      t.ifError(er)
-      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
-        return path.join(path.resolve('a'), m)
-      }))
-      t.end()
-    })
+t.test('a', function (t) {
+  console.error("root=" + path.resolve('a'))
+  glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
+    t.ifError(er)
+    var wanted = [
+        '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'
+      ].map(function (m) {
+        return path.join(path.resolve('a'), m).replace(/\\/g, '/')
+      })
+
+    t.like(matches, wanted)
+    t.end()
   })
+})
 
-  t.test('cd -', function (t) {
-    process.chdir(origCwd)
+t.test('root=a, cwd=a/b', function (t) {
+  glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
+    t.ifError(er)
+    t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
+      return path.join(path.resolve('a'), m).replace(/\\/g, '/')
+    }))
     t.end()
   })
+})
 
+t.test('cd -', function (t) {
+  process.chdir(origCwd)
   t.end()
 })
index 5e02e66..5f74155 100644 (file)
@@ -17,6 +17,7 @@
 
     'conditions': [
       [ 'OS=="mac"', {
+        'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
         'libraries': [ '-undefined dynamic_lookup' ],
         'xcode_settings': {
           'DYLIB_INSTALL_NAME_BASE': '@rpath'
@@ -27,6 +28,9 @@
         # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>'
         # needs to have dll-interface to be used by clients of class 'node::ObjectWrap'
         'msvs_disabled_warnings': [ 4251 ],
+      }, {
+        # OS!="win"
+        'defines': [ '_LARGEFILE_SOURCE', '_FILE_OFFSET_BITS=64' ],
       }],
       [ 'OS=="freebsd" or OS=="openbsd" or OS=="solaris" or (OS=="linux" and target_arch!="ia32")', {
         'cflags': [ '-fPIC' ],
index 811a533..76f69f5 100644 (file)
@@ -10,7 +10,7 @@
     "bindings",
     "gyp"
   ],
-  "version": "0.8.2",
+  "version": "0.8.3",
   "installVersion": 9,
   "author": {
     "name": "Nathan Rajlich",
@@ -46,9 +46,6 @@
   },
   "readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n  * On Unix:\n    * `python`\n    * `make`\n    * A proper C/C++ compiler toolchain, like GCC\n  * On Windows:\n    * [Python][windows-python] ([`v2.7.3`][windows-python-v2.7.3] recommended, `v3.x.x` is __*not*__ supported)\n    * Windows XP/Vista/7:\n      * Microsoft Visual Studio C++ 2010 ([Express][msvc2010] version works well)\n      * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]\n      * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]\n    * Windows 8:\n      * Microsoft Visual Studio C++ 2012 for Windows Desktop ([Express][msvc2012] version works well)\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n  \"targets\": [\n    {\n      \"target_name\": \"binding\",\n      \"sources\": [ \"src/binding.cc\" ]\n    }\n  ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * [*\"binding.gyp\" files out in the wild* wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n| **Command**   | **Description**\n|:--------------|:---------------------------------------------------------------\n| `build`       | Invokes `make`/`msbuild.exe` and builds the native addon\n| `clean`       | Removes any the `build` dir if it exists\n| `configure`   | Generates project build files for the current platform\n| `rebuild`     | Runs \"clean\", \"configure\" and \"build\" all in a row\n| `install`     | Installs node development header files for the given version\n| `list`        | Lists the currently installed node development file versions\n| `remove`      | Removes the node development header files for the given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich &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.3]: http://www.python.org/download/releases/2.7.3#download\n[msvc2010]: http://go.microsoft.com/?linkid=9709949\n[msvc2012]: http://go.microsoft.com/?linkid=9816758\n[win7sdk]: http://www.microsoft.com/en-us/download/details.aspx?id=8279\n[compiler update for the Windows SDK 7.1]: http://www.microsoft.com/en-us/download/details.aspx?id=4422\n",
   "readmeFilename": "README.md",
-  "_id": "node-gyp@0.8.2",
-  "dist": {
-    "shasum": "d1a72a944a16a97b91ed3ea2f2ec6e7c0826c294"
-  },
+  "_id": "node-gyp@0.8.3",
   "_from": "node-gyp@~0.8.1"
 }
index 4b180a0..22751c4 100644 (file)
@@ -37,7 +37,7 @@ also be accepted.
 * `strict-ssl` {Boolean} Whether or not to be strict with SSL
   certificates.  Default = `true`
 * `user-agent` {String} User agent header to send.  Default =
-  `"node/{process.version}"`
+  `"node/{process.version} {process.platform} {process.arch}"`
 * `log` {Object} The logger to use.  Defaults to `require("npmlog")` if
   that works, otherwise logs are disabled.
 * `fetch-retries` {Number} Number of times to retry on GET failures.
index 6e74fee..080c406 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "npm-registry-client",
   "description": "Client for the npm registry",
-  "version": "0.2.11",
+  "version": "0.2.12",
   "repository": {
     "url": "git://github.com/isaacs/npm-registry-client"
   },
@@ -33,8 +33,8 @@
     "npmlog": ""
   },
   "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(config)\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# Configuration\n\nThis program is designed to work with\n[npmconf](https://npmjs.org/package/npmconf), but you can also pass in\na plain-jane object with the appropriate configs, and it'll shim it\nfor you.  Any configuration thingie that has get/set/del methods will\nalso be accepted.\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `always-auth` {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* `strict-ssl` {Boolean} Whether or not to be strict with SSL\n  certificates.  Default = `true`\n* `user-agent` {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* `fetch-retries` {Number} Number of times to retry on GET failures.\n  Default=2\n* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10\n* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.\n  Default=10000 (10 seconds)\n* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.\n  Default=60000 (60 seconds)\n* `proxy` {URL} The url to proxy requests through.\n* `https-proxy` {URL} The url to proxy https requests through.\n  Defaults to be the same as `proxy` if unset.\n* `_auth` {String} The base64-encoded authorization header.\n* `username` `_password` {String} Username/password to use to generate\n  `_auth` if not supplied.\n* `_token` {Object} A token for use with\n  [couch-login](https://npmjs.org/package/couch-login)\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",
+  "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(config)\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# Configuration\n\nThis program is designed to work with\n[npmconf](https://npmjs.org/package/npmconf), but you can also pass in\na plain-jane object with the appropriate configs, and it'll shim it\nfor you.  Any configuration thingie that has get/set/del methods will\nalso be accepted.\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `always-auth` {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* `strict-ssl` {Boolean} Whether or not to be strict with SSL\n  certificates.  Default = `true`\n* `user-agent` {String} User agent header to send.  Default =\n  `\"node/{process.version} {process.platform} {process.arch}\"`\n* `log` {Object} The logger to use.  Defaults to `require(\"npmlog\")` if\n  that works, otherwise logs are disabled.\n* `fetch-retries` {Number} Number of times to retry on GET failures.\n  Default=2\n* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10\n* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.\n  Default=10000 (10 seconds)\n* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.\n  Default=60000 (60 seconds)\n* `proxy` {URL} The url to proxy requests through.\n* `https-proxy` {URL} The url to proxy https requests through.\n  Defaults to be the same as `proxy` if unset.\n* `_auth` {String} The base64-encoded authorization header.\n* `username` `_password` {String} Username/password to use to generate\n  `_auth` if not supplied.\n* `_token` {Object} A token for use with\n  [couch-login](https://npmjs.org/package/couch-login)\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",
   "readmeFilename": "README.md",
-  "_id": "npm-registry-client@0.2.11",
-  "_from": "npm-registry-client@0.2.11"
+  "_id": "npm-registry-client@0.2.12",
+  "_from": "npm-registry-client@~0.2.10"
 }
index 7a6f56b..d443781 100644 (file)
@@ -82,8 +82,15 @@ var defaults
 var temp = osenv.tmpdir()
 var home = osenv.home()
 
+var uidOrPid = process.getuid ? process.getuid() : process.pid
+
 if (home) process.env.HOME = home
-else home = temp
+else home = path.resolve(temp, "npm-" + uidOrPid)
+
+var cacheExtra = process.platform === "win32" ? "npm-cache" : ".npm"
+var cacheRoot = process.platform === "win32" && process.env.APPDATA || home
+var cache = path.resolve(cacheRoot, cacheExtra)
+
 
 var globalPrefix
 Object.defineProperty(exports, "defaults", {get: function () {
@@ -169,9 +176,7 @@ Object.defineProperty(exports, "defaults", {get: function () {
         "-----END CERTIFICATE-----\n" ]
 
 
-    , cache : process.platform === "win32"
-            ? path.resolve(process.env.APPDATA || home || temp, "npm-cache")
-            : path.resolve( home || temp, ".npm")
+    , cache : cache
 
     , "cache-lock-stale": 60000
     , "cache-lock-retries": 10
@@ -227,6 +232,8 @@ Object.defineProperty(exports, "defaults", {get: function () {
     , "https-proxy" : process.env.HTTPS_PROXY || process.env.https_proxy ||
                       process.env.HTTP_PROXY || process.env.http_proxy || null
     , "user-agent" : "node/" + process.version
+                     + ' ' + process.platform
+                     + ' ' + process.arch
     , "rebuild-bundle" : true
     , registry : "https://registry.npmjs.org/"
     , rollback : true
index 65348d5..3199cbf 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "npmconf",
-  "version": "0.0.17",
+  "version": "0.0.19",
   "description": "The config thing npm uses",
   "main": "npmconf.js",
   "directories": {
@@ -37,6 +37,6 @@
   "license": "BSD",
   "readme": "# npmconf\n\nThe config thing npm uses\n\nIf you are interested in interacting with the config settings that npm\nuses, then use this module.\n\nHowever, if you are writing a new Node.js program, and want\nconfiguration functionality similar to what npm has, but for your\nown thing, then I'd recommend using [rc](https://github.com/dominictarr/rc),\nwhich is probably what you want.\n\nIf I were to do it all over again, that's what I'd do for npm.  But,\nalas, there are many systems depending on many of the particulars of\nnpm's configuration setup, so it's not worth the cost of changing.\n\n## USAGE\n\n```javascript\nvar npmconf = require('npmconf')\n\n// pass in the cli options that you read from the cli\n// or whatever top-level configs you want npm to use for now.\nnpmconf.load({some:'configs'}, function (er, conf) {\n  // do stuff with conf\n  conf.get('some', 'cli') // 'configs'\n  conf.get('username') // 'joebobwhatevers'\n  conf.set('foo', 'bar', 'user')\n  conf.save('user', function (er) {\n    // foo = bar is now saved to ~/.npmrc or wherever\n  })\n})\n```\n",
   "readmeFilename": "README.md",
-  "_id": "npmconf@0.0.17",
+  "_id": "npmconf@0.0.19",
   "_from": "npmconf@latest"
 }
index e05c5a9..91d01c2 100644 (file)
@@ -1,7 +1,7 @@
 {
   "name": "read-installed",
   "description": "Read all the installed packages in a folder, and return a tree structure with all the data.",
-  "version": "0.0.4",
+  "version": "0.1.0",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/read-installed"
   },
   "readme": "# read-installed\n\nRead all the installed packages in a folder, and return a tree\nstructure with all the data.\n\nnpm uses this.\n\n## Usage\n\n```javascript\nvar readInstalled = require(\"read-installed\")\n// depth is optional, defaults to Infinity\nreadInstalled(folder, depth, function (er, data) {\n  ...\n})\n```\n",
   "readmeFilename": "README.md",
-  "_id": "read-installed@0.0.4",
-  "_from": "read-installed@latest"
+  "_id": "read-installed@0.1.0",
+  "dist": {
+    "shasum": "27b1358951086bc9b69d527961d9e04a27c921d1"
+  },
+  "_from": "read-installed@0.1.0",
+  "_resolved": "https://registry.npmjs.org/read-installed/-/read-installed-0.1.0.tgz"
 }
index 192907c..4babfc8 100644 (file)
@@ -121,8 +121,6 @@ function readInstalled (folder, depth, cb) {
 
 var rpSeen = {}
 function readInstalled_ (folder, parent, name, reqver, depth, maxDepth, cb) {
-  //console.error(folder, name)
-
   var installed
     , obj
     , real
@@ -251,6 +249,7 @@ function resolveInheritance (obj) {
   Object.keys(obj.dependencies).forEach(function (dep) {
     resolveInheritance(obj.dependencies[dep])
   })
+  findUnmet(obj)
 }
 
 // find unmet deps by walking up the tree object.
@@ -261,6 +260,7 @@ function findUnmet (obj) {
   fuSeen.push(obj)
   //console.error("find unmet", obj.name, obj.parent && obj.parent.name)
   var deps = obj.dependencies = obj.dependencies || {}
+
   //console.error(deps)
   Object.keys(deps)
     .filter(function (d) { return typeof deps[d] === "string" })
@@ -297,8 +297,21 @@ function findUnmet (obj) {
 
   var peerDeps = obj.peerDependencies = obj.peerDependencies || {}
   Object.keys(peerDeps).forEach(function (d) {
-    var dependency = obj.parent && obj.parent.dependencies &&
-      obj.parent.dependencies[d]
+    var dependency
+
+    if (!obj.parent) {
+      dependency = obj.dependencies[d]
+
+      // read it as a missing dep
+      if (!dependency) {
+        obj.dependencies[d] = peerDeps[d]
+      }
+    } else {
+      dependency = obj.parent.dependencies && obj.parent.dependencies[d]
+    }
+
+    if (!dependency) return
+
     dependency.extraneous = false
 
     if (!semver.satisfies(dependency.version, peerDeps[d])) {
index ce7e1dd..3063a89 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "rimraf",
-  "version": "2.1.1",
+  "version": "2.1.2",
   "main": "rimraf.js",
   "description": "A deep deletion module for node (like `rm -rf`)",
   "author": {
   ],
   "readme": "A `rm -rf` for node.\n\nInstall with `npm install rimraf`, or just drop rimraf.js somewhere.\n\n## API\n\n`rimraf(f, callback)`\n\nThe callback will be called with an error if there is one.  Certain\nerrors are handled for you:\n\n* `EBUSY` -  rimraf will back off a maximum of opts.maxBusyTries times\n  before giving up.\n* `EMFILE` - If too many file descriptors get opened, rimraf will\n  patiently wait until more become available.\n\n\n## rimraf.sync\n\nIt can remove stuff synchronously, too.  But that's not so good.  Use\nthe async API.  It's better.\n",
   "readmeFilename": "README.md",
-  "_id": "rimraf@2.1.1",
+  "_id": "rimraf@2.1.2",
   "dependencies": {
     "graceful-fs": "~1.1"
   },
-  "dist": {
-    "shasum": "ee9cec7e2d796ef59ceaa5f3a3024c225e630c61"
-  },
-  "_from": "rimraf@2.1.1"
+  "_from": "rimraf@2"
 }
index 7fc291c..6a67fb4 100644 (file)
@@ -69,6 +69,16 @@ function rimraf_ (p, cb) {
 }
 
 function rmdir (p, cb) {
+  // try to rmdir first, and only readdir on ENOTEMPTY
+  fs.rmdir(p, function (er) {
+    if (er && er.code === "ENOTEMPTY")
+      rmkids(p, cb)
+    else
+      cb(er)
+  })
+}
+
+function rmkids(p, cb) {
   fs.readdir(p, function (er, files) {
     if (er)
       return cb(er)
index cd6b792..bfc830e 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "version": "1.2.2",
+  "version": "1.2.3",
   "name": "npm",
   "publishConfig": {
     "proprietary-attribs": false