<p>This function should not be used programmatically. Instead, just refer
to the <code>npm.bin</code> member.</p>
</div>
-<p id="footer">bin — npm@1.1.10</p>
+<p id="footer">bin — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This command will launch a browser, so this command may not be the most
friendly for programmatic use.</p>
</div>
-<p id="footer">bugs — npm@1.1.10</p>
+<p id="footer">bugs — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">commands — npm@1.1.10</p>
+<p id="footer">commands — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">config — npm@1.1.10</p>
+<p id="footer">config — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../api/unpublish.html">unpublish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">deprecate — npm@1.1.10</p>
+<p id="footer">deprecate — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This command will launch a browser, so this command may not be the most
friendly for programmatic use.</p>
</div>
-<p id="footer">docs — npm@1.1.10</p>
+<p id="footer">docs — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Since this command opens an editor in a new process, be careful about where
and how this is used.</p>
</div>
-<p id="footer">edit — npm@1.1.10</p>
+<p id="footer">edit — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The first element in the 'args' parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p>
</div>
-<p id="footer">explore — npm@1.1.10</p>
+<p id="footer">explore — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The silent parameter is not neccessary not used, but it may in the future.</p>
</div>
-<p id="footer">help-search — npm@1.1.10</p>
+<p id="footer">help-search — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p><a href="../doc/json.html">json(1)</a></p>
</div>
-<p id="footer">init — npm@1.1.10</p>
+<p id="footer">init — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when all packages have been
installed or when an error has been encountered.</p>
</div>
-<p id="footer">install — npm@1.1.10</p>
+<p id="footer">install — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Now, any changes to the redis package will be reflected in
the package in the current working directory</p>
</div>
-<p id="footer">link — npm@1.1.10</p>
+<p id="footer">link — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>For a list of all the available command-line configs, see <code>npm help config</code></p>
</div>
-<p id="footer">load — npm@1.1.10</p>
+<p id="footer">load — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
This means that if a submodule a same dependency as a parent module, then the
dependency will only be output once.</p>
</div>
-<p id="footer">ls — npm@1.1.10</p>
+<p id="footer">ls — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.10</p>
+<p>1.1.14</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre>
</div>
-<p id="footer">npm — npm@1.1.10</p>
+<p id="footer">npm — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If the 'packages' parameter is left out, npm will check all packages.</p>
</div>
-<p id="footer">outdated — npm@1.1.10</p>
+<p id="footer">outdated — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">owner — npm@1.1.10</p>
+<p id="footer">owner — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If no arguments are supplied, then npm packs the current package folder.</p>
</div>
-<p id="footer">pack — npm@1.1.10</p>
+<p id="footer">pack — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">prefix — npm@1.1.10</p>
+<p id="footer">prefix — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Extraneous packages are packages that are not listed on the parent
package's dependencies list.</p>
</div>
-<p id="footer">prune — npm@1.1.10</p>
+<p id="footer">prune — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../api/owner.html">owner(3)</a></li></ul>
</div>
-<p id="footer">publish — npm@1.1.10</p>
+<p id="footer">publish — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>See <code>npm help build</code></p>
</div>
-<p id="footer">rebuild — npm@1.1.10</p>
+<p id="footer">rebuild — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
</div>
-<p id="footer">restart — npm@1.1.10</p>
+<p id="footer">restart — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically.</p>
</div>
-<p id="footer">root — npm@1.1.10</p>
+<p id="footer">root — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../api/test.html">test(3)</a></li><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/restart.html">restart(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
</div>
-<p id="footer">run-script — npm@1.1.10</p>
+<p id="footer">run-script — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
and doesn't try to read your mind (it doesn't do any verb tense matching or the
like).</p>
</div>
-<p id="footer">search — npm@1.1.10</p>
+<p id="footer">search — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when the shrinkwrap has
been saved.</p>
</div>
-<p id="footer">shrinkwrap — npm@1.1.10</p>
+<p id="footer">shrinkwrap — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">start — npm@1.1.10</p>
+<p id="footer">start — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run stop on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">stop — npm@1.1.10</p>
+<p id="footer">stop — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li>npm help json</li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule — npm@1.1.10</p>
+<p id="footer">submodule — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
used. For more information about how to set this config, check
<code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p>
</div>
-<p id="footer">tag — npm@1.1.10</p>
+<p id="footer">tag — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">test — npm@1.1.10</p>
+<p id="footer">test — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when all packages have been
uninstalled or when an error has been encountered.</p>
</div>
-<p id="footer">uninstall — npm@1.1.10</p>
+<p id="footer">uninstall — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If no version is specified, or if all versions are removed then
the root package entry is removed from the registry entirely.</p>
</div>
-<p id="footer">unpublish — npm@1.1.10</p>
+<p id="footer">unpublish — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.</p>
</div>
-<p id="footer">update — npm@1.1.10</p>
+<p id="footer">update — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
parameter. The difference, however, is this function will fail if it does
not have exactly one element. The only element should be a version number.</p>
</div>
-<p id="footer">version — npm@1.1.10</p>
+<p id="footer">version — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>corresponding to the list of fields selected.</p>
</div>
-<p id="footer">view — npm@1.1.10</p>
+<p id="footer">view — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">whoami — npm@1.1.10</p>
+<p id="footer">whoami — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.10</p>
+<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li></ul>
</div>
-<p id="footer">adduser — npm@1.1.10</p>
+<p id="footer">adduser — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">bin — npm@1.1.10</p>
+<p id="footer">bin — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/docs.html">docs(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">bugs — npm@1.1.10</p>
+<p id="footer">bugs — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">build — npm@1.1.10</p>
+<p id="footer">build — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">bundle — npm@1.1.10</p>
+<p id="footer">bundle — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li></ul>
</div>
-<p id="footer">cache — npm@1.1.10</p>
+<p id="footer">cache — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li></ul>
</div>
-<p id="footer">changelog — npm@1.1.10</p>
+<p id="footer">changelog — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">coding-style — npm@1.1.10</p>
+<p id="footer">coding-style — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">completion — npm@1.1.10</p>
+<p id="footer">completion — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
</div>
-<p id="footer">config — npm@1.1.10</p>
+<p id="footer">config — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">deprecate — npm@1.1.10</p>
+<p id="footer">deprecate — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
</div>
-<p id="footer">developers — npm@1.1.10</p>
+<p id="footer">developers — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
</div>
-<p id="footer">disputes — npm@1.1.10</p>
+<p id="footer">disputes — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">docs — npm@1.1.10</p>
+<p id="footer">docs — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/explore.html">explore(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">edit — npm@1.1.10</p>
+<p id="footer">edit — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/submodule.html">submodule(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/edit.html">edit(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">explore — npm@1.1.10</p>
+<p id="footer">explore — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
</div>
-<p id="footer">faq — npm@1.1.10</p>
+<p id="footer">faq — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
</div>
-<p id="footer">folders — npm@1.1.10</p>
+<p id="footer">folders — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li></ul>
</div>
-<p id="footer">help-search — npm@1.1.10</p>
+<p id="footer">help-search — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/help-search.html">help-search(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">help — npm@1.1.10</p>
+<p id="footer">help — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p> Display npm username</p>
</div>
-<p id="footer">index — npm@1.1.10</p>
+<p id="footer">index — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
</div>
-<p id="footer">init — npm@1.1.10</p>
+<p id="footer">init — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></li></ul>
</div>
-<p id="footer">install — npm@1.1.10</p>
+<p id="footer">install — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/semver.html">semver(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/version.html">version(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li></ul>
</div>
-<p id="footer">json — npm@1.1.10</p>
+<p id="footer">json — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">link — npm@1.1.10</p>
+<p id="footer">link — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/update.html">update(1)</a></li></ul>
</div>
-<p id="footer">list — npm@1.1.10</p>
+<p id="footer">list — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.10</p>
+<p>1.1.14</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<ul><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/index.html">index(1)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">npm — npm@1.1.10</p>
+<p id="footer">npm — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
</div>
-<p id="footer">outdated — npm@1.1.10</p>
+<p id="footer">outdated — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
</div>
-<p id="footer">owner — npm@1.1.10</p>
+<p id="footer">owner — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">pack — npm@1.1.10</p>
+<p id="footer">pack — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">prefix — npm@1.1.10</p>
+<p id="footer">prefix — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">prune — npm@1.1.10</p>
+<p id="footer">prune — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li></ul>
</div>
-<p id="footer">publish — npm@1.1.10</p>
+<p id="footer">publish — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">rebuild — npm@1.1.10</p>
+<p id="footer">rebuild — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
</div>
-<p id="footer">registry — npm@1.1.10</p>
+<p id="footer">registry — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/README.html">README</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li></ul>
</div>
-<p id="footer">removing-npm — npm@1.1.10</p>
+<p id="footer">removing-npm — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">restart — npm@1.1.10</p>
+<p id="footer">restart — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">root — npm@1.1.10</p>
+<p id="footer">root — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">run-script — npm@1.1.10</p>
+<p id="footer">run-script — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">scripts — npm@1.1.10</p>
+<p id="footer">scripts — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/view.html">view(1)</a></li></ul>
</div>
-<p id="footer">search — npm@1.1.10</p>
+<p id="footer">search — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">semver — npm@1.1.10</p>
+<p id="footer">semver — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">shrinkwrap — npm@1.1.10</p>
+<p id="footer">shrinkwrap — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">star — npm@1.1.10</p>
+<p id="footer">star — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">start — npm@1.1.10</p>
+<p id="footer">start — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li></ul>
</div>
-<p id="footer">stop — npm@1.1.10</p>
+<p id="footer">stop — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule — npm@1.1.10</p>
+<p id="footer">submodule — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">tag — npm@1.1.10</p>
+<p id="footer">tag — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
</div>
-<p id="footer">test — npm@1.1.10</p>
+<p id="footer">test — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
</div>
-<p id="footer">uninstall — npm@1.1.10</p>
+<p id="footer">uninstall — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
</div>
-<p id="footer">unpublish — npm@1.1.10</p>
+<p id="footer">unpublish — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">update — npm@1.1.10</p>
+<p id="footer">update — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/semver.html">semver(1)</a></li></ul>
</div>
-<p id="footer">version — npm@1.1.10</p>
+<p id="footer">version — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/search.html">search(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/docs.html">docs(1)</a></li></ul>
</div>
-<p id="footer">view — npm@1.1.10</p>
+<p id="footer">view — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
</div>
-<p id="footer">whoami — npm@1.1.10</p>
+<p id="footer">whoami — npm@1.1.14</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
/*
adding a folder:
1. tar into tmp/random/package.tgz
-2. untar into tmp/random/contents/{blah}
-3. rename {blah} to "package"
-4. tar tmp/random/contents/package to cache/n/v/package.tgz
-5. untar cache/n/v/package.tgz into cache/n/v/package
-6. rm tmp/random
+2. untar into tmp/random/contents/package, stripping one dir piece
+3. tar tmp/random/contents/package to cache/n/v/package.tgz
+4. untar cache/n/v/package.tgz into cache/n/v/package
+5. rm tmp/random
Adding a url:
1. fetch to tmp/random/package.tgz
exports.clean = clean
exports.unpack = unpack
-var mkdir = require("./utils/mkdir-p.js")
+var mkdir = require("mkdirp")
, exec = require("./utils/exec.js")
, fetch = require("./utils/fetch.js")
, npm = require("./npm.js")
, tar = require("./utils/tar.js")
, fileCompletion = require("./utils/completion/file-completion.js")
, url = require("url")
+ , chownr = require("chownr")
cache.usage = "npm cache add <tarball file>"
+ "\nnpm cache add <folder>"
// if the pkg and ver are in the cache, then
// just do a readJson and return.
// if they're not, then fetch them from the registry.
-var cacheSeen = {}
function read (name, ver, forceBypass, cb) {
if (typeof cb !== "function") cb = forceBypass, forceBypass = true
var jsonFile = path.join(npm.cache, name, ver, "package", "package.json")
function c (er, data) {
- if (!er) cacheSeen[data._id] = data
if (data) deprCheck(data)
return cb(er, data)
}
return addNamed(name, ver, c)
}
- if (name+"@"+ver in cacheSeen) {
- return cb(null, cacheSeen[name+"@"+ver])
- }
-
readJson(jsonFile, function (er, data) {
if (er) return addNamed(name, ver, c)
deprCheck(data)
output = output || require("./utils/output.js")
args = args.join("/").split("@").join("/")
if (args.substr(-1) === "/") args = args.substr(0, args.length - 1)
+ var prefix = npm.config.get("cache")
+ if (0 === prefix.indexOf(process.env.HOME)) {
+ prefix = "~" + prefix.substr(process.env.HOME.length)
+ }
ls_(args, npm.config.get("depth"), function(er, files) {
output.write(files.map(function (f) {
- return path.join("~/.npm", f)
+ return path.join(prefix, f)
}).join("\n").trim(), function (er) {
return cb(er, files)
})
// see if the spec is a url
// otherwise, treat as name@version
- var p = url.parse(spec.replace(/^git\+/, "git")) || {}
+ var p = url.parse(spec) || {}
log.verbose(p, "parsed url")
// it could be that we got name@http://blah
case "https:":
return addRemoteTarball(spec, null, name, cb)
case "git:":
- case "githttp:":
- case "githttps:":
- case "gitrsync:":
- case "gitftp:":
- case "gitssh:":
+ case "git+http:":
+ case "git+https:":
+ case "git+rsync:":
+ case "git+ftp:":
+ case "git+ssh:":
//p.protocol = p.protocol.replace(/^git([^:])/, "$1")
return addRemoteGit(spec, p, name, cb)
default:
}
function makeCacheDir (cb) {
- if (!process.getuid) return mkdir(npm.cache, npm.modes.exec, cb)
+ if (!process.getuid) return mkdir(npm.cache, cb)
var uid = +process.getuid()
, gid = +process.getgid()
}
if (uid !== 0 || !process.env.HOME) {
cacheStat = {uid: uid, gid: gid}
- return mkdir(npm.cache, npm.modes.exec, uid, gid, function (er) {
- return cb(er, cacheStat)
- })
+ return mkdir(npm.cache, afterMkdir)
}
+
fs.stat(process.env.HOME, function (er, st) {
if (er) return log.er(cb, "homeless?")(er)
cacheStat = st
log.silly([st.uid, st.gid], "uid, gid for cache dir")
- return mkdir(npm.cache, npm.modes.exec, st.uid, st.gid, function (er) {
+ return mkdir(npm.cache, afterMkdir)
+ })
+
+ function afterMkdir (er, made) {
+ if (er || !cacheStat || isNaN(cacheStat.uid) || isNaN(cacheStat.gid)) {
+ return cb(er, cacheStat)
+ }
+
+ if (!made) return cb(er, cacheStat)
+
+ // ensure that the ownership is correct.
+ chownr(made, cacheStat.uid, cacheStat.gid, function (er) {
return cb(er, cacheStat)
})
- })
+ }
}
, tgz = placeDirect ? placed : tmptgz
, doFancyCrap = p.indexOf(npm.tmp) !== 0
&& p.indexOf(npm.cache) !== 0
- tar.pack(tgz, p, data, doFancyCrap, function (er) {
- if (er) return log.er(cb,"couldn't pack "+p+ " to "+tgz)(er)
- addLocalTarball(tgz, name, cb)
+ getCacheStat(function (er, cs) {
+ mkdir(path.dirname(tgz), function (er, made) {
+ if (er) return cb(er)
+ tar.pack(tgz, p, data, doFancyCrap, function (er) {
+ if (er) return log.er(cb,"couldn't pack "+p+ " to "+tgz)(er)
+
+ if (er || !cs || isNaN(cs.uid) || isNaN(cs.gid)) return cb()
+
+ chownr(made || tgz, cs.uid, cs.gid, function (er) {
+ if (er) return cb(er)
+ addLocalTarball(tgz, name, cb)
+ })
+ })
+ })
})
})
}
if (!cb) cb = name, name = ""
getCacheStat(function (er, cs) {
if (er) return cb(er)
- return addTmpTarball_(tgz, name, cs.uid, cs.gid, cb)
- })
-}
-
-function addTmpTarball_ (tgz, name, uid, gid, cb) {
- var contents = path.dirname(tgz)
- tar.unpack( tgz, path.resolve(contents, "package")
- , null, null
- , uid, gid
- , function (er) {
- if (er) {
- return cb(er)
- }
- fs.readdir(contents, function (er, folder) {
- if (er) return log.er(cb, "couldn't readdir "+contents)(er)
- log.verbose(folder, "tarball contents")
- if (folder.length > 1) {
- folder = folder.filter(function (f) {
- return !f.match(/^\.|^tmp\.tgz$/)
- })
- }
- if (folder.length > 1) {
- log.warn(folder.slice(1).join("\n")
- ,"extra junk in folder, ignoring")
+ var contents = path.dirname(tgz)
+ tar.unpack( tgz, path.resolve(contents, "package")
+ , null, null
+ , cs.uid, cs.gid
+ , function (er) {
+ if (er) {
+ return cb(er)
}
- if (!folder.length) return cb(new Error("Empty package tarball"))
- folder = path.join(contents, folder[0])
- var newName = path.join(contents, "package")
- fs.rename(folder, newName, function (er) {
- if (er) return log.er(cb, "couldn't rename "+folder+" to package")(er)
- addLocalDirectory(newName, name, cb)
- })
+ addLocalDirectory(path.resolve(contents, "package"), name, cb)
})
})
}
-
// npm install <pkg> <pkg> <pkg>
//
// See doc/install.md for more description
, relativize = require("./utils/relativize.js")
, output
, url = require("url")
- , mkdir = require("./utils/mkdir-p.js")
+ , mkdir = require("mkdirp")
, lifecycle = require("./utils/lifecycle.js")
+ , archy = require("archy")
function install (args, cb_) {
})
}
- mkdir(where, function (er) {
+ mkdir(where, function (er, made) {
if (er) return cb(er)
// install dependencies locally by default,
// or install current folder globally
// that the submodules are not immediately require()able.
// TODO: Show the complete tree, ls-style, but only if --long is provided
function prettify (tree, installed) {
- // XXX This should match the data structure provided by npm ls --json
- if (npm.config.get("json")) return JSON.stringify(tree, null, 2)
- if (npm.config.get("parseable")) return parseable(installed)
- return Object.keys(tree).map(function (p) {
- p = tree[p]
- var c = ""
- if (p.children && p.children.length) {
- pref = "\n"
- var l = p.children.pop()
- c = p.children.map(function (c) {
- var gc = c.children && c.children.length
- ? " (" + c.children.map(function (gc) {
- return gc.what
- }).join(" ") + ")"
- : ""
- return "\n├── " + c.what + gc
- }).join("") + "\n└── " + l.what
+ if (npm.config.get("json")) {
+ function red (set, kv) {
+ set[kv[0]] = kv[1]
+ return set
}
- return [p.what, p.where, c].join(" ")
+ tree = Object.keys(tree).map(function (p) {
+ if (!tree[p]) return null
+ var what = tree[p].what.split("@")
+ , name = what.shift()
+ , version = what.join("@")
+ , o = { name: name, version: version, from: tree[p].from }
+ o.dependencies = tree[p].children.map(function P (dep) {
+ var what = dep.what.split("@")
+ , name = what.shift()
+ , version = what.join("@")
+ , o = { version: version, from: dep.from }
+ o.dependencies = dep.children.map(P).reduce(red, {})
+ return [name, o]
+ }).reduce(red, {})
+ return o
+ })
+
+ return JSON.stringify(tree, null, 2)
+ }
+ if (npm.config.get("parseable")) return parseable(installed)
+
+ return Object.keys(tree).map(function (p) {
+ return archy({ label: tree[p].what + " " + p
+ , nodes: (tree[p].children || []).map(function P (c) {
+ if (npm.config.get("long")) {
+ return { label: c.what, nodes: c.children.map(P) }
+ }
+ var g = c.children.map(function (g) {
+ return g.what
+ }).join(", ")
+ if (g) g = " (" + g + ")"
+ return c.what + g
+ })
+ })
}).join("\n")
}
}
}
+ // if it's identical to its parent, then it's probably someone
+ // doing `npm install foo` inside of the foo project. Print
+ // a warning, and skip it.
+ if (parent && parent.name === what && !npm.config.get("force")) {
+ log.warn("Refusing to install "+what+" as a dependency of itself"
+ ,"install")
+ return cb(null, [])
+ }
+
if (wrap) {
name = what.split(/@/).shift()
if (wrap[name]) {
// A more correct, but more complex, solution would be to symlink
// the deeper thing into the new location.
// Will do that if anyone whines about this irl.
-
- var p = Object.getPrototypeOf(ancestors)
+ //
+ // Note: `npm install foo` inside of the `foo` package will abort
+ // earlier if `--force` is not set. However, if it IS set, then
+ // we need to still fail here, but just skip the first level. Of
+ // course, it'll still fail eventually if it's a true cycle, and
+ // leave things in an undefined state, but that's what is to be
+ // expected when `--force` is used. That is why getPrototypeOf
+ // is used *twice* here: to skip the first level of repetition.
+
+ var p = Object.getPrototypeOf(Object.getPrototypeOf(ancestors))
, name = target.name
, version = target.version
while (p && p !== Object.prototype && p[name] !== version) {
, log = require("./utils/log.js")
, relativize = require("./utils/relativize.js")
, path = require("path")
+ , archy = require("archy")
ls.usage = "npm ls"
}
return o
}, 2)
- } else {
- out = makePretty(bfsify(data), long, dir).join("\n")
+ } else if (npm.config.get("parseable")) {
+ out = makeParseable(bfsify(data), long, dir)
+ } else if (data) {
+ out = makeArchy(bfsify(data), long, dir)
}
output.write(out, function (er) { cb(er, data, lite) })
})
}
+function alphasort (a, b) {
+ a = a.toLowerCase()
+ b = b.toLowerCase()
+ return a > b ? 1
+ : a < b ? -1 : 0
+}
+
function getLite (data, noname) {
var lite = {}
, maxDepth = npm.config.get("depth")
}
-function makePretty (data, long, dir, prefix, list) {
- var top = !list
- list = list || []
- prefix = prefix || ""
- list.push(format(data, long, prefix, dir))
- var deps = data.dependencies || {}
- , childPref = prefix.split("├─").join("│ ")
- .split("└─").join(" ")
- , depList = Object.keys(deps)
- , depLast = depList.length - 1
- , maxDepth = npm.config.get("depth")
- Object.keys(deps).sort(function (a, b) {
- return a > b ? 1 : -1
- }).forEach(function (d, i) {
- var depData = deps[d]
- if (typeof depData === "string") {
- if (data.depth < maxDepth) {
- var p = data.link || data.path
- log.warn("Unmet dependency in "+p, d+" "+deps[d])
- depData = npm.config.get("parseable")
- ? ( npm.config.get("long")
- ? path.resolve(data.path, "node_modules", d)
- + ":"+d+"@"+JSON.stringify(depData)+":INVALID:MISSING"
- : "" )
- : "─ \033[31;40mUNMET DEPENDENCY\033[0m "+d+" "+depData
- } else {
- if (npm.config.get("parseable")) {
- depData = path.resolve(data.path, "node_modules", d)
- + (npm.config.get("long")
- ? ":" + d + "@" + JSON.stringify(depData)
- + ":" // no realpath resolved
- + ":MAXDEPTH"
- : "")
- } else {
- depData = "─ "+d+"@'"+depData +"' (max depth reached)"
- }
- }
- }
- var c = i === depLast ? "└─" : "├─"
- makePretty(depData, long, dir, childPref + c, list)
- })
- if (top && list.length === 1 && !data._id) {
- if (!npm.config.get("parseable")) {
- list.push("(empty)")
- } else if (npm.config.get("long")) list[0] += ":EMPTY"
- }
- return list.filter(function (l) { return l && l.trim() })
+function makeArchy (data, long, dir) {
+ var out = makeArchy_(data, long, dir, 0)
+ return archy(out, "", { unicode: npm.config.get("unicode") })
}
-function ugly (data) {
+function makeArchy_ (data, long, dir, depth, parent, d) {
if (typeof data === "string") {
+ if (depth < npm.config.get("depth")) {
+ // just missing
+ var p = parent.link || parent.path
+ log.warn("Unmet dependency in "+p, d+" "+data)
+ data = "\033[31;40mUNMET DEPENDENCY\033[0m " + d + " " + data
+ } else {
+ data = d+"@'"+ data +"' (max depth reached)"
+ }
return data
}
- if (!npm.config.get("long")) return data.path
- return data.path
- + ":" + (data._id || "")
- + ":" + (data.realPath !== data.path ? data.realPath : "")
- + (data.extraneous ? ":EXTRANEOUS" : "")
- + (data.invalid ? ":INVALID" : "")
-}
+ var out = {}
+ // the top level is a bit special.
+ out.label = data._id ? data._id + " " : ""
+ if (data.link) out.label += "-> " + data.link
-function format (data, long, prefix, dir) {
- if (npm.config.get("parseable")) return ugly(data)
- if (typeof data === "string") {
- return prefix + data
- }
-// console.log([data.path, dir], "relativize")
- var depLen = Object.keys(data.dependencies).length
- , space = prefix.split("├─").join("│ ")
- .split("└─").join(" ")
- + (depLen ? "" : " ")
- , rel = relativize(data.path || "", dir)
- , l = prefix
- + (rel === "." ? "" : depLen ? "┬ " : "─ ")
- + (data._id ? data._id + " " : "")
- + (data.link ? "-> " + data.link : "") + ""
- + (rel === "." && !(long && data._id) ? dir : "")
if (data.invalid) {
if (data.realName !== data.name) l += " ("+data.realName+")"
- l += " \033[31;40minvalid\033[0m"
+ out.label += " \033[31;40minvalid\033[0m"
}
- if (data.extraneous && rel !== ".") {
- l += " \033[32;40mextraneous\033[0m"
+
+ if (data.extraneous && data.path !== dir) {
+ out.label += " \033[32;40mextraneous\033[0m"
}
- if (!long || !data._id) return l
+
+ if (long) {
+ if (dir === data.path) out.label += "\n" + dir
+ out.label += "\n" + getExtras(data, dir)
+ } else if (dir === data.path) {
+ out.label += dir
+ }
+
+ // now all the children.
+ out.nodes = Object.keys(data.dependencies || {})
+ .sort(alphasort).map(function (d) {
+ return makeArchy_(data.dependencies[d], long, dir, depth + 1, data, d)
+ })
+
+ if (out.nodes.length === 0 && data.path === dir) {
+ out.nodes = ["(empty)"]
+ }
+
+ return out
+}
+
+function getExtras (data, dir) {
var extras = []
- if (rel !== ".") extras.push(rel)
- else extras.push(dir)
+ , rel = relativize(data.path || "", dir)
+ , url = require("url")
+
if (data.description) extras.push(data.description)
if (data.repository) extras.push(data.repository.url)
if (data.homepage) extras.push(data.homepage)
- extras = extras.filter(function (e) { return e })
- var lastExtra = !depLen && extras.length - 1
- l += extras.map(function (e, i) {
- var indent = !depLen ? " " : "│ "
- return "\n" + space + indent + e
- }).join("")
- return l
+ if (data._from) {
+ var from = data._from
+ if (from.indexOf(data.name + "@") === 0) {
+ from = from.substr(data.name.length + 1)
+ }
+ var u = url.parse(from)
+ if (u.protocol) extras.push(from)
+ }
+ return extras.join("\n")
+}
+
+
+function makeParseable (data, long, dir, depth, parent, d) {
+ depth = depth || 0
+
+ return [ makeParseable_(data, long, dir, depth, parent, d) ]
+ .concat(Object.keys(data.dependencies || {})
+ .sort(alphasort).map(function (d) {
+ return makeParseable(data.dependencies[d], long, dir, depth + 1, data, d)
+ }))
+ .join("\n")
+}
+
+function makeParseable_ (data, long, dir, depth, parent, d) {
+ if (typeof data === "string") {
+ if (data.depth < npm.config.get("depth")) {
+ var p = parent.link || parent.path
+ log.warn("Unmet dependency in "+p, d+" "+data)
+ data = npm.config.get("long")
+ ? path.resolve(parent.path, "node_modules", d)
+ + ":"+d+"@"+JSON.stringify(data)+":INVALID:MISSING"
+ : ""
+ } else {
+ data = path.resolve(data.path, "node_modules", d)
+ + (npm.config.get("long")
+ ? ":" + d + "@" + JSON.stringify(data)
+ + ":" // no realpath resolved
+ + ":MAXDEPTH"
+ : "")
+ }
+
+ return data
+ }
+
+ if (!npm.config.get("long")) return data.path
+
+ return data.path
+ + ":" + (data._id || "")
+ + ":" + (data.realPath !== data.path ? data.realPath : "")
+ + (data.extraneous ? ":EXTRANEOUS" : "")
+ + (data.invalid ? ":INVALID" : "")
}
, which = require("which")
, semver = require("semver")
, findPrefix = require("./utils/find-prefix.js")
- , getUid = require("./utils/uid-number.js")
- , mkdir = require("./utils/mkdir-p.js")
+ , getUid = require("uid-number")
+ , mkdir = require("mkdirp")
, slide = require("slide")
, chain = slide.chain
npm.ENOTSUP = {}
npm.EBADPLATFORM = {}
-// HACK for windows
-if (process.platform === "win32") {
- // stub in unavailable methods from process and fs binding
- if (!process.getuid) process.getuid = function() {}
- if (!process.getgid) process.getgid = function() {}
- var fsBinding = process.binding("fs")
- if (!fsBinding.chown) fsBinding.chown = function() {
- var cb = arguments[arguments.length - 1]
- if (typeof cb == "function") cb()
- }
-
- // patch rename/renameSync, but this should really be fixed in node
- var _fsRename = fs.rename
- , _fsPathPatch
- _fsPathPatch = function(p) {
- return p && p.replace(/\\/g, "/") || p;
- }
- fs.rename = function(p1, p2) {
- arguments[0] = _fsPathPatch(p1)
- arguments[1] = _fsPathPatch(p2)
- return _fsRename.apply(fs, arguments);
- }
-}
-
try {
// startup, ok to do this synchronously
var j = JSON.parse(fs.readFileSync(
})
// the prefix MUST exist, or else nothing works.
if (!npm.config.get("global")) {
- mkdir(p, npm.modes.exec, null, null, true, next)
+ mkdir(p, next)
} else {
next(er)
}
, enumerable : true
})
// the prefix MUST exist, or else nothing works.
- mkdir(gp, npm.modes.exec, null, null, true, next)
+ mkdir(gp, next)
})
var i = 2
function uninstall_ (args, nm, cb) {
asyncMap(args, function (arg, cb) {
- var p = path.resolve(nm, arg)
+ // uninstall .. should not delete /usr/local/lib/node_modules/..
+ var p = path.join(path.resolve(nm), path.join("/", arg))
+ if (path.resolve(p) === nm) {
+ log.warn(arg, "uninstall: invalid argument")
+ return cb(null, [])
+ }
fs.lstat(p, function (er) {
if (er) {
log.warn(arg, "Not installed in "+nm)
var fs = require("graceful-fs")
, chain = require("slide").chain
- , mkdir = require("./mkdir-p.js")
+ , mkdir = require("mkdirp")
, rm = require("rimraf")
, log = require("./log.js")
, path = require("path")
module.exports = fileCompletion
var find = require("../find.js")
- , mkdir = require("../mkdir-p.js")
+ , mkdir = require("mkdirp")
, path = require("path")
function fileCompletion (root, req, depth, cb) {
+++ /dev/null
-// build up a set of exclude lists in order of precedence:
-// [ ["!foo", "bar"]
-// , ["foo", "!bar"] ]
-// being *included* will override a previous exclusion,
-// and being excluded will override a previous inclusion.
-//
-// Each time the tar file-list generator thingie enters a new directory,
-// it calls "addIgnoreFile(dir, list, cb)". If an ignore file is found,
-// then it is added to the list and the cb() is called with an
-// child of the original list, so that we don't have
-// to worry about popping it off at the right time, since other
-// directories will continue to use the original parent list.
-//
-// If no ignore file is found, then the original list is returned.
-//
-// To start off with, ~/.{npm,git}ignore is added, as is
-// prefix/{npm,git}ignore, effectively treated as if they were in the
-// base package directory.
-
-exports.addIgnoreFile = addIgnoreFile
-exports.readIgnoreFile = readIgnoreFile
-exports.parseIgnoreFile = parseIgnoreFile
-exports.test = test
-exports.filter = filter
-
-var path = require("path")
- , fs = require("graceful-fs")
- , minimatch = require("minimatch")
- , relativize = require("./relativize.js")
- , log = require("./log.js")
-
-// todo: memoize
-
-// read an ignore file, or fall back to the
-// "gitBase" file in the same directory.
-function readIgnoreFile (file, gitBase, cb) {
- //log.warn(file, "ignoreFile")
- if (!file) return cb(null, "")
- fs.readFile(file, function (er, data) {
- if (!er || !gitBase) return cb(null, data || "")
- var gitFile = path.resolve(path.dirname(file), gitBase)
- fs.readFile(gitFile, function (er, data) {
- return cb(null, data || "")
- })
- })
-}
-
-// read a file, and then return the list of patterns
-function parseIgnoreFile (file, gitBase, dir, cb) {
- readIgnoreFile(file, gitBase, function (er, data) {
- data = data ? data.toString("utf8") : ""
-
- data = data.split(/[\r\n]+/).map(function (p) {
- return p.trim()
- }).filter(function (p) {
- return p.length && p.charAt(0) !== "#"
- })
- data.dir = dir
- return cb(er, data)
- })
-}
-
-// add an ignore file to an existing list which can
-// then be passed to the test() function. If the ignore
-// file doesn't exist, then the list is unmodified. If
-// it is, then a concat-child of the original is returned,
-// so that this is suitable for walking a directory tree.
-function addIgnoreFile (file, gitBase, list, dir, cb) {
- if (typeof cb !== "function") cb = dir, dir = path.dirname(file)
- if (typeof cb !== "function") cb = list, list = []
- parseIgnoreFile(file, gitBase, dir, function (er, data) {
- if (!er && data) {
- // package.json "files" array trumps everything
- // Make sure it's always last.
- if (list.length && list[list.length-1].packageFiles) {
- list = list.concat([data, list.pop()])
- } else {
- list = list.concat([data])
- }
- }
- cb(er, list)
- })
-}
-
-
-// no IO
-// loop through the lists created in the functions above, and test to
-// see if a file should be included or not, given those exclude lists.
-function test (file, excludeList) {
- if (path.basename(file) === "package.json") return true
- // log.warn(file, "test file")
- // log.warn(excludeList, "test list")
- var incRe = /^\!(\!\!)*/
- , excluded = false
- , mmconf = { matchBase: true, dot: true }
- for (var i = 0, l = excludeList.length; i < l; i ++) {
- var excludes = excludeList[i]
- , dir = excludes.dir
-
- // chop the filename down to be relative to excludeDir
- var rf = relativize(file, dir, true)
- rf = rf.replace(/^\.?\//, "")
- if (file.slice(-1) === "/") rf += "/"
-
- // log.warn([file, rf], "rf")
-
- for (var ii = 0, ll = excludes.length; ii < ll; ii ++) {
- var ex = excludes[ii].replace(/^(!*)\//, "$1")
- , inc = !!ex.match(incRe)
-
- // log.warn([ex, rf], "ex, rf")
- // excluding/including a dir excludes/includes all the files in it.
- if (ex.slice(-1) === "/") ex += "**"
-
- // if this is not an inclusion attempt, and someone else
- // excluded it, then just continue, because there's nothing
- // that can be done here to change the exclusion.
- if (!inc && excluded) continue
-
- // if it's an inclusion attempt, and the file has not been
- // excluded, then skip it, because there's no need to try again.
- if (inc && !excluded) continue
-
- // if it matches the pattern, then it should be excluded.
- excluded = !!minimatch(rf, ex, mmconf)
- // log.error([rf, ex, excluded], "rf, ex, excluded")
-
- // if you include foo, then it also includes foo/bar.js
- if (inc && excluded && ex.slice(-3) !== "/**") {
- excluded = minimatch(rf, ex + "/**", mmconf)
- // log.warn([rf, ex + "/**", inc, excluded], "dir without /")
- }
-
- // if you exclude foo, then it also excludes foo/bar.js
- if (!inc
- && excluded
- && ex.slice(-3) !== "/**"
- && rf.slice(-1) === "/"
- && excludes.indexOf(ex + "/**") === -1) {
- // log.warn(ex + "/**", "adding dir-matching exclude pattern")
- excludes.splice(ii, 1, ex, ex + "/**")
- ll ++
- }
- }
-
- // log.warn([rf, excluded, excludes], "rf, excluded, excludes")
- }
- // true if it *should* be included
- // log.warn([file, excludeList, excluded], "file, excluded")
- return !excluded
-}
-
-// returns a function suitable for Array#filter
-function filter (dir, list) { return function (file) {
- file = file.trim()
- var testFile = path.resolve(dir, file)
- if (file.slice(-1) === "/") testFile += "/"
- return file && test(testFile, list)
-}}
, url = require("url")
, log = require("./log.js")
, path = require("path")
- , mkdir = require("./mkdir-p.js")
+ , mkdir = require("mkdirp")
+ , chownr = require("chownr")
, regHost
module.exports = fetch
function fetch (remote, local, headers, cb) {
if (typeof cb !== "function") cb = headers, headers = {}
log.verbose(local, "fetch to")
- mkdir(path.dirname(local), function (er) {
+ mkdir(path.dirname(local), function (er, made) {
if (er) return cb(er)
fetch_(remote, local, headers, cb)
})
var fs = require("graceful-fs")
, chain = require("slide").chain
- , mkdir = require("./mkdir-p.js")
+ , mkdir = require("mkdirp")
, rm = require("./gently-rm.js")
, log = require("./log.js")
, path = require("path")
+++ /dev/null
-
-var log = require("./log.js")
- , fs = require("graceful-fs")
- , path = require("path")
- , npm = require("../npm.js")
- , exec = require("./exec.js")
- , uidNumber = require("./uid-number.js")
- , umask = process.umask()
- , umaskOrig = umask
- , addedUmaskExit = false
- , mkdirCache = {}
-
-module.exports = mkdir
-function mkdir (ensure, mode, uid, gid, noChmod, cb_) {
- if (typeof cb_ !== "function") cb_ = noChmod, noChmod = null
- if (typeof cb_ !== "function") cb_ = gid, gid = null
- if (typeof cb_ !== "function") cb_ = uid, uid = null
- if (typeof cb_ !== "function") cb_ = mode, mode = npm.modes.exec
-
- if (mode & umask) {
- log.verbose(mode.toString(8), "umasking from "+umask.toString(8))
- process.umask(umask = 0)
- if (!addedUmaskExit) {
- addedUmaskExit = true
- process.on("exit", function () { process.umask(umask = umaskOrig) })
- }
- }
-
- ensure = path.resolve(ensure).replace(/\/+$/, '')
-
- // mkdir("/") should not do anything, since that always exists.
- if (!ensure
- || ( process.platform === "win32"
- && ensure.match(/^[a-zA-Z]:(\\|\/)?$/))) {
- return cb_()
- }
-
- if (mkdirCache.hasOwnProperty(ensure)) {
- return mkdirCache[ensure].push(cb_)
- }
- mkdirCache[ensure] = [cb_]
-
- function cb (er) {
- var cbs = mkdirCache[ensure]
- delete mkdirCache[ensure]
- cbs.forEach(function (c) { c(er) })
- }
-
- if (uid === null && gid === null) {
- return mkdir_(ensure, mode, uid, gid, noChmod, cb)
- }
-
- uidNumber(uid, gid, function (er, uid, gid) {
- if (er) return cb(er)
- mkdir_(ensure, mode, uid, gid, noChmod, cb)
- })
-}
-
-function mkdir_ (ensure, mode, uid, gid, noChmod, cb) {
- // if it's already a dir, then just check the bits and owner.
- fs.stat(ensure, function (er, s) {
- if (s && s.isDirectory()) {
- // check mode, uid, and gid.
- if ((noChmod || (s.mode & mode) === mode)
- && (typeof uid !== "number" || s.uid === uid)
- && (typeof gid !== "number" || s.gid === gid)) return cb()
- return done(ensure, mode, uid, gid, noChmod, cb)
- }
- return walkDirs(ensure, mode, uid, gid, noChmod, cb)
- })
-}
-
-function done (ensure, mode, uid, gid, noChmod, cb) {
- // now the directory has been created.
- // chown it to the desired uid/gid
- // Don't chown the npm.root dir, though, in case we're
- // in unsafe-perm mode.
- log.verbose("done: "+ensure+" "+mode.toString(8), "mkdir")
-
- // only chmod if noChmod isn't set.
- var d = done_(ensure, mode, uid, gid, cb)
- if (noChmod) return d()
- fs.chmod(ensure, mode, d)
-}
-
-function done_ (ensure, mode, uid, gid, cb) {
- return function (er) {
- if (er
- || ensure === npm.dir
- || typeof uid !== "number"
- || typeof gid !== "number"
- || npm.config.get("unsafe-perm")) return cb(er)
- uid = Math.floor(uid)
- gid = Math.floor(gid)
- fs.chown(ensure, uid, gid, cb)
- }
-}
-
-var pathSplit = process.platform === "win32" ? /\/|\\/ : "/"
-function walkDirs (ensure, mode, uid, gid, noChmod, cb) {
- var dirs = ensure.split(pathSplit)
- , walker = []
- , foundUID = null
- , foundGID = null
-
- // gobble the "/" or C: first
- walker.push(dirs.shift())
-
- // The loop that goes through and stats each dir.
- ;(function S (d) {
- // no more directory steps left.
- if (d === undefined) {
- // do the chown stuff
- return done(ensure, mode, uid, gid, noChmod, cb)
- }
-
- // get the absolute dir for the next piece being stat'd
- walker.push(d)
- var dir = walker.join(path.SPLIT_CHAR)
-
- // stat callback lambda
- fs.stat(dir, function STATCB (er, s) {
- if (er) {
- // the stat failed - directory does not exist.
-
- log.verbose(er.message, "mkdir (expected) error")
-
- // use the same uid/gid as the nearest parent, if not set.
- if (foundUID !== null) uid = foundUID
- if (foundGID !== null) gid = foundGID
-
- // make the directory
- fs.mkdir(dir, mode, function MKDIRCB (er) {
- // since stat and mkdir are done as two separate syscalls,
- // operating on a path rather than a file descriptor, it's
- // possible that the directory didn't exist when we did
- // the stat, but then *did* exist when we go to to the mkdir.
- // If we didn't care about uid/gid, we could just mkdir
- // repeatedly, failing on any error other than "EEXIST".
- if (er && er.message.indexOf("EEXIST") === 0) {
- return fs.stat(dir, STATCB)
- }
-
- // any other kind of error is not saveable.
- if (er) return cb(er)
-
- // at this point, we've just created a new directory successfully.
-
- // if we care about permissions
- if (!npm.config.get("unsafe-perm") // care about permissions
- // specified a uid and gid
- && uid !== null
- && gid !== null ) {
- // set the proper ownership
- return fs.chown(dir, uid, gid, function (er) {
- if (er) return cb(er)
- // attack the next portion of the path.
- S(dirs.shift())
- })
- } else {
- // either we don't care about ownership, or it's already right.
- S(dirs.shift())
- }
- }) // mkdir
-
- } else {
- // the stat succeeded.
- if (s.isDirectory()) {
- // if it's a directory, that's good.
- // if the uid and gid aren't already set, then try to preserve
- // the ownership on up the tree. Things in ~ remain owned by
- // the user, things in / remain owned by root, etc.
- if (uid === null && typeof s.uid === "number") foundUID = s.uid
- if (gid === null && typeof s.gid === "number") foundGID = s.gid
-
- // move onto next portion of path
- S(dirs.shift())
-
- } else {
- // the stat succeeded, but it's not a directory
- log.verbose(dir, "mkdir exists")
- log.silly(s, "stat("+dir+")")
- log.verbose(s.isDirectory(), "isDirectory()")
- cb(new Error("Failed to mkdir "+dir+": File exists"))
- }// if (isDirectory) else
- } // if (stat failed) else
- }) // stat
-
- // start the S function with the first item in the list of directories.
- })(dirs.shift())
-}
, npm = require("../../npm.js")
, path = require("path")
, log = require("../log.js")
- , mkdir = require("../mkdir-p.js")
+ , mkdir = require("mkdirp")
, cacheStat = null
+ , chownr = require("chownr")
function get (project, version, timeout, nofollow, staleOk, cb) {
if (typeof cb !== "function") cb = staleOk, staleOk = false
}
function saveToCache_ (cache, data, uid, gid, saved) {
- mkdir(path.dirname(cache), npm.modes.exec, uid, gid, function (er) {
+ mkdir(path.dirname(cache), function (er, made) {
if (er) return saved()
fs.writeFile(cache, JSON.stringify(data), function (er) {
if (er || uid === null || gid === null) {
return saved()
}
- fs.chown(cache, uid, gid, saved)
+ chownr(made || cache, uid, gid, saved)
})
})
}
if (er) return hasGyp(false)
// see if there are any *.gyp files in there.
- // If there are, then copy them to binding.gyp
- // if there are not, then just proceed without
gf = gf.filter(function (f) {
return f.match(/\.gyp$/)
})
gf = gf[0]
- if (!gf) return hasGyp(false)
- if (gf === "binding.gyp") return hasGyp(true)
-
- // need to rename. windows is annoying.
- // why not fs.rename? because we just saw the file, so it'll
- // be cached for potentially several seconds on a network share.
- return fs.readFile(path.resolve(pkgdir, gf), function (er, d) {
- if (er) return hasGyp(false)
- fs.writeFile(path.resolve(pkgdir, "binding.gyp"), d, function (er) {
- if (er) return hasGyp(false)
- fs.unlink(path.resolve(pkgdir, gf), function (er) {
- return hasGyp(!er)
- })
- })
- })
+ return hasGyp(!!gf)
})
}
}
if (typeof json.bugs === "object") {
+ // just go ahead and correct these.
Object.keys(bugsTypos).forEach(function (d) {
if (json.bugs.hasOwnProperty(d)) {
- log.warn( "package.json: bugs['" + d + "'] should probably be "
- + "bugs['" + bugsTypos[d] + "']", json._id)
- }
+ json.bugs[ bugsTypos[d] ] = json.bugs[d]
+ delete json.bugs[d]
+ }
})
}
-// XXX lib/cache.js and this file need to be rewritten.
-
// commands for packing and unpacking tarballs
// this file is used by lib/cache.js
var npm = require("../npm.js")
, fs = require("graceful-fs")
- , exec = require("./exec.js")
- , find = require("./find.js")
- , mkdir = require("./mkdir-p.js")
- , asyncMap = require("slide").asyncMap
, path = require("path")
, log = require("./log.js")
- , uidNumber = require("./uid-number.js")
+ , uidNumber = require("uid-number")
, rm = require("rimraf")
, readJson = require("./read-json.js")
, relativize = require("./relativize.js")
, cache = require("../cache.js")
- , excludes = require("./excludes.js")
, myUid = process.getuid && process.getuid()
, myGid = process.getgid && process.getgid()
, tar = require("tar")
, zlib = require("zlib")
, fstream = require("fstream")
+ , Packer = require("fstream-npm")
if (process.env.SUDO_UID && myUid === 0) {
if (!isNaN(process.env.SUDO_UID)) myUid = +process.env.SUDO_UID
exports.pack = pack
exports.unpack = unpack
-exports.makeList = makeList
function pack (targetTarball, folder, pkg, dfc, cb) {
+ log.verbose([targetTarball, folder], "tar.pack")
if (typeof cb !== "function") cb = dfc, dfc = true
- folder = path.resolve(folder)
-
- log.verbose(folder, "pack")
-
- if (typeof pkg === "function") {
- cb = pkg, pkg = null
- return readJson(path.resolve(folder, "package.json"), function (er, pkg) {
- if (er) return log.er(cb, "Couldn't find package.json in "+folder)(er)
- pack(targetTarball, folder, pkg, dfc, cb)
- })
- }
- log.verbose(folder+" "+targetTarball, "pack")
- var parent = path.dirname(folder)
- , addFolder = path.basename(folder)
-
- var confEx = npm.config.get("ignore")
- log.silly(folder, "makeList")
- makeList(folder, pkg, dfc, function (er, files, cleanup) {
- if (er) return cb(er)
- // log.silly(files, "files")
- return packFiles(targetTarball, parent, files, pkg, function (er) {
- if (!cleanup || !cleanup.length) return cb(er)
- // try to be a good citizen, even/especially in the event of failure.
- cleanupResolveLinkDep(cleanup, function (er2) {
- if (er || er2) {
- if (er) log(er, "packing tarball")
- if (er2) log(er2, "while cleaning up resolved deps")
- }
- return cb(er || er2)
- })
- })
- })
-}
-
-function packFiles (targetTarball, parent, files, pkg, cb_) {
-
- var p
-
- files = files.map(function (f) {
- p = f.split(/\/|\\/)[0]
- return path.resolve(parent, f)
- })
-
- parent = path.resolve(parent, p)
-
- var called = false
- function cb (er) {
- if (called) return
- called = true
- cb_(er)
- }
log.verbose(targetTarball, "tarball")
- log.verbose(parent, "parent")
- fstream.Reader({ type: "Directory"
- , path: parent
- , filter: function () {
- // files should *always* get into tarballs
- // in a user-writable state, even if they're
- // being installed from some wackey vm-mounted
- // read-only filesystem.
- this.props.mode = this.props.mode | 0200
- var inc = -1 !== files.indexOf(this.path)
+ log.verbose(folder, "folder")
+ new Packer({ path: folder, type: "Directory", isDirectory: true })
+ .on("error", log.er(cb, "error reading "+folder))
- // WARNING! Hackety hack!
- // XXX Fix this in a better way.
- // Rename .gitignore to .npmignore if there is not a
- // .npmignore file there already, the better to lock
- // down installed packages with git for deployment.
- if (this.basename === ".gitignore") {
- if (this.parent._entries.indexOf(".npmignore") !== -1) {
- return false
- }
- var d = path.dirname(this.path)
- this.basename = ".npmignore"
- this.path = path.join(d, ".npmignore")
- }
- return inc
- }
- })
- .on("error", log.er(cb, "error reading "+parent))
// By default, npm includes some proprietary attributes in the
// package tarball. This is sane, and allowed by the spec.
// However, npm *itself* excludes these from its own package,
.on("error", log.er(cb, "gzip error "+targetTarball))
.pipe(fstream.Writer({ type: "File", path: targetTarball }))
.on("error", log.er(cb, "Could not write "+targetTarball))
- .on("close", cb)
+ .on("close", function () {
+ cb()
+ })
}
function unpack (tarball, unpackTarget, dMode, fMode, uid, gid, cb) {
+ log.verbose(tarball, "unpack")
if (typeof cb !== "function") cb = gid, gid = null
if (typeof cb !== "function") cb = uid, uid = null
if (typeof cb !== "function") cb = fMode, fMode = npm.modes.file
}
function unpack_ ( tarball, unpackTarget, dMode, fMode, uid, gid, cb ) {
- // If the desired target is /path/to/foo,
- // then unpack into /path/to/.foo.npm/{something}
- // rename that to /path/to/foo, and delete /path/to/.foo.npm
var parent = path.dirname(unpackTarget)
, base = path.basename(unpackTarget)
rm(unpackTarget, function (er) {
if (er) return cb(er)
- mkdir(unpackTarget, dMode || npm.modes.exec, uid, gid, function (er) {
- log.verbose([uid, gid], "unpack_ uid, gid")
- log.verbose(unpackTarget, "unpackTarget")
+ // gzip {tarball} --decompress --stdout \
+ // | tar -mvxpf - --strip-components=1 -C {unpackTarget}
+ gunzTarPerm( tarball, unpackTarget
+ , dMode, fMode
+ , uid, gid
+ , function (er, folder) {
if (er) return cb(er)
-
- // cp the gzip of the tarball, pipe the stdout into tar's stdin
- // gzip {tarball} --decompress --stdout \
- // | tar -mvxpf - --strip-components=1 -C {unpackTarget}
- gunzTarPerm( tarball, unpackTarget
- , dMode, fMode
- , uid, gid
- , function (er, folder) {
- if (er) return cb(er)
- log.verbose(folder, "gunzed")
- readJson(path.resolve(folder, "package.json"), cb)
- })
+ readJson(path.resolve(folder, "package.json"), cb)
})
})
}
-// on Windows, A/V software can lock the directory, causing this
-// to fail with an EACCES. Try again on failure, for up to 1 second.
-// XXX Fix this by not unpacking into a temp directory, instead just
-// renaming things on the way out of the tarball.
-function moveIntoPlace (folder, unpackTarget, cb) {
- var start = Date.now()
- fs.rename(folder, unpackTarget, function CB (er) {
- if (er
- && process.platform === "win32"
- && er.code === "EACCES"
- && Date.now() - start < 1000) {
- return fs.rename(folder, unpackTarget, CB)
- }
- cb(er)
- })
-}
-
function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
if (!dMode) dMode = npm.modes.exec
}
function extractEntry (entry) {
+ log.silly(entry.path, "extracting entry")
// never create things that are user-unreadable,
// or dirs that are user-un-listable. Only leads to headaches.
var originalMode = entry.mode = entry.mode || entry.props.mode
var extractOpts = { type: "Directory", path: target, strip: 1 }
+ if (process.platform !== "win32" &&
+ typeof uid === "number" &&
+ typeof gid === "number") {
+ extractOpts.uid = uid
+ extractOpts.gid = gid
+ }
+
+ extractOpts.filter = function () {
+ // symbolic links are not allowed in packages.
+ if (this.type.match(/^.*Link$/)) {
+ log.warn( this.path.substr(target.length + 1)
+ + ' -> ' + this.linkpath
+ , "excluding symbolic link")
+ return false
+ }
+ return true
+ }
+
+
fst.on("error", log.er(cb, "error reading "+tarball))
fst.on("data", function OD (c) {
// detect what it is.
if (c[0] === 0x1F &&
c[1] === 0x8B &&
c[2] === 0x08) {
- var extracter = tar.Extract(extractOpts)
fst
.pipe(zlib.Unzip())
.on("error", log.er(cb, "unzip error "+tarball))
.on("close", cb)
} else {
// naked js file
+ var jsOpts = { path: path.resolve(target, "index.js") }
+
+ if (process.platform !== "win32" &&
+ typeof uid === "number" &&
+ typeof gid === "number") {
+ jsOpts.uid = uid
+ jsOpts.gid = gid
+ }
+
fst
- .pipe(fstream.Writer({ path: path.resolve(target, "index.js") }))
+ .pipe(fstream.Writer(jsOpts))
.on("error", log.er(cb, "copy error "+tarball))
.on("close", function () {
var j = path.resolve(target, "package.json")
fst.emit("data", c)
})
}
-
-function makeList (dir, pkg, dfc, cb) {
- if (typeof cb !== "function") cb = dfc, dfc = true
- if (typeof cb !== "function") cb = pkg, pkg = null
- dir = path.resolve(dir)
-
- if (!pkg.path) pkg.path = dir
-
- var name = path.basename(dir)
-
- // since this is a top-level traversal, get the user and global
- // exclude files, as well as the "ignore" config setting.
- var confIgnore = npm.config.get("ignore").trim()
- .split(/[\n\r\s\t]+/)
- .filter(function (i) { return i.trim() })
- , userIgnore = npm.config.get("userignorefile")
- , globalIgnore = npm.config.get("globalignorefile")
- , userExclude
- , globalExclude
-
- confIgnore.dir = dir
- confIgnore.name = "confIgnore"
-
- var defIgnore = ["build/"]
- defIgnore.dir = dir
-
- // TODO: only look these up once, and cache outside this function
- excludes.parseIgnoreFile( userIgnore, null, dir
- , function (er, uex) {
- if (er) return cb(er)
- userExclude = uex
- next()
- })
-
- excludes.parseIgnoreFile( globalIgnore, null, dir
- , function (er, gex) {
- if (er) return cb(er)
- globalExclude = gex
- next()
- })
-
- function next () {
- if (!globalExclude || !userExclude) return
- var exList = [ defIgnore, confIgnore, globalExclude, userExclude ]
-
- makeList_(dir, pkg, exList, dfc, function (er, files, cleanup) {
- if (er) return cb(er)
- var dirLen = dir.replace(/(\/|\\)$/, "").length + 1
- log.silly([dir, dirLen], "dir, dirLen")
- files = files.map(function (file) {
- return path.join(name, file.substr(dirLen))
- })
- return cb(null, files, cleanup)
- })
- }
-}
-
-// Patterns ending in slashes will only match targets
-// ending in slashes. To implement this, add a / to
-// the filename iff it lstats isDirectory()
-function readDir (dir, pkg, dfc, cb) {
- fs.readdir(dir, function (er, files) {
- if (er) return cb(er)
- files = files.filter(function (f) {
- return f && f.charAt(0) !== "/" && f.indexOf("\0") === -1
- })
- asyncMap(files, function (file, cb) {
- fs.lstat(path.resolve(dir, file), function (er, st) {
- if (er) return cb(null, [])
- // if it's a directory, then tack "/" onto the name
- // so that it can match dir-only patterns in the
- // include/exclude logic later.
- if (st.isDirectory()) return cb(null, file + "/")
-
- // if it's a symlink, then we need to do some more
- // complex stuff for GH-691
- if (st.isSymbolicLink()) return readSymlink(dir, file, pkg, dfc, cb)
-
- // otherwise, just let it on through.
- return cb(null, file)
- })
- }, cb)
- })
-}
-
-// just see where this link is pointing, and resolve relative paths.
-function shallowReal (link, cb) {
- link = path.resolve(link)
- fs.readlink(link, function (er, t) {
- if (er) return cb(er)
- return cb(null, path.resolve(path.dirname(link), t), t)
- })
-}
-
-function readSymlink (dir, file, pkg, dfc, cb) {
- var isNM = dfc
- && path.basename(dir) === "node_modules"
- && path.dirname(dir) === pkg.path
- // see if this thing is pointing outside of the package.
- // external symlinks are resolved for deps, ignored for other things.
- // internal symlinks are allowed through.
- var df = path.resolve(dir, file)
- shallowReal(df, function (er, r, target) {
- if (er) return cb(null, []) // wtf? exclude file.
- if (r.indexOf(dir) === 0) return cb(null, file) // internal
- if (!isNM) return cb(null, []) // external non-dep
- // now the fun stuff!
- fs.realpath(df, function (er, resolved) {
- if (er) return cb(null, []) // can't add it.
- readJson(path.resolve(resolved, "package.json"), function (er) {
- if (er) return cb(null, []) // not a package
- resolveLinkDep(dir, file, resolved, target, pkg, function (er, f, c) {
- cb(er, f, c)
- })
- })
- })
- })
-}
-
-// put the link back the way it was.
-function cleanupResolveLinkDep (cleanup, cb) {
- // cut it out of the list, so that cycles will be broken.
- if (!cleanup) return cb()
-
- asyncMap(cleanup, function (d, cb) {
- rm(d[1], function (er) {
- if (er) return cb(er)
- fs.symlink(d[0], d[1], cb)
- })
- }, cb)
-}
-
-function resolveLinkDep (dir, file, resolved, target, pkg, cb) {
- // we've already decided that this is a dep that will be bundled.
- // make sure the data reflects this.
- var bd = pkg.bundleDependencies || pkg.bundledDependencies || []
- delete pkg.bundledDependencies
- pkg.bundleDependencies = bd
- var f = path.resolve(dir, file)
- , cleanup = [[target, f, resolved]]
-
- if (bd.indexOf(file) === -1) {
- // then we don't do this one.
- // just move the symlink out of the way.
- return rm(f, function (er) {
- cb(er, file, cleanup)
- })
- }
-
- rm(f, function (er) {
- if (er) return cb(er)
- cache.add(resolved, function (er, data) {
- if (er) return cb(er)
- cache.unpack(data.name, data.version, f, function (er, data) {
- if (er) return cb(er)
- // now clear out the cache entry, since it's weird, probably.
- // pass the cleanup object along so that the thing getting the
- // list of files knows what to clean up afterwards.
- cache.clean([data._id], function (er) { cb(er, file, cleanup) })
- })
- })
- })
-}
-
-// exList is a list of ignore lists.
-// Each exList item is an array of patterns of files to ignore
-//
-function makeList_ (dir, pkg, exList, dfc, cb) {
- var files = null
- , cleanup = null
-
- readDir(dir, pkg, dfc, function (er, f, c) {
- if (er) return cb(er)
- cleanup = c
- files = f.map(function (f) {
- // no nulls in paths!
- return f.split(/\0/)[0]
- }).filter(function (f) {
- // always remove all source control folders and
- // waf/vim/OSX garbage. this is a firm requirement.
- return !( f === ".git/"
- || f === ".lock-wscript"
- || f.match(/^\.wafpickle-[0-9]+$/)
- || f === "CVS/"
- || f === ".svn/"
- || f === ".hg/"
- || f.match(/^\..*\.swp/)
- || f === ".DS_Store"
- || f.match(/^\._/)
- || f === "npm-debug.log"
- || f === ""
- || f.charAt(0) === "/"
- )
- })
-
- // if (files.length > 0) files.push(".")
-
- if (files.indexOf("package.json") !== -1 && dir !== pkg.path) {
- // a package.json file starts the whole exclude/include
- // logic all over. Otherwise, a parent could break its
- // deps with its files list or .npmignore file.
- readJson(path.resolve(dir, "package.json"), function (er, data) {
- if (!er && typeof data === "object") {
- data.path = dir
- return makeList(dir, data, dfc, function (er, files) {
- // these need to be mounted onto the directory now.
- cb(er, files && files.map(function (f) {
- return path.resolve(path.dirname(dir), f)
- }))
- })
- }
- next()
- })
- //next()
- } else next()
-
- // add a local ignore file, if found.
- if (files.indexOf(".npmignore") === -1
- && files.indexOf(".gitignore") === -1) next()
- else {
- excludes.addIgnoreFile( path.resolve(dir, ".npmignore")
- , ".gitignore"
- , exList
- , dir
- , function (er, list) {
- if (!er) exList = list
- next(er)
- })
- }
- })
-
- var n = 2
- , errState = null
- function next (er) {
- if (errState) return
- if (er) return cb(errState = er, [], cleanup)
- if (-- n > 0) return
-
- if (!pkg) return cb(new Error("No package.json file in "+dir))
- if (pkg.path === dir && pkg.files) {
- pkg.files = pkg.files.filter(function (f) {
- f = f.trim()
- return f && f.charAt(0) !== "#"
- })
- if (!pkg.files.length) pkg.files = null
- }
- if (pkg.path === dir && pkg.files) {
- // stuff on the files list MUST be there.
- // ignore everything, then include the stuff on the files list.
- var pkgFiles = ["*"].concat(pkg.files.map(function (f) {
- return "!" + f
- }))
- pkgFiles.dir = dir
- pkgFiles.packageFiles = true
- exList.push(pkgFiles)
- }
-
- if (path.basename(dir) === "node_modules"
- && pkg.path === path.dirname(dir)
- // do fancy crap
- && dfc
- // not already part of a bundled dependency
- && (path.basename(path.dirname(pkg.path)) !== "node_modules"
- // unless it's the root
- || pkg.path === npm.prefix)) {
- log.verbose(dir, "doing fancy crap")
- files = filterNodeModules(files, pkg)
- } else {
- // If a directory is excluded, we still need to be
- // able to *include* a file within it, and have that override
- // the prior exclusion.
- //
- // This whole makeList thing probably needs to be rewritten
- files = files.filter(function (f) {
- return excludes.filter(dir, exList)(f) || f.slice(-1) === "/"
- })
- }
-
-
- asyncMap(files, function (file, cb) {
- // if this is a dir, then dive into it.
- // otherwise, don't.
- file = path.resolve(dir, file)
-
- // in 0.6.0, fs.readdir can produce some really odd results.
- // XXX: remove this and make the engines hash exclude 0.6.0
- if (file.indexOf(dir) !== 0) {
- return cb(null, [])
- }
-
- fs.lstat(file, function (er, st) {
- if (er) return cb(er)
- if (st.isDirectory()) {
- return makeList_(file, pkg, exList, dfc, cb)
- }
- return cb(null, file)
- })
- }, function (er, files, c) {
- if (c) cleanup = (cleanup || []).concat(c)
- if (files.length > 0) files.push(dir)
- return cb(er, files, cleanup)
- })
- }
-}
-
-// only include node_modules folder that are:
-// 1. not on the dependencies list or
-// 2. on the "bundleDependencies" list.
-function filterNodeModules (files, pkg) {
- var bd = pkg.bundleDependencies || pkg.bundledDependencies || []
- , deps = Object.keys(pkg.dependencies || {})
- .filter(function (key) { return !pkg.dependencies[key].extraneous })
- .concat(Object.keys(pkg.devDependencies || {}))
-
- delete pkg.bundledDependencies
- pkg.bundleDependencies = bd
-
- return files.filter(function (f) {
- f = f.replace(/\/$/, "")
- return f.charAt(0) !== "."
- && f.charAt(0) !== "_"
- && bd.indexOf(f) !== -1
- })
-}
+++ /dev/null
-module.exports = uidNumber
-
-// This module calls into bin/npm-get-uid-gid.js, which sets the
-// uid and gid to the supplied argument, in order to find out their
-// numeric value. This can't be done in the main node process,
-// because otherwise npm would be running as that user.
-
-var exec = require("./exec.js")
- , path = require("path")
- , log = require("./log.js")
- , constants = require("constants")
- , npm = require("../npm.js")
- , uidSupport = process.getuid && process.setuid
- , uidCache = {}
- , gidCache = {}
-
-function uidNumber (uid, gid, cb) {
- if (!uidSupport || npm.config.get("unsafe-perm")) return cb()
- if (typeof cb !== "function") cb = gid, gid = null
- if (typeof cb !== "function") cb = uid, uid = null
- if (gid == null) gid = process.getgid()
- if (uid == null) uid = process.getuid()
- if (!isNaN(gid)) gid = +gid
- if (!isNaN(uid)) uid = +uid
-
- if (uidCache[uid]) uid = uidCache[uid]
- if (gidCache[gid]) gid = gidCache[gid]
-
- if (typeof gid === "number" && typeof uid === "number") {
- return cb(null, uid, gid)
- }
-
- var getter = path.join(__dirname, "..", "..", "bin", "npm-get-uid-gid.js")
- return exec( process.execPath, [getter, uid, gid], process.env, false
- , null, process.getuid(), process.getgid()
- , function (er, code, out, err) {
- if (er) return log.er(cb, "Could not get uid/gid "+err)(er)
- log.silly(out, "output from getuid/gid")
- out = JSON.parse(out+"")
- if (out.error) {
- if (!npm.config.get("unsafe-perm")) {
- var er = new Error(out.error)
- er.errno = out.errno
- return cb(er)
- } else {
- return cb(null, +process.getuid(), +process.getgid())
- }
- }
- if (isNaN(out.uid) || isNaN(out.gid)) return cb(new Error(
- "Could not get uid/gid: "+JSON.stringify(out)))
- uidCache[uid] = out.uid
- uidCache[gid] = out.gid
- cb(null, out.uid, out.gid)
- })
-}
.fi
.
.SH "VERSION"
-1.1.10
+1.1.14
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
.fi
.
.SH "VERSION"
-1.1.10
+1.1.14
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
--- /dev/null
+archy
+=====
+
+Render nested hierarchies `npm ls` style with unicode pipes.
+
+[![build status](https://secure.travis-ci.org/substack/node-archy.png)](http://travis-ci.org/substack/node-archy)
+
+example
+=======
+
+``` js
+var archy = require('archy');
+var s = archy({
+ label : 'beep',
+ nodes : [
+ 'ity',
+ {
+ label : 'boop',
+ nodes : [
+ {
+ label : 'o_O',
+ nodes : [
+ {
+ label : 'oh',
+ nodes : [ 'hello', 'puny' ]
+ },
+ 'human'
+ ]
+ },
+ 'party\ntime!'
+ ]
+ }
+ ]
+});
+console.log(s);
+```
+
+output
+
+```
+beep
+├── ity
+└─┬ boop
+ ├─┬ o_O
+ │ ├─┬ oh
+ │ │ ├── hello
+ │ │ └── puny
+ │ └── human
+ └── party
+ time!
+```
+
+methods
+=======
+
+var archy = require('archy')
+
+archy(obj, prefix='', opts={})
+------------------------------
+
+Return a string representation of `obj` with unicode pipe characters like how
+`npm ls` looks.
+
+`obj` should be a tree of nested objects with `'label'` and `'nodes'` fields.
+`'label'` is a string of text to display at a node level and `'nodes'` is an
+array of the descendents of the current node.
+
+If a node is a string, that string will be used as the `'label'` and an empty
+array of `'nodes'` will be used.
+
+`prefix` gets prepended to all the lines and is used by the algorithm to
+recursively update.
+
+If `'label'` has newlines they will be indented at the present indentation level
+with the current prefix.
+
+To disable unicode results in favor of all-ansi output set `opts.unicode` to
+`false`.
+
+install
+=======
+
+With [npm](http://npmjs.org) do:
+
+```
+npm install archy
+```
+
+license
+=======
+
+MIT/X11
--- /dev/null
+module.exports = function archy (obj, prefix, opts) {
+ if (prefix === undefined) prefix = '';
+ if (!opts) opts = {};
+ var chr = function (s) {
+ var chars = {
+ '│' : '|',
+ 'â””' : '`',
+ '├' : '+',
+ '─' : '-',
+ '┬' : '-'
+ };
+ return opts.unicode === false ? chars[s] : s;
+ };
+
+ if (typeof obj === 'string') obj = { label : obj };
+
+ var nodes = obj.nodes || [];
+ var lines = (obj.label || '').split('\n');
+ var splitter = '\n' + prefix + (nodes.length ? chr('│') : ' ') + ' ';
+
+ return prefix
+ + lines.join(splitter) + '\n'
+ + nodes.map(function (node, ix) {
+ var last = ix === nodes.length - 1;
+ var more = node.nodes && node.nodes.length;
+ var prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
+
+ return prefix
+ + (last ? chr('└') : chr('├')) + chr('─')
+ + (more ? chr('┬') : chr('─')) + ' '
+ + archy(node, prefix_, opts).slice(prefix.length + 2)
+ ;
+ }).join('')
+ ;
+};
--- /dev/null
+{
+ "name": "archy",
+ "version": "0.0.2",
+ "description": "render nested hierarchies `npm ls` style with unicode pipes",
+ "main": "index.js",
+ "directories": {
+ "lib": ".",
+ "example": "example",
+ "test": "test"
+ },
+ "devDependencies": {
+ "tap": "~0.2.3"
+ },
+ "scripts": {
+ "test": "tap test"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/substack/node-archy.git"
+ },
+ "keywords": [
+ "hierarchy",
+ "npm ls",
+ "unicode",
+ "pretty",
+ "print"
+ ],
+ "author": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "license": "MIT/X11",
+ "engine": {
+ "node": ">=0.4"
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "archy@0.0.2",
+ "dependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_engineSupported": true,
+ "_npmVersion": "1.1.13",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "_from": "archy@0.0.2"
+}
--- /dev/null
+Like `chown -R`.
+
+Takes the same arguments as `fs.chown()`
--- /dev/null
+module.exports = chownr
+chownr.sync = chownrSync
+
+var fs = require("fs")
+, path = require("path")
+
+function chownr (p, uid, gid, cb) {
+ fs.readdir(p, function (er, children) {
+ // any error other than ENOTDIR means it's not readable, or
+ // doesn't exist. give up.
+ if (er && er.code !== "ENOTDIR") return cb(er)
+ if (er || !children.length) return fs.chown(p, uid, gid, cb)
+
+ var len = children.length
+ , errState = null
+ children.forEach(function (child) {
+ chownr(path.resolve(p, child), uid, gid, then)
+ })
+ function then (er) {
+ if (errState) return
+ if (er) return cb(errState = er)
+ if (-- len === 0) return fs.chown(p, uid, gid, cb)
+ }
+ })
+}
+
+function chownrSync (p, uid, gid) {
+ var children
+ try {
+ children = fs.readdirSync(p)
+ } catch (er) {
+ if (er && er.code === "ENOTDIR") return fs.chownSync(p, uid, gid)
+ throw er
+ }
+ if (!children.length) return fs.chownSync(p, uid, gid)
+
+ children.forEach(function (child) {
+ chownrSync(path.resolve(p, child), uid, gid)
+ })
+ return fs.chownSync(p, uid, gid)
+}
--- /dev/null
+{
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "name": "chownr",
+ "description": "like `chown -R`",
+ "version": "0.0.1",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/chownr.git"
+ },
+ "main": "chownr.js",
+ "devDependencies": {
+ "tap": "0.2",
+ "mkdirp": "0.3",
+ "rimraf": ""
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "chownr@0.0.1",
+ "dependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_engineSupported": true,
+ "_npmVersion": "1.1.13",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "_from": "chownr"
+}
+++ /dev/null
-node_modules/
+++ /dev/null
-language: node_js
-node_js:
- - 0.4
- - 0.6
+++ /dev/null
-# The Problem
-
-You've got some thing where you need to push a bunch of stuff into a
-queue and then shift it out. Or, maybe it's a stack, and you're just
-pushing and popping it.
-
-Arrays work for this, but are a bit costly performance-wise.
-
-# The Solution
-
-A linked-list implementation that takes advantage of what v8 is good at:
-creating objects with a known shape.
-
-This is faster for this use case. How much faster? About 50%.
-
- $ node bench.js
- benchmarking /Users/isaacs/dev-src/js/fast-list/bench.js
- Please be patient.
- { node: '0.6.2-pre',
- v8: '3.6.6.8',
- ares: '1.7.5-DEV',
- uv: '0.1',
- openssl: '0.9.8l' }
- Scores: (bigger is better)
-
- new FastList()
- Raw:
- > 22556.39097744361
- > 23054.755043227666
- > 22770.398481973436
- > 23414.634146341465
- > 23099.133782483157
- Average (mean) 22979.062486293868
-
- []
- Raw:
- > 12195.121951219513
- > 12184.508268059182
- > 12173.91304347826
- > 12216.404886561955
- > 12184.508268059182
- Average (mean) 12190.891283475617
-
- new Array()
- Raw:
- > 12131.715771230503
- > 12184.508268059182
- > 12216.404886561955
- > 12195.121951219513
- > 11940.298507462687
- Average (mean) 12133.609876906768
-
- Winner: new FastList()
- Compared with next highest ([]), it's:
- 46.95% faster
- 1.88 times as fast
- 0.28 order(s) of magnitude faster
-
- Compared with the slowest (new Array()), it's:
- 47.2% faster
- 1.89 times as fast
- 0.28 order(s) of magnitude faster
-
-This lacks a lot of features that arrays have:
-
-1. You can't specify the size at the outset.
-2. It's not indexable.
-3. There's no join, concat, etc.
-
-If any of this matters for your use case, you're probably better off
-using an Array object.
-
-## Installing
-
-```
-npm install fast-list
-```
-
-## API
-
-```javascript
-var FastList = require("fast-list")
-var list = new FastList()
-list.push("foo")
-list.unshift("bar")
-list.push("baz")
-console.log(list.length) // 2
-console.log(list.pop()) // baz
-console.log(list.shift()) // bar
-console.log(list.shift()) // foo
-```
-
-### Methods
-
-* `push`: Just like Array.push, but only can take a single entry
-* `pop`: Just like Array.pop
-* `shift`: Just like Array.shift
-* `unshift`: Just like Array.unshift, but only can take a single entry
-* `drop`: Drop all entries
-* `item(n)`: Retrieve the nth item in the list. This involves a walk
- every time. It's very slow. If you find yourself using this,
- consider using a normal Array instead.
-* `map(fn, thisp)`: Like `Array.prototype.map`. Returns a new FastList.
-* `reduce(fn, startValue, thisp)`: Like `Array.prototype.reduce`
-* `forEach(fn, this)`: Like `Array.prototype.forEach`
-* `filter(fn, thisp)`: Like `Array.prototype.filter`. Returns a new
- FastList.
-* `slice(start, end)`: Retrieve an array of the items at this position.
- This involves a walk every time. It's very slow. If you find
- yourself using this, consider using a normal Array instead.
-
-### Members
-
-* `length`: The number of things in the list. Note that, unlike
- Array.length, this is not a getter/setter, but rather a counter that
- is internally managed. Setting it can only cause harm.
+++ /dev/null
-;(function() { // closure for web browsers
-
-function Item (data, prev, next) {
- this.next = next
- if (next) next.prev = this
- this.prev = prev
- if (prev) prev.next = this
- this.data = data
-}
-
-function FastList () {
- if (!(this instanceof FastList)) return new FastList
- this._head = null
- this._tail = null
- this.length = 0
-}
-
-FastList.prototype =
-{ push: function (data) {
- this._tail = new Item(data, this._tail, null)
- if (!this._head) this._head = this._tail
- this.length ++
- }
-
-, pop: function () {
- if (this.length === 0) return undefined
- var t = this._tail
- this._tail = t.prev
- if (t.prev) {
- t.prev = this._tail.next = null
- }
- this.length --
- if (this.length === 1) this._head = this._tail
- else if (this.length === 0) this._head = this._tail = null
- return t.data
- }
-
-, unshift: function (data) {
- this._head = new Item(data, null, this._head)
- if (!this._tail) this._tail = this._head
- this.length ++
- }
-
-, shift: function () {
- if (this.length === 0) return undefined
- var h = this._head
- this._head = h.next
- if (h.next) {
- h.next = this._head.prev = null
- }
- this.length --
- if (this.length === 1) this._tail = this._head
- else if (this.length === 0) this._head = this._tail = null
- return h.data
- }
-
-, item: function (n) {
- if (n < 0) n = this.length + n
- var h = this._head
- while (n-- > 0 && h) h = h.next
- return h ? h.data : undefined
- }
-
-, slice: function (n, m) {
- if (!n) n = 0
- if (!m) m = this.length
- if (m < 0) m = this.length + m
- if (n < 0) n = this.length + n
-
- if (m === n) {
- return []
- }
-
- if (m < n) {
- throw new Error("invalid offset: "+n+","+m+" (length="+this.length+")")
- }
-
- var len = m - n
- , ret = new Array(len)
- , i = 0
- , h = this._head
- while (n-- > 0 && h) h = h.next
- while (i < len && h) {
- ret[i++] = h.data
- h = h.next
- }
- return ret
- }
-
-, drop: function () {
- FastList.call(this)
- }
-
-, forEach: function (fn, thisp) {
- var p = this._head
- , i = 0
- , len = this.length
- while (i < len && p) {
- fn.call(thisp || this, p.data, i, this)
- p = p.next
- i ++
- }
- }
-
-, map: function (fn, thisp) {
- var n = new FastList()
- this.forEach(function (v, i, me) {
- n.push(fn.call(thisp || me, v, i, me))
- })
- return n
- }
-
-, filter: function (fn, thisp) {
- var n = new FastList()
- this.forEach(function (v, i, me) {
- if (fn.call(thisp || me, v, i, me)) n.push(v)
- })
- return n
- }
-
-, reduce: function (fn, val, thisp) {
- var i = 0
- , p = this._head
- , len = this.length
- if (!val) {
- i = 1
- val = p && p.data
- p = p && p.next
- }
- while (i < len && p) {
- val = fn.call(thisp || this, val, p.data, this)
- i ++
- p = p.next
- }
- return val
- }
-}
-
-if ("undefined" !== typeof(exports)) module.exports = FastList
-else if ("function" === typeof(define) && define.amd) {
- define("FastList", function() { return FastList })
-} else (function () { return this })().FastList = FastList
-
-})()
+++ /dev/null
-{
- "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
- "name": "fast-list",
- "description": "A fast linked list (good for queues, stacks, etc.)",
- "version": "1.0.2",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/fast-list.git"
- },
- "main": "fast-list.js",
- "dependencies": {},
- "devDependencies": {
- "bench": "~0.3.2",
- "tap": "~0.1.0"
- },
- "scripts": {
- "test": "tap test.js",
- "bench": "node bench.js"
- }
-}
--- /dev/null
+# ignore the output junk from the example scripts
+example/output
--- /dev/null
+# fstream-npm
+
+This is an fstream DirReader class that will read a directory and filter
+things according to the semantics of what goes in an npm package.
+
+For example:
+
+```javascript
+// This will print out all the files that would be included
+// by 'npm publish' or 'npm install' of this directory.
+
+var FN = require("fstream-npm")
+FN({ path: "./" })
+ .on("child", function (e) {
+ console.error(e.path.substr(e.root.path.length + 1))
+ })
+```
+
--- /dev/null
+var Ignore = require("fstream-ignore")
+, inherits = require("inherits")
+, path = require("path")
+, fs = require("fs")
+
+module.exports = Packer
+
+inherits(Packer, Ignore)
+
+function Packer (props) {
+ if (!(this instanceof Packer)) {
+ return new Packer(props)
+ }
+
+ if (typeof props === "string") {
+ props = { path: props }
+ }
+
+ props.ignoreFiles = [ ".npmignore",
+ ".gitignore",
+ "package.json" ]
+
+ Ignore.call(this, props)
+
+ this.bundled = props.bundled
+ this.bundleLinks = props.bundleLinks
+ this.package = props.package
+
+ // in a node_modules folder, resolve symbolic links to
+ // bundled dependencies when creating the package.
+ props.follow = this.follow = this.basename === "node_modules"
+ // console.error("follow?", this.path, props.follow)
+
+ if (this === this.root ||
+ this.parent &&
+ this.parent.basename === "node_modules" &&
+ this.basename.charAt(0) !== ".") {
+ this.readBundledLinks()
+ }
+
+
+ this.on("entryStat", function (entry, props) {
+ // files should *always* get into tarballs
+ // in a user-writable state, even if they're
+ // being installed from some wackey vm-mounted
+ // read-only filesystem.
+ entry.mode = props.mode = props.mode | 0200
+ })
+}
+
+Packer.prototype.readBundledLinks = function () {
+ if (this._paused) {
+ this.once("resume", this.addIgnoreFiles)
+ return
+ }
+
+ this.pause()
+ fs.readdir(this.path + "/node_modules", function (er, list) {
+ // no harm if there's no bundle
+ var l = list && list.length
+ if (er || l === 0) return this.resume()
+
+ var errState = null
+ , then = function then (er) {
+ if (errState) return
+ if (er) return errState = er, this.resume()
+ if (-- l === 0) return this.resume()
+ }.bind(this)
+
+ list.forEach(function (pkg) {
+ if (pkg.charAt(0) === ".") return then()
+ var pd = this.path + "/node_modules/" + pkg
+ fs.realpath(pd, function (er, rp) {
+ if (er) return then()
+ this.bundleLinks = this.bundleLinks || {}
+ this.bundleLinks[pkg] = rp
+ then()
+ }.bind(this))
+ }, this)
+ }.bind(this))
+}
+
+Packer.prototype.applyIgnores = function (entry, partial, entryObj) {
+ // package.json files can never be ignored.
+ if (entry === "package.json") return true
+
+ // special rules. see below.
+ if (entry === "node_modules") return true
+
+ // some files are *never* allowed under any circumstances
+ if (entry === ".git" ||
+ entry === ".lock-wscript" ||
+ entry.match(/^\.wafpickle-[0-9]+$/) ||
+ entry === "CVS" ||
+ entry === ".svn" ||
+ entry === ".hg" ||
+ entry.match(/^\..*\.swp$/) ||
+ entry === ".DS_Store" ||
+ entry.match(/^\._/) ||
+ entry === "npm-debug.log"
+ ) {
+ return false
+ }
+
+ // in a node_modules folder, we only include bundled dependencies
+ // also, prevent packages in node_modules from being affected
+ // by rules set in the containing package, so that
+ // bundles don't get busted.
+ // Also, once in a bundle, everything is installed as-is
+ // To prevent infinite cycles in the case of cyclic deps that are
+ // linked with npm link, even in a bundle, deps are only bundled
+ // if they're not already present at a higher level.
+ if (this.basename === "node_modules") {
+ // bubbling up. stop here and allow anything the bundled pkg allows
+ if (entry.indexOf("/") !== -1) return true
+
+ // never include the .bin. It's typically full of platform-specific
+ // stuff like symlinks and .cmd files anyway.
+ if (entry === ".bin") return false
+
+ var shouldBundle = false
+ // the package root.
+ var p = this.parent
+ // the package before this one.
+ var pp = p && p.parent
+
+ // if this entry has already been bundled, and is a symlink,
+ // and it is the *same* symlink as this one, then exclude it.
+ if (pp && pp.bundleLinks && this.bundleLinks &&
+ pp.bundleLinks[entry] === this.bundleLinks[entry]) {
+ return false
+ }
+
+ // since it's *not* a symbolic link, if we're *already* in a bundle,
+ // then we should include everything.
+ if (pp && pp.package) {
+ return true
+ }
+
+ // only include it at this point if it's a bundleDependency
+ var bd = this.package && this.package.bundleDependencies
+ var shouldBundle = bd && bd.indexOf(entry) !== -1
+ // if we're not going to bundle it, then it doesn't count as a bundleLink
+ // if (this.bundleLinks && !shouldBundle) delete this.bundleLinks[entry]
+ return shouldBundle
+ }
+ // if (this.bundled) return true
+
+ return Ignore.prototype.applyIgnores.call(this, entry, partial, entryObj)
+}
+
+Packer.prototype.addIgnoreFiles = function () {
+ var entries = this.entries
+ // if there's a .npmignore, then we do *not* want to
+ // read the .gitignore.
+ if (-1 !== entries.indexOf(".npmignore")) {
+ var i = entries.indexOf(".gitignore")
+ if (i !== -1) {
+ entries.splice(i, 1)
+ }
+ }
+
+ this.entries = entries
+
+ Ignore.prototype.addIgnoreFiles.call(this)
+}
+
+
+Packer.prototype.readRules = function (buf, e) {
+ if (e !== "package.json") {
+ return Ignore.prototype.readRules.call(this, buf, e)
+ }
+
+ var p = this.package = JSON.parse(buf.toString())
+
+ if (this === this.root) {
+ this.bundleLinks = this.bundleLinks || {}
+ this.bundleLinks[p.name] = this._path
+ }
+
+ this.packageRoot = true
+ this.emit("package", p)
+
+ // make bundle deps predictable
+ if (p.bundledDependencies && !p.bundleDependencies) {
+ p.bundleDependencies = p.bundledDependencies
+ delete p.bundledDependencies
+ }
+
+ if (!p.files || !Array.isArray(p.files)) return []
+
+ // ignore everything except what's in the files array.
+ return ["*"].concat(p.files.map(function (f) {
+ return "!" + f
+ })).concat(p.files.map(function (f) {
+ return "!" + f.replace(/\/+$/, "") + "/**"
+ }))
+}
+
+Packer.prototype.getChildProps = function (stat) {
+ var props = Ignore.prototype.getChildProps.call(this, stat)
+
+ props.package = this.package
+
+ props.bundled = this.bundled && this.bundled.slice(0)
+ props.bundleLinks = this.bundleLinks &&
+ Object.create(this.bundleLinks)
+
+ // Directories have to be read as Packers
+ // otherwise fstream.Reader will create a DirReader instead.
+ if (stat.isDirectory()) {
+ props.type = this.constructor
+ }
+
+ // only follow symbolic links directly in the node_modules folder.
+ props.follow = false
+ return props
+}
+
+
+var order =
+ [ "package.json"
+ , ".npmignore"
+ , ".gitignore"
+ , /^README(\.md)?$/
+ , "LICENCE"
+ , "LICENSE"
+ , /\.js$/ ]
+
+Packer.prototype.sort = function (a, b) {
+ for (var i = 0, l = order.length; i < l; i ++) {
+ var o = order[i]
+ if (typeof o === "string") {
+ if (a === o) return -1
+ if (b === o) return 1
+ } else {
+ if (a.match(o)) return -1
+ if (b.match(o)) return 1
+ }
+ }
+
+ // deps go in the back
+ if (a === "node_modules") return 1
+ if (b === "node_modules") return -1
+
+ return Ignore.prototype.sort.call(this, a, b)
+}
+
+
+
+Packer.prototype.emitEntry = function (entry) {
+ if (this._paused) {
+ this.once("resume", this.emitEntry.bind(this, entry))
+ return
+ }
+
+ // if there is a .gitignore, then we're going to
+ // rename it to .npmignore in the output.
+ if (entry.basename === ".gitignore") {
+ entry.basename = ".npmignore"
+ entry.path = path.resolve(entry.dirname, entry.basename)
+ }
+
+ // all *.gyp files are renamed to binding.gyp for node-gyp
+ if (entry.basename.match(/\.gyp$/)) {
+ entry.basename = "binding.gyp"
+ entry.path = path.resolve(entry.dirname, entry.basename)
+ }
+
+ // skip over symbolic links
+ if (entry.type === "SymbolicLink") {
+ entry.abort()
+ return
+ }
+
+ if (entry.type !== "Directory") {
+ // make it so that the folder in the tarball is named "package"
+ var h = path.dirname((entry.root || entry).path)
+ , t = entry.path.substr(h.length + 1).replace(/^[^\/\\]+/, "package")
+ , p = h + "/" + t
+
+ entry.path = p
+ entry.dirname = path.dirname(p)
+ return Ignore.prototype.emitEntry.call(this, entry)
+ }
+
+ // we don't want empty directories to show up in package
+ // tarballs.
+ // don't emit entry events for dirs, but still walk through
+ // and read them. This means that we need to proxy up their
+ // entry events so that those entries won't be missed, since
+ // .pipe() doesn't do anythign special with "child" events, on
+ // with "entry" events.
+ var me = this
+ entry.on("entry", function (e) {
+ if (e.parent === entry) {
+ e.parent = me
+ me.emit("entry", e)
+ }
+ })
+ entry.on("package", this.emit.bind(this, "package"))
+}
--- /dev/null
+test/fixtures
--- /dev/null
+# fstream-ignore
+
+A fstream DirReader that filters out files that match globs in `.ignore`
+files throughout the tree, like how git ignores files based on a
+`.gitignore` file.
+
+Here's an example:
+
+```javascript
+var Ignore = require("fstream-ignore")
+Ignore({ path: __dirname
+ , ignoreFiles: [".ignore", ".gitignore"]
+ })
+ .on("child", function (c) {
+ console.error(c.path.substr(c.root.path.length + 1))
+ })
+ .pipe(tar.Pack())
+ .pipe(fs.createWriteStream("foo.tar"))
+```
+
+This will tar up the files in __dirname into `foo.tar`, ignoring
+anything matched by the globs in any .iginore or .gitignore file.
--- /dev/null
+// Essentially, this is a fstream.DirReader class, but with a
+// bit of special logic to read the specified sort of ignore files,
+// and a filter that prevents it from picking up anything excluded
+// by those files.
+
+var Minimatch = require("minimatch").Minimatch
+, fstream = require("fstream")
+, DirReader = fstream.DirReader
+, inherits = require("inherits")
+, path = require("path")
+, fs = require("fs")
+
+module.exports = IgnoreReader
+
+inherits(IgnoreReader, DirReader)
+
+function IgnoreReader (props) {
+ if (!(this instanceof IgnoreReader)) {
+ return new IgnoreReader(props)
+ }
+
+ // must be a Directory type
+ if (typeof props === "string") {
+ props = { path: path.resolve(props) }
+ }
+
+ props.type = "Directory"
+ props.Directory = true
+
+ if (!props.ignoreFiles) props.ignoreFiles = [".ignore"]
+ this.ignoreFiles = props.ignoreFiles
+
+ this.ignoreRules = null
+
+ // ensure that .ignore files always show up at the top of the list
+ // that way, they can be read before proceeding to handle other
+ // entries in that same folder
+ if (props.sort) {
+ this._sort = props.sort === "alpha" ? alphasort : props.sort
+ props.sort = null
+ }
+
+ this.on("entries", function () {
+ // if there are any ignore files in the list, then
+ // pause and add them.
+ // then, filter the list based on our ignoreRules
+
+ var hasIg = this.entries.some(this.isIgnoreFile, this)
+
+ if (!hasIg) return this.filterEntries()
+
+ this.addIgnoreFiles()
+ })
+
+ // we filter entries before we know what they are.
+ // however, directories have to be re-tested against
+ // rules with a "/" appended, because "a/b/" will only
+ // match if "a/b" is a dir, and not otherwise.
+ this.on("_entryStat", function (entry, props) {
+ var t = entry.basename
+ if (!this.applyIgnores(entry.basename,
+ entry.type === "Directory",
+ entry)) {
+ entry.abort()
+ }
+ }.bind(this))
+
+ DirReader.call(this, props)
+}
+
+
+IgnoreReader.prototype.addIgnoreFiles = function () {
+ if (this._paused) {
+ this.once("resume", this.addIgnoreFiles)
+ return
+ }
+ if (this._ignoreFilesAdded) return
+ this._ignoreFilesAdded = true
+
+ var newIg = this.entries.filter(this.isIgnoreFile, this)
+ , count = newIg.length
+ , errState = null
+
+ if (!count) return
+
+ this.pause()
+
+ var then = function then (er) {
+ if (errState) return
+ if (er) return this.emit("error", errState = er)
+ if (-- count === 0) {
+ this.filterEntries()
+ this.resume()
+ }
+ }.bind(this)
+
+ newIg.forEach(function (ig) {
+ this.addIgnoreFile(ig, then)
+ }, this)
+}
+
+
+IgnoreReader.prototype.isIgnoreFile = function (e) {
+ return e !== "." &&
+ e !== ".." &&
+ -1 !== this.ignoreFiles.indexOf(e)
+}
+
+
+IgnoreReader.prototype.getChildProps = function (stat) {
+ var props = DirReader.prototype.getChildProps.call(this, stat)
+ props.ignoreFiles = this.ignoreFiles
+
+ // Directories have to be read as IgnoreReaders
+ // otherwise fstream.Reader will create a DirReader instead.
+ if (stat.isDirectory()) {
+ props.type = this.constructor
+ }
+ return props
+}
+
+
+IgnoreReader.prototype.addIgnoreFile = function (e, cb) {
+ // read the file, and then call addIgnoreRules
+ // if there's an error, then tell the cb about it.
+
+ var ig = path.resolve(this.path, e)
+ fs.readFile(ig, function (er, data) {
+ if (er) return cb(er)
+
+ this.emit("ignoreFile", e, data)
+ var rules = this.readRules(data, e)
+ this.addIgnoreRules(rules, e)
+ cb()
+ }.bind(this))
+}
+
+
+IgnoreReader.prototype.readRules = function (buf, e) {
+ return buf.toString().split(/\r?\n/)
+}
+
+
+// Override this to do fancier things, like read the
+// "files" array from a package.json file or something.
+IgnoreReader.prototype.addIgnoreRules = function (set, e) {
+ // filter out anything obvious
+ set = set.filter(function (s) {
+ s = s.trim()
+ return s && !s.match(/^#/)
+ })
+
+ // no rules to add!
+ if (!set.length) return
+
+ // now get a minimatch object for each one of these.
+ // Note that we need to allow dot files by default, and
+ // not switch the meaning of their exclusion
+ var mmopt = { matchBase: true, dot: true, flipNegate: true }
+ , mm = set.map(function (s) {
+ var m = new Minimatch(s, mmopt)
+ m.ignoreFile = e
+ return m
+ })
+
+ if (!this.ignoreRules) this.ignoreRules = []
+ this.ignoreRules.push.apply(this.ignoreRules, mm)
+}
+
+
+IgnoreReader.prototype.filterEntries = function () {
+ // this exclusion is at the point where we know the list of
+ // entries in the dir, but don't know what they are. since
+ // some of them *might* be directories, we have to run the
+ // match in dir-mode as well, so that we'll pick up partials
+ // of files that will be included later. Anything included
+ // at this point will be checked again later once we know
+ // what it is.
+ this.entries = this.entries.filter(function (entry) {
+ // at this point, we don't know if it's a dir or not.
+ return this.applyIgnores(entry) || this.applyIgnores(entry, true)
+ }, this)
+}
+
+
+IgnoreReader.prototype.applyIgnores = function (entry, partial, obj) {
+ var included = true
+
+ // this = /a/b/c
+ // entry = d
+ // parent /a/b sees c/d
+ if (this.parent && this.parent.applyIgnores) {
+ var pt = this.basename + "/" + entry
+ included = this.parent.applyIgnores(pt, partial)
+ }
+
+ // Negated Rules
+ // Since we're *ignoring* things here, negating means that a file
+ // is re-included, if it would have been excluded by a previous
+ // rule. So, negated rules are only relevant if the file
+ // has been excluded.
+ //
+ // Similarly, if a file has been excluded, then there's no point
+ // trying it against rules that have already been applied
+ //
+ // We're using the "flipnegate" flag here, which tells minimatch
+ // to set the "negate" for our information, but still report
+ // whether the core pattern was a hit or a miss.
+
+ if (!this.ignoreRules) {
+ return included
+ }
+
+ this.ignoreRules.forEach(function (rule) {
+ // negation means inclusion
+ if (rule.negate && included ||
+ !rule.negate && !included) {
+ // unnecessary
+ return
+ }
+
+ // first, match against /foo/bar
+ var match = rule.match("/" + entry)
+
+ if (!match) {
+ // try with the leading / trimmed off the test
+ // eg: foo/bar instead of /foo/bar
+ match = rule.match(entry)
+ }
+
+ // if the entry is a directory, then it will match
+ // with a trailing slash. eg: /foo/bar/ or foo/bar/
+ if (!match && partial) {
+ match = rule.match("/" + entry + "/") ||
+ rule.match(entry + "/")
+ }
+
+ // When including a file with a negated rule, it's
+ // relevant if a directory partially matches, since
+ // it may then match a file within it.
+ // Eg, if you ignore /a, but !/a/b/c
+ if (!match && rule.negate && partial) {
+ match = rule.match("/" + entry, true) ||
+ rule.match(entry, true)
+ }
+
+ if (match) {
+ included = rule.negate
+ }
+ }, this)
+
+ return included
+}
+
+
+IgnoreReader.prototype.sort = function (a, b) {
+ var aig = this.ignoreFiles.indexOf(a) !== -1
+ , big = this.ignoreFiles.indexOf(b) !== -1
+
+ if (aig && !big) return -1
+ if (big && !aig) return 1
+ return this._sort(a, b)
+}
+
+IgnoreReader.prototype._sort = function (a, b) {
+ return 0
+}
+
+function alphasort (a, b) {
+ return a === b ? 0
+ : a.toLowerCase() > b.toLowerCase() ? 1
+ : a.toLowerCase() < b.toLowerCase() ? -1
+ : a > b ? 1
+ : -1
+}
--- /dev/null
+{
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "name": "fstream-ignore",
+ "description": "A thing for ignoring files based on globs",
+ "version": "0.0.5",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/fstream-ignore.git"
+ },
+ "main": "ignore.js",
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "dependencies": {
+ "minimatch": "~0.2.0",
+ "fstream": "~0.1.17",
+ "inherits": "~1.0.0"
+ },
+ "devDependencies": {
+ "tap": "",
+ "rimraf": "",
+ "mkdirp": ""
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "fstream-ignore@0.0.5",
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_engineSupported": true,
+ "_npmVersion": "1.1.13",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "_from": "fstream-ignore@~0.0.5"
+}
--- /dev/null
+{
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "name": "fstream-npm",
+ "description": "fstream class for creating npm packages",
+ "version": "0.0.4",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/fstream-npm.git"
+ },
+ "main": "./fstream-npm.js",
+ "dependencies": {
+ "fstream-ignore": "~0.0.5",
+ "inherits": ""
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "fstream-npm@0.0.4",
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_engineSupported": true,
+ "_npmVersion": "1.1.13",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "_from": "fstream-npm@0 >=0.0.3"
+}
.*.swp
-examples/deep-copy
node_modules/
+examples/deep-copy/
+examples/path/
+examples/filter-copy/
--- /dev/null
+Copyright (c) Isaac Z. Schlueter
+All rights reserved.
+
+The BSD License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
return this
}
+Abstract.prototype.abort = function () {
+ this._aborted = true
+ this.emit("abort")
+}
+
Abstract.prototype.destroy = function () {}
Abstract.prototype.warn = function (msg, code) {
, mkdir = require("mkdirp")
, path = require("path")
, Reader = require("./reader.js")
+ , assert = require("assert").ok
inherits(DirReader, Reader)
throw new Error("Non-directory type "+ props.type)
}
- me._entries = null
+ me.entries = null
me._index = -1
me._paused = false
me._length = -1
+ if (props.sort) {
+ this.sort = props.sort
+ }
+
Reader.call(this, props)
}
DirReader.prototype._getEntries = function () {
var me = this
+
+ // race condition. might pause() before calling _getEntries,
+ // and then resume, and try to get them a second time.
+ if (me._gotEntries) return
+ me._gotEntries = true
+
fs.readdir(me._path, function (er, entries) {
if (er) return me.error(er)
- me._entries = entries
- me._length = entries.length
- // console.error("DR %s sort =", me.path, me.props.sort)
- if (typeof me.props.sort === "function") {
- me._entries.sort(me.props.sort)
+
+ me.entries = entries
+
+ me.emit("entries", entries)
+ if (me._paused) me.once("resume", processEntries)
+ else processEntries()
+
+ function processEntries () {
+ me._length = me.entries.length
+ if (typeof me.sort === "function") {
+ me.entries = me.entries.sort(me.sort.bind(me))
+ }
+ me._read()
}
- me._read()
})
}
DirReader.prototype._read = function () {
var me = this
- if (!me._entries) return me._getEntries()
+ if (!me.entries) return me._getEntries()
if (me._paused || me._currentEntry || me._aborted) {
// console.error("DR paused=%j, current=%j, aborted=%j", me._paused, !!me._currentEntry, me._aborted)
}
me._index ++
- if (me._index >= me._length) {
+ if (me._index >= me.entries.length) {
if (!me._ended) {
me._ended = true
me.emit("end")
// ok, handle this one, then.
// save creating a proxy, by stat'ing the thing now.
- var p = path.resolve(me._path, me._entries[me._index])
+ var p = path.resolve(me._path, me.entries[me._index])
+ assert(p !== me._path)
+ assert(me.entries[me._index])
+
// set this to prevent trying to _read() again in the stat time.
me._currentEntry = p
fs[ me.props.follow ? "stat" : "lstat" ](p, function (er, stat) {
if (er) return me.error(er)
- var entry = Reader({ path: p
- , depth: me.depth + 1
- , root: me.root || me._proxy || me
- , parent: me._proxy || me
- , follow: me.follow
- , filter: me.filter
- , sort: me.props.sort
- }, stat)
+ var who = me._proxy || me
+
+ stat.path = p
+ stat.basename = path.basename(p)
+ stat.dirname = path.dirname(p)
+ var childProps = me.getChildProps.call(who, stat)
+ childProps.path = p
+ childProps.basename = path.basename(p)
+ childProps.dirname = path.dirname(p)
+
+ var entry = Reader(childProps, stat)
// console.error("DR Entry", p, stat.size)
// This nomenclature is not completely final.
entry.on("pause", function (who) {
- if (!me._paused) {
+ if (!me._paused && !entry._disowned) {
me.pause(who)
}
})
entry.on("resume", function (who) {
- if (me._paused) {
+ if (me._paused && !entry._disowned) {
me.resume(who)
}
})
+ entry.on("stat", function (props) {
+ me.emit("_entryStat", entry, props)
+ if (entry._aborted) return
+ if (entry._paused) entry.once("resume", function () {
+ me.emit("entryStat", entry, props)
+ })
+ })
+
entry.on("ready", function EMITCHILD () {
// console.error("DR emit child", entry._path)
if (me._paused) {
if (entry.type === "Socket") {
me.emit("socket", entry)
} else {
- me.emit("entry", entry)
- me.emit("child", entry)
+ me.emitEntry(entry)
}
})
var ended = false
entry.on("close", onend)
+ entry.on("disown", onend)
function onend () {
if (ended) return
ended = true
me.emit("childEnd", entry)
me.emit("entryEnd", entry)
me._currentEntry = null
- me._read()
+ if (!me._paused) {
+ me._read()
+ }
}
- // XXX Make this work in node.
+ // XXX Remove this. Works in node as of 0.6.2 or so.
// Long filenames should not break stuff.
entry.on("error", function (er) {
if (entry._swallowErrors) {
})
}
+DirReader.prototype.disown = function (entry) {
+ entry.emit("beforeDisown")
+ entry._disowned = true
+ entry.parent = entry.root = null
+ if (entry === this._currentEntry) {
+ this._currentEntry = null
+ }
+ entry.emit("disown")
+}
+
+DirReader.prototype.getChildProps = function (stat) {
+ return { depth: this.depth + 1
+ , root: this.root || this
+ , parent: this
+ , follow: this.follow
+ , filter: this.filter
+ , sort: this.props.sort
+ }
+}
+
DirReader.prototype.pause = function (who) {
var me = this
if (me._paused) return
}
if (me._currentEntry) {
- if (me._currentEntry.resume) {
- me._currentEntry.resume(who)
- }
+ if (me._currentEntry.resume) me._currentEntry.resume(who)
} else me._read()
}
+
+DirReader.prototype.emitEntry = function (entry) {
+ this.emit("entry", entry)
+ this.emit("child", entry)
+}
// don't allow recursive copying
var p = entry
do {
- if (p._path === me.root._path || p._path === me._path) {
+ var pp = p._path || p.path
+ if (pp === me.root._path || pp === me._path ||
+ (pp && pp.indexOf(me._path) === 0)) {
// console.error("DW Exit (recursive)", entry.basename, me._path)
me._processing = false
if (entry._collected) entry.pipe()
// get rid of any ../../ shenanigans
props.path = path.join(me.path, path.join("/", p))
+ // if i have a filter, the child should inherit it.
+ props.filter = me.filter
+
// all the rest of the stuff, copy over from the source.
Object.keys(entry.props).forEach(function (k) {
if (!props.hasOwnProperty(k)) {
var fs = require("graceful-fs")
, Writer = require("./writer.js")
, inherits = require("inherits")
- , collect = require("./collect.js")
, path = require("path")
, rimraf = require("rimraf")
, "close"
, "linkpath"
, "entry"
+ , "entryEnd"
+ , "child"
+ , "childEnd"
, "warn"
+ , "stat"
].forEach(function (ev) {
// console.error("~~ proxy event", ev, me.path)
proxy.on(ev, me.emit.bind(me, ev))
// if the filter doesn't pass, then just skip over this one.
// still have to emit end so that dir-walking can move on.
if (me.filter) {
+ var who = me._proxy || me
// special handling for ProxyReaders
- if (!me.filter.call(me._proxy || me)) {
- me._aborted = true
+ if (!me.filter.call(who, who, props)) {
+ if (!me._disowned) {
+ me.abort()
+ me.emit("end")
+ me.emit("close")
+ }
+ return
+ }
+ }
+
+ // last chance to abort or disown before the flow starts!
+ var events = ["_stat", "stat", "ready"]
+ var e = 0
+ ;(function go () {
+ if (me._aborted) {
me.emit("end")
me.emit("close")
return
}
- }
- me.emit("ready", props)
+ if (me._paused) {
+ me.once("resume", go)
+ return
+ }
- // if it's a directory, then we'll be emitting "entry" events.
- me._read()
+ var ev = events[e ++]
+ if (!ev) return me._read()
+ me.emit(ev, props)
+ go()
+ })()
}
}
me._buffer = []
me.ready = false
+ me.filter = typeof props.filter === "function" ? props.filter: null
+
// start the ball rolling.
// this checks what's there already, and then calls
// me._create() to call the impl-specific creation stuff.
var me = this
, props = me.props
, stat = props.follow ? "stat" : "lstat"
+ , who = me._proxy || me
if (current) statCb(null, current)
else fs[stat](me._path, statCb)
function statCb (er, current) {
+ if (me.filter && !me.filter.call(who, who, current)) {
+ me._aborted = true
+ me.emit("end")
+ me.emit("close")
+ return
+ }
+
// if it's not there, great. We'll just create it.
// if it is there, then we'll need to change whatever differs
if (er || !current) {
// XXX Need to clobber non-dirs that are in the way,
// unless { clobber: false } in the props.
- mkdir(path.dirname(me._path), Writer.dirmode, function (er) {
+ mkdir(path.dirname(me._path), Writer.dirmode, function (er, made) {
// console.error("W created", path.dirname(me._path), er)
if (er) return me.error(er)
- me._create()
+
+ // later on, we have to set the mode and owner for these
+ me._madeDir = made
+ return me._create()
})
}
+function endChmod (me, want, current, path, cb) {
+ var wantMode = want.mode
+ , chmod = want.follow || me.type !== "SymbolicLink"
+ ? "chmod" : "lchmod"
+
+ if (!fs[chmod]) return cb()
+ if (typeof wantMode !== "number") return cb()
+
+ var curMode = current.mode & 0777
+ wantMode = wantMode & 0777
+ if (wantMode === curMode) return cb()
+
+ fs[chmod](path, wantMode, cb)
+}
+
+
+function endChown (me, want, current, path, cb) {
+ // Don't even try it unless root. Too easy to EPERM.
+ if (process.platform === "win32") return cb()
+ if (!process.getuid || !process.getuid() === 0) return cb()
+ if (typeof want.uid !== "number" &&
+ typeof want.gid !== "number" ) return cb()
+
+ if (current.uid === want.uid &&
+ current.gid === want.gid) return cb()
+
+ var chown = (me.props.follow || me.type !== "SymbolicLink")
+ ? "chown" : "lchown"
+ if (!fs[chown]) return cb()
+
+ if (typeof want.uid !== "number") want.uid = current.uid
+ if (typeof want.gid !== "number") want.gid = current.gid
+
+ fs[chown](path, want.uid, want.gid, cb)
+}
+
+function endUtimes (me, want, current, path, cb) {
+ if (!fs.utimes || process.platform === "win32") return cb()
+
+ var utimes = (want.follow || me.type !== "SymbolicLink")
+ ? "utimes" : "lutimes"
+
+ if (utimes === "lutimes" && !fs[utimes]) {
+ utimes = "utimes"
+ }
+
+ if (!fs[utimes]) return cb()
+
+ var curA = current.atime
+ , curM = current.mtime
+ , meA = want.atime
+ , meM = want.mtime
+
+ if (meA === undefined) meA = curA
+ if (meM === undefined) meM = curM
+
+ if (!isDate(meA)) meA = new Date(meA)
+ if (!isDate(meM)) meA = new Date(meM)
+
+ if (meA.getTime() === curA.getTime() &&
+ meM.getTime() === curM.getTime()) return cb()
+
+ fs[utimes](path, meA, meM, cb)
+}
+
+
+// XXX This function is beastly. Break it up!
Writer.prototype._finish = function () {
var me = this
return
function setProps (current) {
- // console.error(" W setprops", me._path)
- // mode
- var wantMode = me.props.mode
- , chmod = me.props.follow || me.type !== "SymbolicLink"
- ? "chmod" : "lchmod"
-
- if (fs[chmod] && typeof wantMode === "number") {
- wantMode = wantMode & 0777
- todo ++
- // console.error(" W chmod", wantMode.toString(8), me.basename, "\r")
- fs[chmod](me._path, wantMode, next(chmod))
- }
+ endChmod(me, me.props, current, me._path, next("chmod"))
+ endChown(me, me.props, current, me._path, next("chown"))
+ endUtimes(me, me.props, current, me._path, next("chown"))
+ }
- // uid, gid
- // Don't even try it unless root. Too easy to EPERM.
- if (process.platform !== "win32" &&
- process.getuid && process.getuid() === 0 &&
- ( typeof me.props.uid === "number" ||
- typeof me.props.gid === "number" )) {
- var chown = (me.props.follow || me.type !== "SymbolicLink")
- ? "chown" : "lchown"
- if (fs[chown]) {
- if (typeof me.props.uid !== "number") me.props.uid = current.uid
- if (typeof me.props.gid !== "number") me.props.gid = current.gid
- if (me.props.uid !== current.uid || me.props.gid !== current.gid) {
- todo ++
- // console.error(" W chown", me.props.uid, me.props.gid, me.basename)
- fs[chown](me._path, me.props.uid, me.props.gid, next("chown"))
+ function next (what) {
+ todo ++
+ return function (er) {
+ // console.error(" W Finish", what, todo)
+ if (errState) return
+ if (er) {
+ er.fstream_finish_call = what
+ return me.error(errState = er)
+ }
+ if (--todo > 0) return
+ if (done) return
+ done = true
+
+ // we may still need to set the mode/etc. on some parent dirs
+ // that were created previously. delay end/close until then.
+ if (!me._madeDir) return end()
+ else endMadeDir(me, me._path, end)
+
+ function end (er) {
+ if (er) {
+ er.fstream_finish_call = "setupMadeDir"
+ return me.error(er)
}
+ // all the props have been set, so we're completely done.
+ me.emit("end")
+ me.emit("close")
}
}
+ }
+}
- // atime, mtime.
- if (fs.utimes && process.platform !== "win32") {
- var utimes = (me.props.follow || me.type !== "SymbolicLink")
- ? "utimes" : "lutimes"
-
- if (utimes === "lutimes" && !fs[utimes]) {
- utimes = "utimes"
- }
-
- var curA = current.atime
- , curM = current.mtime
- , meA = me.props.atime
- , meM = me.props.mtime
+function endMadeDir (me, p, cb) {
+ var made = me._madeDir
+ // everything *between* made and path.dirname(me._path)
+ // needs to be set up. Note that this may just be one dir.
+ var d = path.dirname(p)
- if (meA === undefined) meA = curA
- if (meM === undefined) meM = curM
+ endMadeDir_(me, d, function (er) {
+ if (er) return cb(er)
+ if (d === made) {
+ return cb()
+ }
+ endMadeDir(me, d, cb)
+ })
+}
- if (!isDate(meA)) meA = new Date(meA)
- if (!isDate(meM)) meA = new Date(meM)
+function endMadeDir_ (me, p, cb) {
+ var dirProps = {}
+ Object.keys(me.props).forEach(function (k) {
+ dirProps[k] = me.props[k]
- if (meA.getTime() !== curA.getTime() ||
- meM.getTime() !== curM.getTime()) {
- todo ++
- // console.error(" W utimes", meA, meM, me.basename)
- fs[utimes](me._path, meA, meM, next("utimes"))
- }
+ // only make non-readable dirs if explicitly requested.
+ if (k === "mode" && me.type !== "Directory") {
+ dirProps[k] = dirProps[k] | 0111
}
+ })
- // finally, handle the case if there was nothing to do.
- if (todo === 0) {
- // console.error(" W nothing to do", me.basename)
- next("nothing to do")()
- }
- }
+ var todo = 3
+ , errState = null
+ fs.stat(p, function (er, current) {
+ if (er) return cb(errState = er)
+ endChmod(me, dirProps, current, p, next)
+ endChown(me, dirProps, current, p, next)
+ endUtimes(me, dirProps, current, p, next)
+ })
- function next (what) { return function (er) {
- // console.error(" W Finish", what, todo)
+ function next (er) {
if (errState) return
- if (er) {
- er.fstream_finish_call = what
- return me.error(errState = er)
- }
- if (--todo > 0) return
- if (done) return
- done = true
-
- // all the props have been set, so we're completely done.
- me.emit("end")
- me.emit("close")
- }}
+ if (er) return cb(errState = er)
+ if (-- todo === 0) return cb()
+ }
}
Writer.prototype.pipe = function () {
},
"name": "fstream",
"description": "Advanced file system stream things",
- "version": "0.1.13",
+ "version": "0.1.18",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/fstream.git"
},
"main": "fstream.js",
"engines": {
- "node": "0.5 || 0.6 || 0.7"
+ "node": ">=0.6"
},
"dependencies": {
"rimraf": "2",
"inherits": "~1.0.0"
},
"devDependencies": {
- "tap": "0.1"
+ "tap": ""
},
"scripts": {
"test": "tap examples/*.js"
},
+ "license": "BSD",
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
- "_id": "fstream@0.1.13",
+ "_id": "fstream@0.1.18",
"optionalDependencies": {},
"_engineSupported": true,
- "_npmVersion": "1.1.4",
- "_nodeVersion": "v0.7.6-pre",
+ "_npmVersion": "1.1.13",
+ "_nodeVersion": "v0.7.7-pre",
"_defaultsLoaded": true,
- "_from": "fstream@~0.1.5"
+ "_from": "fstream@~0.1.17"
}
// there is such a thing as TOO graceful.
if (fs.open === gracefulOpen) return
-var FastList = require("fast-list")
- , queue = new FastList()
+var queue = []
, curOpen = 0
, constants = require("constants")
if (!er || (!process.getuid || process.getuid() !== 0)
&& (er.code === "EINVAL" || er.code === "EPERM")) return true
}
+
+
+
+// on Windows, A/V software can lock the directory, causing this
+// to fail with an EACCES or EPERM if the directory contains newly
+// created files. Try again on failure, for up to 1 second.
+if (process.platform === "win32") {
+ var rename_ = fs.rename
+ fs.rename = function rename (from, to, cb) {
+ var start = Date.now()
+ rename_(from, to, function CB (er) {
+ if (er
+ && (er.code === "EACCES" || er.code === "EPERM")
+ && Date.now() - start < 1000) {
+ return rename_(from, to, CB)
+ }
+ cb(er)
+ })
+ }
+}
{
- "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me"
+ },
"name": "graceful-fs",
"description": "fs monkey-patching to avoid EMFILE and other problems",
- "version": "1.1.5",
+ "version": "1.1.8",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-graceful-fs.git"
"engines": {
"node": ">=0.4.0"
},
- "dependencies": {
- "fast-list": "1"
+ "devDependencies": {},
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
},
- "devDependencies": {}
+ "_id": "graceful-fs@1.1.8",
+ "dependencies": {},
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.10",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "_from": "graceful-fs@~1.1.1"
}
-Copyright 2011 Isaac Z. Schlueter (the "Author")
-All rights reserved.
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
-General Public Obviousness License
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
-The Author asserts that this software and associated documentation
-files (the "Software"), while the Author's original creation, is
-nonetheless obvious, trivial, unpatentable, and implied by the
-context in which the software was created. If you sat down and
-thought about the problem for an hour or less, you'd probably
-come up with exactly this solution.
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
-Permission is granted to use this software in any way
-whatsoever, with the following restriction:
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-You may not release the Software under a more restrictive license
-than this one.
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-{ "name" : "inherits"
-, "description": "A tiny simple way to do classic inheritance in js"
-, "version" : "1.0.0"
-, "keywords" : ["inheritance", "class", "klass", "oop", "object-oriented"]
-, "main" : "./inherits.js"
-, "repository" : "https://github.com/isaacs/inherits"
-, "license": { "type": "GPOL", "url": "https://raw.github.com/isaacs/inherits/master/LICENSE" }
-, "author" : "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)" }
+{
+ "name": "inherits",
+ "description": "A tiny simple way to do classic inheritance in js",
+ "version": "1.0.0",
+ "keywords": [
+ "inheritance",
+ "class",
+ "klass",
+ "oop",
+ "object-oriented"
+ ],
+ "main": "./inherits.js",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/inherits.git"
+ },
+ "license": {
+ "type": "WTFPL2"
+ },
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "inherits@1.0.0",
+ "dependencies": {},
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_engineSupported": true,
+ "_npmVersion": "1.1.10",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "dist": {
+ "shasum": "12dbc03c9f7c203289234b214a7d05a311d71450"
+ },
+ "_from": "git://github.com/isaacs/inherits"
+}
`a/**b` will not. **Note that this is different from the way that `**` is
handled by ruby's `Dir` class.**
-If an escaped pattern has no matches, and the `null` flag is not set,
+If an escaped pattern has no matches, and the `nonull` flag is set,
then minimatch.match returns the pattern as-provided, rather than
interpreting the character escapes. For example,
`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`.
+`"*a?"`. This is akin to setting the `nullglob` option in bash, except
+that it does not resolve escaped pattern characters.
If brace expansion is not disabled, then it is performed before any
other interpretation of the glob pattern. Thus, a pattern like
### minimatch.match(list, pattern, options)
Match against the list of
-files, in the style of fnmatch or glob. If nothing is matched, then
-return the pattern (unless `{ null: true }` in the options.)
+files, in the style of fnmatch or glob. If nothing is matched, and
+options.nonull is set, then return a list containing the pattern itself.
```javascript
var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
### nonegate
Suppress the behavior of treating a leading `!` character as negation.
+
+### flipNegate
+
+Returns from negate expressions the same as if they were not negated.
+(Ie, true on a hit, false on a miss.)
var LRU = require("lru-cache")
, cache = minimatch.cache = new LRU(100)
, GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
- , pathSplit = process.platform === "win32" ? /\\|\// : "/"
var path = require("path")
// any single thing other than /
this.parseNegate()
// step 2: expand braces
- var set = this.braceExpand()
+ var set = this.globSet = this.braceExpand()
if (options.debug) console.error(this.pattern, set)
// These will be regexps, except in the case of "**", which is
// set to the GLOBSTAR object for globstar behavior,
// and will not contain any / characters
- set = set.map(function (s) {
+ set = this.globParts = set.map(function (s) {
return s.split(slashSplit)
})
if (options.debug) console.error(this.pattern, set)
- // step 4: if we have a defined root, then patterns starting with ""
- // get attached to that. If we have a defined cwd, then patterns
- // *not* starting with "" get attached to that.
- // Exception 1: on windows, a pattern like //\?/c:/ or c:/ will
- // not get anything prefixed to it.
- // Exception 2: If matchBase is set, and it's just a filename,
- // then don't prefix anything onto it, since it'll only match
- // files with that basename anyhow.
- set = set.map(function (p) {
- if (process.platform === "win32" &&
- ( (p[0] === "" && p[1] === "" && p[2] === "\\?") // unc
- || (typeof p[0] === "string" && p[0].match(/^[a-zA-Z]:$/)) )) {
- return p
- }
- if (options.matchBase && p.length === 1) return p
- // do prefixing.
- if (options.root && p[0] === "") {
- var r = options.root.split(pathSplit)
- if (r[r.length - 1] === "") r.pop()
- r = r.concat(p.slice(1))
- r.absolute = true
- return r
- }
- if (options.cwd && p[0] !== "") {
- return options.cwd.split(pathSplit).concat(p)
- }
- return p
- })
-
-
this.set = set
}
patternListStack.push({ type: plType
, start: i - 1
, reStart: re.length })
- re += stateChar === "!" ? "(?!" : "(?:"
+ // negation is (?:(?!js)[^/]*)
+ re += stateChar === "!" ? "(?:(?!" : "(?:"
stateChar = false
continue
hasMagic = true
re += ")"
plType = patternListStack.pop().type
+ // negation is (?:(?!js)[^/]*)
+ // The others are (?:<pattern>)<type>
switch (plType) {
+ case "!":
+ re += "[^/]*?)"
+ break
case "?":
case "+":
case "*": re += plType
- case "!": // already handled by the start
case "@": break // the default anyway
}
continue
var pattern = set[i]
var hit = this.matchOne(f, pattern, partial)
if (hit) {
+ if (options.flipNegate) return true
return !this.negate
}
}
// didn't get any hits. this is success if it's a negative
// pattern, failure otherwise.
+ if (options.flipNegate) return false
return this.negate
}
{
- "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me"
+ },
"name": "minimatch",
"description": "a glob matcher in javascript",
- "version": "0.1.5",
+ "version": "0.2.2",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/minimatch.git"
"lru-cache": "~1.0.5"
},
"devDependencies": {
- "tap": "~0.1.3"
+ "tap": ""
},
- "licenses" : [
+ "licenses": [
{
- "type" : "MIT",
- "url" : "http://github.com/isaacs/minimatch/raw/master/LICENSE"
+ "type": "MIT",
+ "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
}
- ]
+ ],
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "minimatch@0.2.2",
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "_from": "minimatch@0"
}
f = mode;
mode = 0777 & (~process.umask());
}
-
+
+ // secret passalong argument.
+ var made = arguments[3] || null;
+
var cb = f || function () {};
if (typeof mode === 'string') mode = parseInt(mode, 8);
p = path.resolve(p);
fs.mkdir(p, mode, function (er) {
- if (!er) return cb();
+ if (!er) {
+ made = made || p;
+ return cb(null, made);
+ }
switch (er.code) {
case 'ENOENT':
- mkdirP(path.dirname(p), mode, function (er) {
- if (er) cb(er);
- else mkdirP(p, mode, cb);
+ mkdirP(path.dirname(p), mode, function (er, made) {
+ if (er) cb(er, made);
+ else mkdirP(p, mode, cb, made);
});
break;
fs.stat(p, function (er2, stat) {
// if the stat fails, then that's super weird.
// let the original EEXIST be the failure reason.
- if (er2 || !stat.isDirectory()) cb(er)
- else cb();
+ if (er2 || !stat.isDirectory()) cb(er, made)
+ else cb(null, made);
});
break;
default:
- cb(er);
+ cb(er, made);
break;
}
});
if (mode === undefined) {
mode = 0777 & (~process.umask());
}
-
+
+ // secret passalong argument
+ var made = arguments[2] || null;
+
if (typeof mode === 'string') mode = parseInt(mode, 8);
p = path.resolve(p);
-
+
try {
- fs.mkdirSync(p, mode)
+ fs.mkdirSync(p, mode);
+ made = made || p;
}
catch (err0) {
switch (err0.code) {
case 'ENOENT' :
- var err1 = sync(path.dirname(p), mode)
- if (err1) throw err1;
- else return sync(p, mode);
+ made = sync(path.dirname(p), mode, made);
+ sync(p, mode, made);
break;
-
+
case 'EEXIST' :
var stat;
try {
stat = fs.statSync(p);
}
catch (err1) {
- throw err0
+ throw err0;
}
if (!stat.isDirectory()) throw err0;
- else return null;
break;
default :
throw err0
break;
}
}
-
- return null;
+
+ return made;
};
{
- "name" : "mkdirp",
- "description" : "Recursively mkdir, like `mkdir -p`",
- "version" : "0.3.0",
- "author" : "James Halliday <mail@substack.net> (http://substack.net)",
- "main" : "./index",
- "keywords" : [
- "mkdir",
- "directory"
- ],
- "repository" : {
- "type" : "git",
- "url" : "http://github.com/substack/node-mkdirp.git"
- },
- "scripts" : {
- "test" : "tap test/*.js"
- },
- "devDependencies" : {
- "tap" : "0.0.x"
- },
- "license" : "MIT/X11",
- "engines": { "node": "*" }
+ "name": "mkdirp",
+ "description": "Recursively mkdir, like `mkdir -p`",
+ "version": "0.3.0",
+ "author": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "main": "./index",
+ "keywords": [
+ "mkdir",
+ "directory"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/substack/node-mkdirp.git"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "devDependencies": {
+ "tap": "0.2"
+ },
+ "license": "MIT/X11",
+ "engines": {
+ "node": "*"
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "mkdirp@0.3.0",
+ "dependencies": {},
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.13",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "dist": {
+ "shasum": "a3cc6816e78b84f570caf9d95cb7368dc5d0bab8"
+ },
+ "_from": "../mkdirp"
}
``` json
{
- 'targets': [
+ "targets": [
{
- 'target_name': 'binding',
- 'sources': [ 'src/binding.cc' ]
+ "target_name": "binding",
+ "sources": [ "src/binding.cc" ]
}
]
}
* Module dependencies.
*/
-var gyp = require('../lib/node-gyp')
+var gyp = require('../')
, inspect = require('util').inspect
, ansi = require('ansi')
, cursor = ansi(process.stderr)
function loadConfigGypi () {
fs.readFile(configPath, 'utf8', function (err, data) {
- if (err) return callback(err)
+ if (err) {
+ if (err.code == 'ENOENT') {
+ callback(new Error('You must run `node-gyp configure` first!'))
+ } else {
+ callback(err)
+ }
+ return
+ }
config = JSON.parse(data.replace(/\#.+\n/, ''))
if (win) {
findSolutionFile()
function build () {
var buildType = config.target_defaults.default_configuration
- , platform = config.target_arch == 'x64' ? '64' : '32'
+ , platform = config.variables.target_arch == 'x64' ? '64' : '32'
if (gyp.opts.debug) {
buildType = 'Debug'
if (!version) {
return callback(new Error('Invalid version number: ' + versionStr))
}
- version = version.slice(1, 4).join('.')
gyp.opts.ensure = true
- gyp.commands.install([ version ], createBuildDir)
+ gyp.commands.install([ versionStr ], function (err, _version) {
+ if (err) return callback(err)
+ version = _version
+ gyp.verbose('setting target version to:', version)
+ createBuildDir()
+ })
}
- function createBuildDir (err) {
- if (err) return callback(err)
+ function createBuildDir () {
gyp.verbose('attempting to create "build" dir', buildDir)
mkdirp(buildDir, function (err, isNew) {
if (err) return callback(err)
callback(err)
})
} else {
- callback.apply(null, arguments)
+ callback(null, version)
}
}
if (version[5] === '-pre') {
version[3] = +version[3] - 1
version[5] = null
+ gyp.verbose('-pre version detected, adjusting patch version')
}
// flatten version into String
gyp.verbose('version not already installed, continuing with install', version)
go()
} else {
- callback(err)
+ cb(err)
}
return
}
var installVersionFile = path.resolve(devDir, 'installVersion')
fs.readFile(installVersionFile, 'ascii', function (err, ver) {
if (err && err.code != 'ENOENT') {
- return callback(err)
+ return cb(err)
}
var installVersion = parseInt(ver, 10) || 0
gyp.verbose('got "installVersion":', installVersion)
go()
} else {
gyp.verbose('version is good')
- callback()
+ cb()
}
})
})
go()
}
+ function download(url,onError) {
+ gyp.info('downloading:', url)
+ var requestOpts = {
+ uri: url
+ , onResponse: true
+ }
+
+ // basic support for a proxy server
+ var proxyUrl = gyp.opts.proxy
+ || process.env.http_proxy
+ || process.env.HTTP_PROXY
+ || process.env.npm_config_proxy
+ if (proxyUrl) {
+ gyp.verbose('using proxy:', proxyUrl)
+ requestOpts.proxy = proxyUrl
+ }
+ return request(requestOpts, onError)
+ }
function go () {
var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz'
, badDownload = false
, extractCount = 0
- , parser = tar.Parse()
-
- gyp.info('downloading:', tarballUrl)
-
- var requestOpts = { uri: tarballUrl }
- var proxyUrl = gyp.opts.proxy || process.env.http_proxy || process.env.HTTP_PROXY
- if (proxyUrl) {
- gyp.verbose('using proxy:', proxyUrl)
- requestOpts.proxy = proxyUrl
+ , gunzip = zlib.createGunzip()
+ , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid })
+
+ // checks if a file to be extracted from the tarball is valid.
+ // only .h header files and the gyp files get extracted
+ function isValid () {
+ var name = this.path.substring(devDir.length + 1)
+ , _valid = valid(name)
+ if (name === '' && this.type === 'Directory') {
+ // the first directory entry is ok
+ return true
+ }
+ if (_valid) {
+ gyp.verbose('extracted file from tarball', name)
+ extractCount++
+ } else {
+ // invalid
+ }
+ return _valid
}
- request(requestOpts, downloadError)
- .pipe(zlib.createGunzip())
- .pipe(parser)
- parser.on('entry', onEntry)
- parser.on('end', afterTarball)
+ gunzip.on('error', cb)
+ extracter.on('error', cb)
+ extracter.on('end', afterTarball)
+
+ // download the tarball, gunzip and extract!
+ var req = download(tarballUrl, downloadError)
+ .pipe(gunzip)
+ .pipe(extracter)
// something went wrong downloading the tarball?
function downloadError (err, res) {
}
}
- // handle a file from the tarball
- function onEntry (entry) {
- extractCount++
-
- var filename = entry.props.path
- , trimmed = install.trim(filename)
-
- if (!valid(trimmed)) {
- // skip
- return
- }
-
- var dir = path.dirname(trimmed)
- , devFileDir = path.resolve(devDir, dir)
- , devFile = path.resolve(devDir, trimmed)
-
- if (dir !== '.') {
- // TODO: async
- // TODO: keep track of the dirs that have been created/checked so far
- //console.error(devFileDir)
- mkdir.sync(devFileDir)
- }
- // TODO: better "File" detection or use `fstream`
- if (entry.props.type !== '0') {
- return
- }
- //console.error(trimmed, entry.props)
-
- // Finally save the file to the filesystem
- // TODO: Figure out why pipe() hangs here or use `fstream`
- var ws = fs.createWriteStream(devFile, {
- mode: entry.props.mode
- })
- entry.on('data', function (b) {
- ws.write(b)
- })
- entry.on('end', function () {
- ws.end()
- gyp.verbose('saved file', devFile)
- })
-
- }
-
+ // invoked after the tarball has finished being extracted
function afterTarball () {
if (badDownload) return
if (extractCount === 0) {
- return cb(new Error('There was a fatal problem while downloading the tarball'))
+ return cb(new Error('There was a fatal problem while downloading/extracting the tarball'))
}
gyp.verbose('done parsing tarball')
var async = 0
if (err) return done(err)
mkdir(debugDir, function (err) {
if (err) return done(err)
- gyp.info('downloading `node.lib`', nodeLibUrl)
// TODO: clean this mess up, written in a hastemode-9000
var badDownload = false
- var res = request(nodeLibUrl, function (err, res) {
+ var res = download(nodeLibUrl, function (err, res) {
if (err || res.statusCode != 200) {
badDownload = true
done(err || new Error(res.statusCode + ' status code downloading node.lib'))
function valid (file) {
// header files
- return minimatch(file, 'src/*.h')
- || minimatch(file, 'deps/**/*.h')
+ return minimatch(file, '*.h', { matchBase: true })
// non-legacy versions of node also extract the gyp build files
|| (!isLegacy &&
- (minimatch(file, '*.gypi')
- || minimatch(file, 'tools/*.gypi')
+ (minimatch(file, '*.gypi', { matchBase: true })
|| minimatch(file, 'tools/gyp_addon')
|| (minimatch(file, 'tools/gyp/**') && !minimatch(file, 'tools/gyp/test/**'))
)
var v = argv[0] || gyp.opts.target
if (!v) {
- return callback(new Error('You must specify a version number to remove. Ex: "0.6.12"'))
+ return callback(new Error('You must specify a version number to remove. Ex: "' + process.version + '"'))
}
// parse the version to normalize and make sure it's valid
"dependencies": {},
"optionalDependencies": {},
"_engineSupported": true,
- "_npmVersion": "1.1.8",
+ "_npmVersion": "1.1.13",
"_nodeVersion": "v0.7.7-pre",
"_defaultsLoaded": true,
"_from": "ansi@0.0.x"
--- /dev/null
+Copyright (c) Isaac Z. Schlueter
+All rights reserved.
+
+The BSD License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
, path = require("path")
, isDir = {}
, assert = require("assert").ok
+, EOF = {}
function glob (pattern, options, cb) {
if (typeof options === "function") cb = options, options = {}
this._process(pattern, 0, i, function (er) {
if (er) this.emit("error", er)
if (-- n <= 0) this._finish()
- }.bind(this))
+ })
}
}
if (this.debug) console.error("emitting end", all)
- this.found = all
- this.emit("end", all)
+ EOF = this.found = all
+ this.emitMatch(EOF)
}
function alphasorti (a, b) {
this.emit("abort")
}
+Glob.prototype.pause = function () {
+ if (this.paused) return
+ if (this.sync)
+ this.emit("error", new Error("Can't pause/resume sync glob"))
+ this.paused = true
+ this.emit("pause")
+}
+
+Glob.prototype.resume = function () {
+ if (!this.paused) return
+ if (this.sync)
+ this.emit("error", new Error("Can't pause/resume sync glob"))
+ this.paused = false
+ this.emit("resume")
+}
+
+
+Glob.prototype.emitMatch = function (m) {
+ if (!this.paused) {
+ this.emit(m === EOF ? "end" : "match", m)
+ return
+ }
+
+ if (!this._emitQueue) {
+ this._emitQueue = []
+ this.once("resume", function () {
+ var q = this._emitQueue
+ this._emitQueue = null
+ q.forEach(function (m) {
+ this.emitMatch(m)
+ }, this)
+ })
+ }
+
+ this._emitQueue.push(m)
+
+ //this.once("resume", this.emitMatch.bind(this, m))
+}
+
+
-Glob.prototype._process = function (pattern, depth, index, cb) {
+Glob.prototype._process = function (pattern, depth, index, cb_) {
assert(this instanceof Glob)
- cb = cb.bind(this)
+
+ var cb = function cb (er, res) {
+ assert(this instanceof Glob)
+ if (this.paused) {
+ if (!this._processQueue) {
+ this._processQueue = []
+ this.once("resume", function () {
+ var q = this._processQueue
+ this._processQueue = null
+ q.forEach(function (cb) { cb() })
+ })
+ }
+ this._processQueue.push(cb_.bind(this, er, res))
+ } else {
+ cb_.call(this, er, res)
+ }
+ }.bind(this)
+
if (this.aborted) return cb()
if (depth > this.maxDepth) return cb()
}
this.matches[index] = this.matches[index] || {}
this.matches[index][prefix] = true
- this.emit("match", prefix)
+ this.emitMatch(prefix)
}
return cb()
})
this.matches[index] = this.matches[index] || {}
this.matches[index][e] = true
- this.emit("match", e)
+ this.emitMatch(e)
}, this)
return cb.call(this)
}
if (errState) return
if (er) return cb(errState = er)
if (--l === 0) return cb.call(this)
- }.bind(this))
+ })
}, this)
})
}
Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
+ var exists
assert(this instanceof Glob)
if (er || !stat) {
exists = false
+++ /dev/null
-language: node_js
-node_js:
- - 0.4
- - 0.6
+++ /dev/null
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
+++ /dev/null
-# minimatch
-
-A minimal matching utility.
-
-[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
-
-
-This is the matching library used internally by npm.
-
-Eventually, it will replace the C binding in node-glob.
-
-It works by converting glob expressions into JavaScript `RegExp`
-objects.
-
-## Usage
-
-```javascript
-var minimatch = require("minimatch")
-
-minimatch("bar.foo", "*.foo") // true!
-minimatch("bar.foo", "*.bar") // false!
-```
-
-## Features
-
-Supports these glob features:
-
-* Brace Expansion
-* Extended glob matching
-* "Globstar" `**` matching
-
-See:
-
-* `man sh`
-* `man bash`
-* `man 3 fnmatch`
-* `man 5 gitignore`
-
-### Comparisons to other fnmatch/glob implementations
-
-While strict compliance with the existing standards is a worthwhile
-goal, some discrepancies exist between minimatch and other
-implementations, and are intentional.
-
-If the pattern starts with a `!` character, then it is negated. Set the
-`nonegate` flag to suppress this behavior, and treat leading `!`
-characters normally. This is perhaps relevant if you wish to start the
-pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
-characters at the start of a pattern will negate the pattern multiple
-times.
-
-If a pattern starts with `#`, then it is treated as a comment, and
-will not match anything. Use `\#` to match a literal `#` at the
-start of a line, or set the `nocomment` flag to suppress this behavior.
-
-The double-star character `**` is supported by default, unless the
-`noglobstar` flag is set. This is supported in the manner of bsdglob
-and bash 4.1, where `**` only has special significance if it is the only
-thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
-`a/**b` will not. **Note that this is different from the way that `**` is
-handled by ruby's `Dir` class.**
-
-If an escaped pattern has no matches, and the `null` flag is not set,
-then minimatch.match returns the pattern as-provided, rather than
-interpreting the character escapes. For example,
-`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`.
-
-If brace expansion is not disabled, then it is performed before any
-other interpretation of the glob pattern. Thus, a pattern like
-`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-checked for validity. Since those two are valid, matching proceeds.
-
-
-## Minimatch Class
-
-Create a minimatch object by instanting the `minimatch.Minimatch` class.
-
-```javascript
-var Minimatch = require("minimatch").Minimatch
-var mm = new Minimatch(pattern, options)
-```
-
-### Properties
-
-* `pattern` The original pattern the minimatch object represents.
-* `options` The options supplied to the constructor.
-* `set` A 2-dimensional array of regexp or string expressions.
- Each row in the
- array corresponds to a brace-expanded pattern. Each item in the row
- corresponds to a single path-part. For example, the pattern
- `{a,b/c}/d` would expand to a set of patterns like:
-
- [ [ a, d ]
- , [ b, c, d ] ]
-
- If a portion of the pattern doesn't have any "magic" in it
- (that is, it's something like `"foo"` rather than `fo*o?`), then it
- will be left as a string rather than converted to a regular
- expression.
-
-* `regexp` Created by the `makeRe` method. A single regular expression
- expressing the entire pattern. This is useful in cases where you wish
- to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
-* `negate` True if the pattern is negated.
-* `comment` True if the pattern is a comment.
-* `empty` True if the pattern is `""`.
-
-### Methods
-
-* `makeRe` Generate the `regexp` member if necessary, and return it.
- Will return `false` if the pattern is invalid.
-* `match(fname)` Return true if the filename matches the pattern, or
- false otherwise.
-* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
- filename, and match it against a single row in the `regExpSet`. This
- method is mainly for internal use, but is exposed so that it can be
- used by a glob-walker that needs to avoid excessive filesystem calls.
-
-All other methods are internal, and will be called as necessary.
-
-## Functions
-
-The top-level exported function has a `cache` property, which is an LRU
-cache set to store 100 items. So, calling these methods repeatedly
-with the same pattern and options will use the same Minimatch object,
-saving the cost of parsing it multiple times.
-
-### minimatch(path, pattern, options)
-
-Main export. Tests a path against the pattern using the options.
-
-```javascript
-var isJS = minimatch(file, "*.js", { matchBase: true })
-```
-
-### minimatch.filter(pattern, options)
-
-Returns a function that tests its
-supplied argument, suitable for use with `Array.filter`. Example:
-
-```javascript
-var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
-```
-
-### minimatch.match(list, pattern, options)
-
-Match against the list of
-files, in the style of fnmatch or glob. If nothing is matched, then
-return the pattern (unless `{ null: true }` in the options.)
-
-```javascript
-var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
-```
-
-### minimatch.makeRe(pattern, options)
-
-Make a regular expression object from the pattern.
-
-## Options
-
-All options are `false` by default.
-
-### debug
-
-Dump a ton of stuff to stderr.
-
-### nobrace
-
-Do not expand `{a,b}` and `{1..3}` brace sets.
-
-### noglobstar
-
-Disable `**` matching against multiple folder names.
-
-### dot
-
-Allow patterns to match filenames starting with a period, even if
-the pattern does not explicitly have a period in that spot.
-
-Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
-is set.
-
-### noext
-
-Disable "extglob" style patterns like `+(a|b)`.
-
-### nocase
-
-Perform a case-insensitive match.
-
-### nonull
-
-When a match is not found by `minimatch.match`, return a list containing
-the pattern itself. When set, an empty list is returned if there are
-no matches.
-
-### matchBase
-
-If set, then patterns without slashes will be matched
-against the basename of the path if it contains slashes. For example,
-`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
-
-### nocomment
-
-Suppress the behavior of treating `#` at the start of a pattern as a
-comment.
-
-### nonegate
-
-Suppress the behavior of treating a leading `!` character as negation.
+++ /dev/null
-module.exports = minimatch
-minimatch.Minimatch = Minimatch
-
-var LRU = require("lru-cache")
- , cache = minimatch.cache = new LRU(100)
- , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
- , pathSplit = process.platform === "win32" ? /\\|\// : "/"
-
-var path = require("path")
- // any single thing other than /
- // don't need to escape / when using new RegExp()
- , qmark = "[^/]"
-
- // * => any number of characters
- , star = qmark + "*?"
-
- // ** when dots are allowed. Anything goes, except .. and .
- // not (^ or / followed by one or two dots followed by $ or /),
- // followed by anything, any number of times.
- , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
-
- // not a ^ or / followed by a dot,
- // followed by anything, any number of times.
- , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
-
- // characters that need to be escaped in RegExp.
- , reSpecials = charSet("().*{}+?[]^$\\!")
-
-// "abc" -> { a:true, b:true, c:true }
-function charSet (s) {
- return s.split("").reduce(function (set, c) {
- set[c] = true
- return set
- }, {})
-}
-
-// normalizes slashes.
-var slashSplit = /\/+/
-
-minimatch.monkeyPatch = monkeyPatch
-function monkeyPatch () {
- var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
- var orig = desc.value
- desc.value = function (p) {
- if (p instanceof Minimatch) return p.match(this)
- return orig.call(this, p)
- }
- Object.defineProperty(String.prototype, desc)
-}
-
-minimatch.filter = filter
-function filter (pattern, options) {
- options = options || {}
- return function (p, i, list) {
- return minimatch(p, pattern, options)
- }
-}
-
-function minimatch (p, pattern, options) {
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
- }
-
- if (!options) options = {}
-
- // shortcut: comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
- return false
- }
-
- // "" only matches ""
- if (pattern.trim() === "") return p === ""
-
- return new Minimatch(pattern, options).match(p)
-}
-
-function Minimatch (pattern, options) {
- if (!(this instanceof Minimatch)) {
- return new Minimatch(pattern, options, cache)
- }
-
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
- }
-
- if (!options) options = {}
- pattern = pattern.trim()
-
- // lru storage.
- // these things aren't particularly big, but walking down the string
- // and turning it into a regexp can get pretty costly.
- var cacheKey = pattern + "\n" + Object.keys(options).filter(function (k) {
- return options[k]
- }).join(":")
- var cached = minimatch.cache.get(cacheKey)
- if (cached) return cached
- minimatch.cache.set(cacheKey, this)
-
- this.options = options
- this.set = []
- this.pattern = pattern
- this.regexp = null
- this.negate = false
- this.comment = false
- this.empty = false
-
- // make the set of regexps etc.
- this.make()
-}
-
-Minimatch.prototype.make = make
-function make () {
- // don't do it more than once.
- if (this._made) return
-
- var pattern = this.pattern
- var options = this.options
-
- // empty patterns and comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
- this.comment = true
- return
- }
- if (!pattern) {
- this.empty = true
- return
- }
-
- // step 1: figure out negation, etc.
- this.parseNegate()
-
- // step 2: expand braces
- var set = this.globSet = this.braceExpand()
-
- if (options.debug) console.error(this.pattern, set)
-
- // step 3: now we have a set, so turn each one into a series of path-portion
- // matching patterns.
- // These will be regexps, except in the case of "**", which is
- // set to the GLOBSTAR object for globstar behavior,
- // and will not contain any / characters
- set = this.globParts = set.map(function (s) {
- return s.split(slashSplit)
- })
-
- if (options.debug) console.error(this.pattern, set)
-
- // glob --> regexps
- set = set.map(function (s, si, set) {
- return s.map(this.parse, this)
- }, this)
-
- if (options.debug) console.error(this.pattern, set)
-
- // filter out everything that didn't compile properly.
- set = set.filter(function (s) {
- return -1 === s.indexOf(false)
- })
-
- if (options.debug) console.error(this.pattern, set)
-
- this.set = set
-}
-
-Minimatch.prototype.parseNegate = parseNegate
-function parseNegate () {
- var pattern = this.pattern
- , negate = false
- , options = this.options
- , negateOffset = 0
-
- if (options.nonegate) return
-
- for ( var i = 0, l = pattern.length
- ; i < l && pattern.charAt(i) === "!"
- ; i ++) {
- negate = !negate
- negateOffset ++
- }
-
- if (negateOffset) this.pattern = pattern.substr(negateOffset)
- this.negate = negate
-}
-
-// Brace expansion:
-// a{b,c}d -> abd acd
-// a{b,}c -> abc ac
-// a{0..3}d -> a0d a1d a2d a3d
-// a{b,c{d,e}f}g -> abg acdfg acefg
-// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
-//
-// Invalid sets are not expanded.
-// a{2..}b -> a{2..}b
-// a{b}c -> a{b}c
-minimatch.braceExpand = function (pattern, options) {
- return new Minimatch(pattern, options).braceExpand()
-}
-
-Minimatch.prototype.braceExpand = braceExpand
-function braceExpand (pattern, options) {
- options = options || this.options
- pattern = typeof pattern === "undefined"
- ? this.pattern : pattern
-
- if (typeof pattern === "undefined") {
- throw new Error("undefined pattern")
- }
-
- if (options.nobrace ||
- !pattern.match(/\{.*\}/)) {
- // shortcut. no need to expand.
- return [pattern]
- }
-
- var escaping = false
-
- // examples and comments refer to this crazy pattern:
- // a{b,c{d,e},{f,g}h}x{y,z}
- // expected:
- // abxy
- // abxz
- // acdxy
- // acdxz
- // acexy
- // acexz
- // afhxy
- // afhxz
- // aghxy
- // aghxz
-
- // everything before the first \{ is just a prefix.
- // So, we pluck that off, and work with the rest,
- // and then prepend it to everything we find.
- if (pattern.charAt(0) !== "{") {
- // console.error(pattern)
- var prefix = null
- for (var i = 0, l = pattern.length; i < l; i ++) {
- var c = pattern.charAt(i)
- // console.error(i, c)
- if (c === "\\") {
- escaping = !escaping
- } else if (c === "{" && !escaping) {
- prefix = pattern.substr(0, i)
- break
- }
- }
-
- // actually no sets, all { were escaped.
- if (prefix === null) {
- // console.error("no sets")
- return [pattern]
- }
-
- var tail = braceExpand(pattern.substr(i), options)
- return tail.map(function (t) {
- return prefix + t
- })
- }
-
- // now we have something like:
- // {b,c{d,e},{f,g}h}x{y,z}
- // walk through the set, expanding each part, until
- // the set ends. then, we'll expand the suffix.
- // If the set only has a single member, then'll put the {} back
-
- // first, handle numeric sets, since they're easier
- var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
- if (numset) {
- // console.error("numset", numset[1], numset[2])
- var suf = braceExpand(pattern.substr(numset[0].length), options)
- , start = +numset[1]
- , end = +numset[2]
- , inc = start > end ? -1 : 1
- , set = []
- for (var i = start; i != (end + inc); i += inc) {
- // append all the suffixes
- for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
- set.push(i + suf[ii])
- }
- }
- return set
- }
-
- // ok, walk through the set
- // We hope, somewhat optimistically, that there
- // will be a } at the end.
- // If the closing brace isn't found, then the pattern is
- // interpreted as braceExpand("\\" + pattern) so that
- // the leading \{ will be interpreted literally.
- var i = 1 // skip the \{
- , depth = 1
- , set = []
- , member = ""
- , sawEnd = false
- , escaping = false
-
- function addMember () {
- set.push(member)
- member = ""
- }
-
- // console.error("Entering for")
- FOR: for (i = 1, l = pattern.length; i < l; i ++) {
- var c = pattern.charAt(i)
- // console.error("", i, c)
-
- if (escaping) {
- escaping = false
- member += "\\" + c
- } else {
- switch (c) {
- case "\\":
- escaping = true
- continue
-
- case "{":
- depth ++
- member += "{"
- continue
-
- case "}":
- depth --
- // if this closes the actual set, then we're done
- if (depth === 0) {
- addMember()
- // pluck off the close-brace
- i ++
- break FOR
- } else {
- member += c
- continue
- }
-
- case ",":
- if (depth === 1) {
- addMember()
- } else {
- member += c
- }
- continue
-
- default:
- member += c
- continue
- } // switch
- } // else
- } // for
-
- // now we've either finished the set, and the suffix is
- // pattern.substr(i), or we have *not* closed the set,
- // and need to escape the leading brace
- if (depth !== 0) {
- // console.error("didn't close", pattern)
- return braceExpand("\\" + pattern, options)
- }
-
- // x{y,z} -> ["xy", "xz"]
- // console.error("set", set)
- // console.error("suffix", pattern.substr(i))
- var suf = braceExpand(pattern.substr(i), options)
- // ["b", "c{d,e}","{f,g}h"] ->
- // [["b"], ["cd", "ce"], ["fh", "gh"]]
- var addBraces = set.length === 1
- // console.error("set pre-expanded", set)
- set = set.map(function (p) {
- return braceExpand(p, options)
- })
- // console.error("set expanded", set)
-
-
- // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
- // ["b", "cd", "ce", "fh", "gh"]
- set = set.reduce(function (l, r) {
- return l.concat(r)
- })
-
- if (addBraces) {
- set = set.map(function (s) {
- return "{" + s + "}"
- })
- }
-
- // now attach the suffixes.
- var ret = []
- for (var i = 0, l = set.length; i < l; i ++) {
- for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
- ret.push(set[i] + suf[ii])
- }
- }
- return ret
-}
-
-// parse a component of the expanded set.
-// At this point, no pattern may contain "/" in it
-// so we're going to return a 2d array, where each entry is the full
-// pattern, split on '/', and then turned into a regular expression.
-// A regexp is made at the end which joins each array with an
-// escaped /, and another full one which joins each regexp with |.
-//
-// Following the lead of Bash 4.1, note that "**" only has special meaning
-// when it is the *only* thing in a path portion. Otherwise, any series
-// of * is equivalent to a single *. Globstar behavior is enabled by
-// default, and can be disabled by setting options.noglobstar.
-Minimatch.prototype.parse = parse
-var SUBPARSE = {}
-function parse (pattern, isSub) {
- var options = this.options
-
- // shortcuts
- if (!options.noglobstar && pattern === "**") return GLOBSTAR
- if (pattern === "") return ""
-
- var re = ""
- , hasMagic = false
- , escaping = false
- // ? => one single character
- , patternListStack = []
- , plType
- , stateChar
- , inClass = false
- , reClassStart = -1
- , classStart = -1
- // . and .. never match anything that doesn't start with .,
- // even when options.dot is set.
- , patternStart = pattern.charAt(0) === "." ? "" // anything
- // not (start or / followed by . or .. followed by / or end)
- : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
- : "(?!\\.)"
-
- function clearStateChar () {
- if (stateChar) {
- // we had some state-tracking character
- // that wasn't consumed by this pass.
- switch (stateChar) {
- case "*":
- re += star
- hasMagic = true
- break
- case "?":
- re += qmark
- hasMagic = true
- break
- default:
- re += "\\"+stateChar
- break
- }
- stateChar = false
- }
- }
-
- for ( var i = 0, len = pattern.length, c
- ; (i < len) && (c = pattern.charAt(i))
- ; i ++ ) {
-
- if (options.debug) {
- console.error("%s\t%s %s %j", pattern, i, re, c)
- }
-
- // skip over any that are escaped.
- if (escaping && reSpecials[c]) {
- re += "\\" + c
- escaping = false
- continue
- }
-
- SWITCH: switch (c) {
- case "/":
- // completely not allowed, even escaped.
- // Should already be path-split by now.
- return false
-
- case "\\":
- clearStateChar()
- escaping = true
- continue
-
- // the various stateChar values
- // for the "extglob" stuff.
- case "?":
- case "*":
- case "+":
- case "@":
- case "!":
- if (options.debug) {
- console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
- }
-
- // all of those are literals inside a class, except that
- // the glob [!a] means [^a] in regexp
- if (inClass) {
- if (c === "!" && i === classStart + 1) c = "^"
- re += c
- continue
- }
-
- // if we already have a stateChar, then it means
- // that there was something like ** or +? in there.
- // Handle the stateChar, then proceed with this one.
- clearStateChar()
- stateChar = c
- // if extglob is disabled, then +(asdf|foo) isn't a thing.
- // just clear the statechar *now*, rather than even diving into
- // the patternList stuff.
- if (options.noext) clearStateChar()
- continue
-
- case "(":
- if (inClass) {
- re += "("
- continue
- }
-
- if (!stateChar) {
- re += "\\("
- continue
- }
-
- plType = stateChar
- patternListStack.push({ type: plType
- , start: i - 1
- , reStart: re.length })
- re += stateChar === "!" ? "(?!" : "(?:"
- stateChar = false
- continue
-
- case ")":
- if (inClass || !patternListStack.length) {
- re += "\\)"
- continue
- }
-
- hasMagic = true
- re += ")"
- plType = patternListStack.pop().type
- switch (plType) {
- case "?":
- case "+":
- case "*": re += plType
- case "!": // already handled by the start
- case "@": break // the default anyway
- }
- continue
-
- case "|":
- if (inClass || !patternListStack.length || escaping) {
- re += "\\|"
- escaping = false
- continue
- }
-
- re += "|"
- continue
-
- // these are mostly the same in regexp and glob
- case "[":
- // swallow any state-tracking char before the [
- clearStateChar()
-
- if (inClass) {
- re += "\\" + c
- continue
- }
-
- inClass = true
- classStart = i
- reClassStart = re.length
- re += c
- continue
-
- case "]":
- // a right bracket shall lose its special
- // meaning and represent itself in
- // a bracket expression if it occurs
- // first in the list. -- POSIX.2 2.8.3.2
- if (i === classStart + 1 || !inClass) {
- re += "\\" + c
- escaping = false
- continue
- }
-
- // finish up the class.
- hasMagic = true
- inClass = false
- re += c
- continue
-
- default:
- // swallow any state char that wasn't consumed
- clearStateChar()
-
- if (escaping) {
- // no need
- escaping = false
- } else if (reSpecials[c]
- && !(c === "^" && inClass)) {
- re += "\\"
- }
-
- re += c
-
- } // switch
- } // for
-
-
- // handle the case where we left a class open.
- // "[abc" is valid, equivalent to "\[abc"
- if (inClass) {
- // split where the last [ was, and escape it
- // this is a huge pita. We now have to re-walk
- // the contents of the would-be class to re-translate
- // any characters that were passed through as-is
- var cs = pattern.substr(classStart + 1)
- , sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0]
- hasMagic = hasMagic || sp[1]
- }
-
- // handle the case where we had a +( thing at the *end*
- // of the pattern.
- // each pattern list stack adds 3 chars, and we need to go through
- // and escape any | chars that were passed through as-is for the regexp.
- // Go through and escape them, taking care not to double-escape any
- // | chars that were already escaped.
- var pl
- while (pl = patternListStack.pop()) {
- var tail = re.slice(pl.reStart + 3)
- // maybe some even number of \, then maybe 1 \, followed by a |
- tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
- if (!$2) {
- // the | isn't already escaped, so escape it.
- $2 = "\\"
- }
-
- // need to escape all those slashes *again*, without escaping the
- // one that we need for escaping the | character. As it works out,
- // escaping an even number of slashes can be done by simply repeating
- // it exactly after itself. That's why this trick works.
- //
- // I am sorry that you have to see this.
- return $1 + $1 + $2 + "|"
- })
-
- // console.error("tail=%j\n %s", tail, tail)
- var t = pl.type === "*" ? star
- : pl.type === "?" ? qmark
- : "\\" + pl.type
-
- hasMagic = true
- re = re.slice(0, pl.reStart)
- + t + "\\("
- + tail
- }
-
- // handle trailing things that only matter at the very end.
- clearStateChar()
- if (escaping) {
- // trailing \\
- re += "\\\\"
- }
-
- // only need to apply the nodot start if the re starts with
- // something that could conceivably capture a dot
- var addPatternStart = false
- switch (re.charAt(0)) {
- case ".":
- case "[":
- case "(": addPatternStart = true
- }
-
- // if the re is not "" at this point, then we need to make sure
- // it doesn't match against an empty path part.
- // Otherwise a/* will match a/, which it should not.
- if (re !== "" && hasMagic) re = "(?=.)" + re
-
- if (addPatternStart) re = patternStart + re
-
- // parsing just a piece of a larger pattern.
- if (isSub === SUBPARSE) {
- return [ re, hasMagic ]
- }
-
- // skip the regexp for non-magical patterns
- // unescape anything in it, though, so that it'll be
- // an exact match against a file etc.
- if (!hasMagic) {
- return globUnescape(pattern)
- }
-
- var flags = options.nocase ? "i" : ""
- , regExp = new RegExp("^" + re + "$", flags)
-
- regExp._glob = pattern
- regExp._src = re
-
- return regExp
-}
-
-minimatch.makeRe = function (pattern, options) {
- return new Minimatch(pattern, options || {}).makeRe()
-}
-
-Minimatch.prototype.makeRe = makeRe
-function makeRe () {
- if (this.regexp || this.regexp === false) return this.regexp
-
- // at this point, this.set is a 2d array of partial
- // pattern strings, or "**".
- //
- // It's better to use .match(). This function shouldn't
- // be used, really, but it's pretty convenient sometimes,
- // when you just want to work with a regex.
- var set = this.set
-
- if (!set.length) return this.regexp = false
- var options = this.options
-
- var twoStar = options.noglobstar ? star
- : options.dot ? twoStarDot
- : twoStarNoDot
- , flags = options.nocase ? "i" : ""
-
- var re = set.map(function (pattern) {
- return pattern.map(function (p) {
- return (p === GLOBSTAR) ? twoStar
- : (typeof p === "string") ? regExpEscape(p)
- : p._src
- }).join("\\\/")
- }).join("|")
-
- // must match entire pattern
- // ending in a * or ** will make it less strict.
- re = "^" + re + "$"
-
- // can match anything, as long as it's not this.
- if (this.negate) re = "^(?!" + re + ").*$"
-
- try {
- return this.regexp = new RegExp(re, flags)
- } catch (ex) {
- return this.regexp = false
- }
-}
-
-minimatch.match = function (list, pattern, options) {
- var mm = new Minimatch(pattern, options)
- list = list.filter(function (f) {
- return mm.match(f)
- })
- if (options.nonull && !list.length) {
- list.push(pattern)
- }
- return list
-}
-
-Minimatch.prototype.match = match
-function match (f, partial) {
- // console.error("match", f, this.pattern)
- // short-circuit in the case of busted things.
- // comments, etc.
- if (this.comment) return false
- if (this.empty) return f === ""
-
- if (f === "/" && partial) return true
-
- var options = this.options
-
- // first, normalize any slash-separated path parts.
- // f = path.normalize(f)
-
- // windows: need to use /, not \
- // On other platforms, \ is a valid (albeit bad) filename char.
- if (process.platform === "win32") {
- f = f.split("\\").join("/")
- }
-
- // treat the test path as a set of pathparts.
- f = f.split(slashSplit)
- if (options.debug) {
- console.error(this.pattern, "split", f)
- }
-
- // just ONE of the pattern sets in this.set needs to match
- // in order for it to be valid. If negating, then just one
- // match means that we have failed.
- // Either way, return on the first hit.
-
- var set = this.set
- // console.error(this.pattern, "set", set)
-
- for (var i = 0, l = set.length; i < l; i ++) {
- var pattern = set[i]
- var hit = this.matchOne(f, pattern, partial)
- if (hit) {
- return !this.negate
- }
- }
-
- // didn't get any hits. this is success if it's a negative
- // pattern, failure otherwise.
- return this.negate
-}
-
-// set partial to true to test if, for example,
-// "/a/b" matches the start of "/*/b/*/d"
-// Partial means, if you run out of file before you run
-// out of pattern, then that's fine, as long as all
-// the parts match.
-Minimatch.prototype.matchOne = function (file, pattern, partial) {
- var options = this.options
-
- if (options.debug) {
- console.error("matchOne",
- { "this": this
- , file: file
- , pattern: pattern })
- }
-
- if (options.matchBase && pattern.length === 1) {
- file = path.basename(file.join("/")).split("/")
- }
-
- if (options.debug) {
- console.error("matchOne", file.length, pattern.length)
- }
-
- for ( var fi = 0
- , pi = 0
- , fl = file.length
- , pl = pattern.length
- ; (fi < fl) && (pi < pl)
- ; fi ++, pi ++ ) {
-
- if (options.debug) {
- console.error("matchOne loop")
- }
- var p = pattern[pi]
- , f = file[fi]
-
- if (options.debug) {
- console.error(pattern, p, f)
- }
-
- // should be impossible.
- // some invalid regexp stuff in the set.
- if (p === false) return false
-
- if (p === GLOBSTAR) {
- // "**"
- // a/**/b/**/c would match the following:
- // a/b/x/y/z/c
- // a/x/y/z/b/c
- // a/b/x/b/x/c
- // a/b/c
- // To do this, take the rest of the pattern after
- // the **, and see if it would match the file remainder.
- // If so, return success.
- // If not, the ** "swallows" a segment, and try again.
- // This is recursively awful.
- // a/b/x/y/z/c
- // - a matches a
- // - doublestar
- // - matchOne(b/x/y/z/c, b/**/c)
- // - b matches b
- // - doublestar
- // - matchOne(x/y/z/c, c) -> no
- // - matchOne(y/z/c, c) -> no
- // - matchOne(z/c, c) -> no
- // - matchOne(c, c) yes, hit
- var fr = fi
- , pr = pi + 1
- if (pr === pl) {
- // a ** at the end will just swallow the rest.
- // We have found a match.
- // however, it will not swallow /.x, unless
- // options.dot is set.
- // . and .. are *never* matched by **, for explosively
- // exponential reasons.
- for ( ; fi < fl; fi ++) {
- if (file[fi] === "." || file[fi] === ".." ||
- (!options.dot && file[fi].charAt(0) === ".")) return false
- }
- return true
- }
-
- // ok, let's see if we can swallow whatever we can.
- WHILE: while (fr < fl) {
- var swallowee = file[fr]
- if (swallowee === "." || swallowee === ".." ||
- (!options.dot && swallowee.charAt(0) === ".")) {
- // console.error("dot detected!")
- break WHILE
- }
-
- // XXX remove this slice. Just pass the start index.
- if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
- // found a match.
- return true
- } else {
- // ** swallows a segment, and continue.
- fr ++
- }
- }
- // no match was found.
- // However, in partial mode, we can't say this is necessarily over.
- // If there's more *pattern* left, then
- if (partial) {
- // ran out of file
- // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
- if (fr === fl) return true
- }
- return false
- }
-
- // something other than **
- // non-magic patterns just have to match exactly
- // patterns with magic have been turned into regexps.
- var hit
- if (typeof p === "string") {
- if (options.nocase) {
- hit = f.toLowerCase() === p.toLowerCase()
- } else {
- hit = f === p
- }
- if (options.debug) {
- console.error("string match", p, f, hit)
- }
- } else {
- hit = f.match(p)
- if (options.debug) {
- console.error("pattern match", p, f, hit)
- }
- }
-
- if (!hit) return false
- }
-
- // Note: ending in / means that we'll get a final ""
- // at the end of the pattern. This can only match a
- // corresponding "" at the end of the file.
- // If the file ends in /, then it can only match a
- // a pattern that ends in /, unless the pattern just
- // doesn't have any more for it. But, a/b/ should *not*
- // match "a/b/*", even though "" matches against the
- // [^/]*? pattern, except in partial mode, where it might
- // simply not be reached yet.
- // However, a/b/ should still satisfy a/*
-
- // now either we fell off the end of the pattern, or we're done.
- if (fi === fl && pi === pl) {
- // ran out of pattern and filename at the same time.
- // an exact hit!
- return true
- } else if (fi === fl) {
- // ran out of file, but still had pattern left.
- // this is ok if we're doing the match as part of
- // a glob fs traversal.
- return partial
- } else if (pi === pl) {
- // ran out of pattern, still have file left.
- // this is only acceptable if we're on the very last
- // empty segment of a file with a trailing slash.
- // a/* should match a/b/
- var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
- return emptyFileEnd
- }
-
- // should be unreachable.
- throw new Error("wtf?")
-}
-
-
-// replace stuff like \* with *
-function globUnescape (s) {
- return s.replace(/\\(.)/g, "$1")
-}
-
-
-function regExpEscape (s) {
- return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
-}
+++ /dev/null
-{
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me"
- },
- "name": "minimatch",
- "description": "a glob matcher in javascript",
- "version": "0.2.0",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/minimatch.git"
- },
- "main": "minimatch.js",
- "scripts": {
- "test": "tap test"
- },
- "engines": {
- "node": "*"
- },
- "dependencies": {
- "lru-cache": "~1.0.5"
- },
- "devDependencies": {
- "tap": "~0.1.3"
- },
- "licenses": [
- {
- "type": "MIT",
- "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
- }
- ],
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "_id": "minimatch@0.2.0",
- "optionalDependencies": {},
- "_engineSupported": true,
- "_npmVersion": "1.1.8",
- "_nodeVersion": "v0.7.7-pre",
- "_defaultsLoaded": true,
- "_from": "minimatch@0.2"
-}
},
"name": "glob",
"description": "a little globber",
- "version": "3.1.6",
+ "version": "3.1.9",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-glob.git"
"scripts": {
"test": "tap test/*.js"
},
+ "license": "BSD",
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
- "_id": "glob@3.1.6",
+ "_id": "glob@3.1.9",
"optionalDependencies": {},
"_engineSupported": true,
- "_npmVersion": "1.1.8",
+ "_npmVersion": "1.1.13",
"_nodeVersion": "v0.7.7-pre",
"_defaultsLoaded": true,
"_from": "glob@3"
"bindings",
"gyp"
],
- "version": "0.3.5",
+ "version": "0.3.9",
"installVersion": 5,
"author": {
"name": "Nathan Rajlich",
"dependencies": {
"ansi": "0.0.x",
"glob": "3",
+ "graceful-fs": "1",
"fstream": "~0.1.13",
- "minimatch": "~0.1.4",
+ "minimatch": "0.2.x",
"mkdirp": "0.3.0",
"nopt": "1",
"request": "2.9.x",
"name": "isaacs",
"email": "i@izs.me"
},
- "_id": "node-gyp@0.3.5",
+ "_id": "node-gyp@0.3.9",
"devDependencies": {},
"optionalDependencies": {},
"_engineSupported": true,
- "_npmVersion": "1.1.8",
+ "_npmVersion": "1.1.13",
"_nodeVersion": "v0.7.7-pre",
"_defaultsLoaded": true,
- "_from": "node-gyp@~0.3.4"
+ "dist": {
+ "shasum": "78c01d4b662c55607e7220b8c8e2a1f25390474a"
+ },
+ "_from": "node-gyp@~0.3.7"
}
--- /dev/null
+Use this module to convert a username/groupname to a uid/gid number.
+
+Usage:
+
+```
+npm install uid-number
+```
+
+Then, in your node program:
+
+```javascript
+var uidNumber = require("uid-number")
+uidNumber("isaacs", function (er, uid, gid) {
+ // gid is null because we didn't ask for a group name
+ // uid === 24561 because that's my number.
+})
+```
+if (module !== require.main) {
+ throw new Error("This file should not be loaded with require()")
+}
+
+if (!process.getuid || !process.getgid) {
+ throw new Error("this file should not be called without uid/gid support")
+}
+
var argv = process.argv.slice(2)
, user = argv[0] || process.getuid()
, group = argv[1] || process.getgid()
--- /dev/null
+{
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "name": "uid-number",
+ "description": "Convert a username/group name to a uid/gid number",
+ "version": "0.0.3",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/uid-number.git"
+ },
+ "main": "uid-number.js",
+ "dependencies": {},
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_id": "uid-number@0.0.3",
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.7.7-pre",
+ "_defaultsLoaded": true,
+ "dist": {
+ "shasum": "be40aeab1db6ba45d2344d4ed6015109fc9d98d4"
+ },
+ "_from": "uid-number@0.0.3"
+}
--- /dev/null
+module.exports = uidNumber
+
+// This module calls into get-uid-gid.js, which sets the
+// uid and gid to the supplied argument, in order to find out their
+// numeric value. This can't be done in the main node process,
+// because otherwise node would be running as that user from this
+// point on.
+
+var child_process = require("child_process")
+ , path = require("path")
+ , uidSupport = process.getuid && process.setuid
+ , uidCache = {}
+ , gidCache = {}
+
+function uidNumber (uid, gid, cb) {
+ if (!uidSupport) return cb()
+ if (typeof cb !== "function") cb = gid, gid = null
+ if (typeof cb !== "function") cb = uid, uid = null
+ if (gid == null) gid = process.getgid()
+ if (uid == null) uid = process.getuid()
+ if (!isNaN(gid)) gid = uidCache[gid] = +gid
+ if (!isNaN(uid)) uid = uidCache[uid] = +uid
+
+ if (uidCache.hasOwnProperty(uid)) uid = uidCache[uid]
+ if (gidCache.hasOwnProperty(gid)) gid = gidCache[gid]
+
+ if (typeof gid === "number" && typeof uid === "number") {
+ return process.nextTick(cb.bind(null, null, uid, gid))
+ }
+
+ var getter = require.resolve("./get-uid-gid.js")
+
+ child_process.execFile( process.execPath
+ , [getter, uid, gid]
+ , function (code, out, err) {
+ if (er) return cb(new Error("could not get uid/gid\n" + err))
+ try {
+ out = JSON.parse(out+"")
+ } catch (ex) {
+ return cb(ex)
+ }
+
+ if (out.error) {
+ var er = new Error(out.error)
+ er.errno = out.errno
+ return cb(er)
+ }
+
+ if (isNaN(out.uid) || isNaN(out.gid)) return cb(new Error(
+ "Could not get uid/gid: "+JSON.stringify(out)))
+
+ cb(null, uidCache[uid] = +out.uid, uidCache[gid] = +out.gid)
+ })
+}
"install",
"package.json"
],
- "version": "1.1.10",
+ "version": "1.1.14",
"preferGlobal": true,
"config": {
"publishtest": false
"slide": "1",
"abbrev": "1",
"graceful-fs": "~1.1.1",
- "minimatch": "0",
+ "minimatch": "~0.2",
"nopt": "1",
"node-uuid": "~1.3",
"proto-list": "1",
"request": "~2.9",
"which": "1",
"tar": "~0.1.12",
- "fstream": "~0.1.13",
+ "fstream": "~0.1.17",
"block-stream": "*",
"inherits": "1",
"mkdirp": "0.3",
- "fast-list": "~1.0.1",
"read": "0",
"lru-cache": "1",
- "node-gyp": "~0.3.4"
+ "node-gyp": "~0.3.7",
+ "fstream-npm": "0 >=0.0.4",
+ "uid-number": "0",
+ "archy": "0",
+ "chownr": "0"
},
"bundleDependencies": [
"slide",
"fast-list",
"read",
"lru-cache",
- "node-gyp"
+ "node-gyp",
+ "fstream-npm",
+ "uid-number",
+ "archy",
+ "chownr"
],
"devDependencies": {
"ronn": "https://github.com/isaacs/ronnjs/tarball/master"