+++ /dev/null
-[submodule "node_modules/semver"]
- path = node_modules/semver
- url = https://github.com/isaacs/node-semver.git
-[submodule "node_modules/abbrev"]
- path = node_modules/abbrev
- url = https://github.com/isaacs/abbrev-js.git
-[submodule "node_modules/nopt"]
- path = node_modules/nopt
- url = https://github.com/isaacs/nopt.git
-[submodule "node_modules/node-uuid"]
- path = node_modules/node-uuid
- url = https://github.com/broofa/node-uuid
-[submodule "node_modules/minimatch"]
- path = node_modules/minimatch
- url = https://github.com/isaacs/minimatch.git
-[submodule "node_modules/graceful-fs"]
- path = node_modules/graceful-fs
- url = https://github.com/isaacs/node-graceful-fs.git
-[submodule "node_modules/slide"]
- path = node_modules/slide
- url = https://github.com/isaacs/slide-flow-control.git
-[submodule "node_modules/rimraf"]
- path = node_modules/rimraf
- url = https://github.com/isaacs/rimraf.git
-[submodule "node_modules/proto-list"]
- path = node_modules/proto-list
- url = https://github.com/isaacs/proto-list.git
-[submodule "node_modules/ini"]
- path = node_modules/ini
- url = https://github.com/isaacs/ini.git
-[submodule "node_modules/which"]
- path = node_modules/which
- url = https://github.com/isaacs/node-which.git
-[submodule "node_modules/request"]
- path = node_modules/request
- url = https://github.com/mikeal/request.git
-[submodule "node_modules/tar"]
- path = node_modules/tar
- url = https://github.com/isaacs/node-tar.git
-[submodule "node_modules/fstream"]
- path = node_modules/fstream
- url = https://github.com/isaacs/fstream.git
-[submodule "node_modules/inherits"]
- path = node_modules/inherits
- url = https://github.com/isaacs/inherits.git
-[submodule "node_modules/block-stream"]
- path = node_modules/block-stream
- url = https://github.com/isaacs/block-stream.git
-[submodule "node_modules/mkdirp"]
- path = node_modules/mkdirp
- url = https://github.com/isaacs/node-mkdirp.git
-[submodule "node_modules/fast-list"]
- path = node_modules/fast-list
- url = https://github.com/isaacs/fast-list.git
-[submodule "node_modules/read"]
- path = node_modules/read
- url = https://github.com/isaacs/read.git
-[submodule "node_modules/lru-cache"]
- path = node_modules/lru-cache
- url = https://github.com/isaacs/node-lru-cache.git
npm-debug.log
./npmrc
.gitignore
+release/
cspotcode <cspotcode@gmail.com>
Maciej Małecki <maciej.malecki@notimplemented.org>
Stephen Sugden <glurgle@gmail.com>
+Gautham Pai <buzypi@gmail.com>
+David Trejo <david.daniel.trejo@gmail.com>
+Paul Vorbach <paul@vorb.de>
htmldocs = $(api_htmldocs) $(cli_htmldocs)
-all: submodules doc
+all: doc
-submodules:
- ! [ -d .git ] || git submodule update --init --recursive
-
-latest: submodules
+latest:
@echo "Installing latest published npm"
@echo "Use 'make install' or 'make link' to install the code"
@echo "in this folder that you're looking at right now."
rm npmrc
node cli.js cache clean
-uninstall: submodules
+uninstall:
node cli.js rm npm -g -f
doc: $(mandocs) $(htmldocs)
doc/cli/index.md: $(markdowns) scripts/index-build.js scripts/doc-build.sh package.json
node scripts/index-build.js > $@
-node_modules/ronn:
+node_modules/.bin/ronn:
node cli.js install https://github.com/isaacs/ronnjs/tarball/master
doc: man
man: $(cli_docs) $(api_docs)
-test: submodules
+test:
node cli.js test
version: link
git ci -m v$(shell npm -v)
publish: link doc
- git tag -d v$(shell npm -v) || true
- git push origin :v$(shell npm -v) || true
- npm unpublish npm@$(shell npm -v) || true
+ @git tag -d v$(shell npm -v) || true
+ @git push origin :v$(shell npm -v) || true
+ @npm unpublish npm@$(shell npm -v) || true
+ git clean -fd
git tag -s -m v$(shell npm -v) v$(shell npm -v) &&\
git push origin --tags &&\
npm publish &&\
--- /dev/null
+#!/bin/sh
+if [ -x "`dirname "$0"`/node.exe" ]; then
+ "`dirname "$0"`/node.exe" "`dirname "$0"`/node_modules/npm/bin/npm-cli.js" "$@"
+else
+ node "`dirname "$0"`/node_modules/npm/bin/npm-cli.js" "$@"
+fi
+++ /dev/null
-:: Created by npm, please don't edit manually.\r
-@IF EXIST "%~dp0"\"node.exe" (\r
- "%~dp0"\"node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*\r
-) ELSE (\r
- node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*\r
-)
\ No newline at end of file
+++ /dev/null
-:: Created by npm, please don't edit manually.\r
-@IF EXIST "%~dp0"\"node.exe" (\r
- "%~dp0"\"node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*\r
-) ELSE (\r
- node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*\r
-)
\ No newline at end of file
* `-v`: `--version`
* `-h`, `-?`, `--help`, `-H`: `--usage`
* `-s`, `--silent`: `--loglevel silent`
+* `-q`, `--quiet`: `--loglevel warn`
* `-d`: `--loglevel info`
* `-dd`, `--verbose`: `--loglevel verbose`
* `-ddd`: `--loglevel silly`
* skips cache when requesting from the registry.
* prevents checks against clobbering non-npm files.
+### git
+
+* Default: `"git"`
+* Type: String
+
+The command to use for git commands. If git is installed on the
+computer, but is not in the `PATH`, then set this to the full path to
+the git binary.
+
### global
* Default: false
<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.0-beta-10</p>
+<p id="footer">bin — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">bugs — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">commands — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">config — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">deprecate — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">docs — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">edit — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">explore — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">help-search — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">init — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">install — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">link — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">load — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">ls — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.0-beta-10</p>
+<p>1.1.0-2</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.0-beta-10</p>
+<p id="footer">npm — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">outdated — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">owner — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">pack — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">prefix — npm@1.1.0-beta-10</p>
+<p id="footer">prefix — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">prune — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">publish — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>See <code>npm help build</code></p>
</div>
-<p id="footer">rebuild — npm@1.1.0-beta-10</p>
+<p id="footer">rebuild — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">restart — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically.</p>
</div>
-<p id="footer">root — npm@1.1.0-beta-10</p>
+<p id="footer">root — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">run-script — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">search — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">start — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">stop — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">submodule — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">tag — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">test — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">uninstall — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">unpublish — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">update — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">version — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">view — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">whoami — npm@1.1.0-beta-10</p>
+<p id="footer">whoami — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">adduser — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">bin — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">bugs — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">build — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">bundle — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">cache — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">changelog — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">coding-style — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">completion — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The following shorthands are parsed on the command-line:</p>
-<ul><li><code>-v</code>: <code>--version</code></li><li><code>-h</code>, <code>-?</code>, <code>--help</code>, <code>-H</code>: <code>--usage</code></li><li><code>-s</code>, <code>--silent</code>: <code>--loglevel silent</code></li><li><code>-d</code>: <code>--loglevel info</code></li><li><code>-dd</code>, <code>--verbose</code>: <code>--loglevel verbose</code></li><li><code>-ddd</code>: <code>--loglevel silly</code></li><li><code>-g</code>: <code>--global</code></li><li><code>-l</code>: <code>--long</code></li><li><code>-m</code>: <code>--message</code></li><li><code>-p</code>, <code>--porcelain</code>: <code>--parseable</code></li><li><code>-reg</code>: <code>--registry</code></li><li><code>-v</code>: <code>--version</code></li><li><code>-f</code>: <code>--force</code></li><li><code>-l</code>: <code>--long</code></li><li><code>-desc</code>: <code>--description</code></li><li><code>-S</code>: <code>--save</code></li><li><code>-y</code>: <code>--yes</code></li><li><code>-n</code>: <code>--yes false</code></li><li><code>ll</code> and <code>la</code> commands: <code>ls --long</code></li></ul>
+<ul><li><code>-v</code>: <code>--version</code></li><li><code>-h</code>, <code>-?</code>, <code>--help</code>, <code>-H</code>: <code>--usage</code></li><li><code>-s</code>, <code>--silent</code>: <code>--loglevel silent</code></li><li><code>-q</code>, <code>--quiet</code>: <code>--loglevel warn</code></li><li><code>-d</code>: <code>--loglevel info</code></li><li><code>-dd</code>, <code>--verbose</code>: <code>--loglevel verbose</code></li><li><code>-ddd</code>: <code>--loglevel silly</code></li><li><code>-g</code>: <code>--global</code></li><li><code>-l</code>: <code>--long</code></li><li><code>-m</code>: <code>--message</code></li><li><code>-p</code>, <code>--porcelain</code>: <code>--parseable</code></li><li><code>-reg</code>: <code>--registry</code></li><li><code>-v</code>: <code>--version</code></li><li><code>-f</code>: <code>--force</code></li><li><code>-l</code>: <code>--long</code></li><li><code>-desc</code>: <code>--description</code></li><li><code>-S</code>: <code>--save</code></li><li><code>-y</code>: <code>--yes</code></li><li><code>-n</code>: <code>--yes false</code></li><li><code>ll</code> and <code>la</code> commands: <code>ls --long</code></li></ul>
<p>If the specified configuration param resolves unambiguously to a known
configuration parameter, then it is expanded to that configuration
<ul><li>lifecycle script failure does not block progress.</li><li>publishing clobbers previously published versions.</li><li>skips cache when requesting from the registry.</li><li>prevents checks against clobbering non-npm files.</li></ul>
+<h3 id="git">git</h3>
+
+<ul><li>Default: <code>"git"</code></li><li>Type: String</li></ul>
+
+<p>The command to use for git commands. If git is installed on the
+computer, but is not in the <code>PATH</code>, then set this to the full path to
+the git binary.</p>
+
<h3 id="global">global</h3>
<ul><li>Default: false</li><li>Type: Boolean</li></ul>
<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.0-beta-10</p>
+<p id="footer">config — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">deprecate — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">developers — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">disputes — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">docs — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">edit — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">explore — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">faq — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">folders — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">help-search — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">help — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p> Display npm username</p>
</div>
-<p id="footer">index — npm@1.1.0-beta-10</p>
+<p id="footer">index — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">init — npm@1.1.0-2</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></ul>
</div>
-<p id="footer">install — npm@1.1.0-beta-10</p>
+<p id="footer">install — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">json — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">link — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">list — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.0-beta-10</p>
+<p>1.1.0-2</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.0-beta-10</p>
+<p id="footer">npm — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">outdated — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">owner — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">pack — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">prefix — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">prune — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">publish — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">rebuild — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">registry — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">removing-npm — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">restart — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">root — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">run-script — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">scripts — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">search — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">semver — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">star — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">start — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">stop — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">submodule — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">tag — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">test — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">uninstall — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">unpublish — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">update — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">version — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">view — npm@1.1.0-2</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.0-beta-10</p>
+<p id="footer">whoami — npm@1.1.0-2</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
var tmp = path.join(npm.tmp, Date.now()+"-"+Math.random())
mkdir(path.dirname(tmp), function (er) {
if (er) return cb(er)
- exec( "git", ["clone", u, tmp], null, false
+ exec( npm.config.get("git"), ["clone", u, tmp], null, false
, function (er, code, stdout, stderr) {
stdout = (stdout + "\n" + stderr).trim()
if (er) {
return cb(er)
}
log.verbose(stdout, "git clone "+u)
- exec( "git", ["checkout", co], null, false, tmp
+ exec( npm.config.get("git"), ["checkout", co], null, false, tmp
, function (er, code, stdout, stderr) {
stdout = (stdout + "\n" + stderr).trim()
if (er) {
function defaultVersion (folder, data, cb) {
if (data.version) return cb(null, data.version)
- exec("git", ["describe", "--tags"], process.env, false, folder,
+ exec(npm.config.get("git"), ["describe", "--tags"], process.env, false, folder,
function (er, code, out) {
out = (out || "").trim()
if (semver.valid(out)) return cb(null, out)
function defaultRepo (folder, data, cb) {
if (data.repository) return cb(null, data.repository)
- exec( "git", ["remote", "-v"], process.env, false, folder
+ exec( npm.config.get("git"), ["remote", "-v"], process.env, false, folder
, function (er, code, out) {
out = (out || "")
.trim()
installManyTop(deps.map(function (dep) {
var target = data.dependencies[dep]
, parsed = url.parse(target.replace(/^git\+/, "git"))
- if (!parsed.protocol) {
- target = dep + "@" + target
- }
+ target = dep + "@" + target
return target
- }), where, family, ancestors, false, cb)
+ }), where, family, ancestors, false, data, cb)
})
}
, ancestors = {}
if (data) family[data.name] = ancestors[data.name] = data.version
var fn = npm.config.get("global") ? installMany : installManyTop
- fn(args, where, family, ancestors, true, cb)
+ fn(args, where, family, ancestors, true, data, cb)
})
})
}
// The relevant tree shape is { <folder>: {what:<pkg>} }
var saveTarget = path.resolve(where, "package.json")
, things = Object.keys(tree).map(function (k) {
- //log.warn(k, "k")
return tree[k].what.split("@")
}).reduce(function (set, k) {
var rangeDescriptor = semver.gte(k[1], "0.1.0") ? "~" : ""
return set
}, {})
- //log.warn(things, "things")
-
// don't use readJson, because we don't want to do all the other
// tricky npm-specific stuff that's in there.
fs.readFile(saveTarget, function (er, data) {
// just like installMany, but also add the existing packages in
// where/node_modules to the family object.
-function installManyTop (what, where, family, ancestors, explicit, cb_) {
+function installManyTop (what, where, family, ancestors, explicit, parent, cb_) {
function cb (er, d) {
if (explicit || er) return cb_(er, d)
function next (er) {
if (er) return cb(er)
- installManyTop_(what, where, family, ancestors, explicit, cb)
+ installManyTop_(what, where, family, ancestors, explicit, parent, cb)
}
}
-function installManyTop_ (what, where, family, ancestors, explicit, cb) {
+function installManyTop_ (what, where, family, ancestors, explicit, parent, cb) {
var nm = path.resolve(where, "node_modules")
, names = explicit
? what.map(function (w) { return w.split(/@/).shift() })
: []
fs.readdir(nm, function (er, pkgs) {
- if (er) return installMany(what, where, family, ancestors, explicit, cb)
+ if (er) return installMany(what, where, family, ancestors, explicit, parent, cb)
pkgs = pkgs.filter(function (p) {
return !p.match(/^[\._-]/)
&& (!explicit || names.indexOf(p) === -1)
packages.forEach(function (p) {
family[p[0]] = p[1]
})
- return installMany(what, where, family, ancestors, explicit, cb)
+ return installMany(what, where, family, ancestors, explicit, parent, cb)
})
})
}
-function installMany (what, where, family, ancestors, explicit, cb) {
+function installMany (what, where, family, ancestors, explicit, parent, cb) {
// 'npm install foo' should install the version of foo
// that satisfies the dep in the current folder.
// This will typically return immediately, since we already read
if (er) data = {}
d = data.dependencies || {}
- var parent = data._id
+ var parent = data
- log.verbose(what, "into "+where)
// what is a list of things.
// resolve each one.
asyncMap( what
- , targetResolver(where, family, ancestors, explicit, d)
+ , targetResolver(where, family, ancestors, explicit, d, parent)
, function (er, targets) {
+
if (er) return cb(er)
+
// each target will be a data object corresponding
// to a package, folder, or whatever that is in the cache now.
var newPrev = Object.create(family)
})
}
-function targetResolver (where, family, ancestors, explicit, deps) {
+function targetResolver (where, family, ancestors, explicit, deps, parent) {
var alreadyInstalledManually = explicit ? [] : null
, nm = path.resolve(where, "node_modules")
if (deps[what]) {
what = what + "@" + deps[what]
}
- log.verbose(what, "cache add")
+
cache.add(what, function (er, data) {
+ if (er && parent && parent.optionalDependencies &&
+ parent.optionalDependencies.hasOwnProperty(what.split("@").shift())) {
+ log.warn(what, "optional dependency failed, continuing")
+ return cb(null, [])
+ }
if (!er && data && family[data.name] === data.version) {
return cb(null, [])
}
function thenLink () {
npm.commands.link([target.name], function (er, d) {
log.silly([er, d], "back from link")
- cb(er, [resultList(target, where, parent)])
+ cb(er, [resultList(target, where, parent && parent._id)])
})
}
})
}
-function resultList (target, where, parent) {
+function resultList (target, where, parentId) {
var nm = path.resolve(where, "node_modules")
, targetFolder = path.resolve(nm, target.name)
, prettyWhere = relativize(where, process.cwd() + "/x")
return [ target._id
, targetFolder
- , prettyWhere && parent
- , parent && prettyWhere ]
+ , prettyWhere && parentId
+ , parentId && prettyWhere ]
}
function installOne_ (target, where, family, ancestors, parent, cb) {
, function (er, d) {
log.verbose(target._id, "installOne cb")
if (er) return cb(er)
-
- d.push(resultList(target, where, parent))
+ d.push(resultList(target, where, parent && parent._id))
cb(er, d)
}
)
}).map(function (d) {
var t = target.dependencies[d]
, parsed = url.parse(t.replace(/^git\+/, "git"))
- if (!parsed.protocol) {
- t = d + "@" + t
- }
+ t = d + "@" + t
return t
- }), targetFolder, family, ancestors, false, function (er, d) {
- //log.warn(d, "write installMany cb")
+ }), targetFolder, family, ancestors, false, target, function (er, d) {
log.verbose(targetFolder, "about to build")
if (er) return cb(er)
npm.commands.build( [targetFolder]
}
function updateSubmodule (name, cb) {
- exec( "git", [ "submodule", "update", "--init"
+ exec( npm.config.get("git"), [ "submodule", "update", "--init"
, "node_modules/" + name ]
, null, true, npm.prefix, cb)
}
function addSubmodule (name, url, cb) {
- exec( "git", [ "submodule", "add", url
+ exec( npm.config.get("git"), [ "submodule", "add", url
, "node_modules/" + name ]
, null, true, npm.prefix, function (er) {
if (er) return cb(er)
var getSubmodules = function getSubmodules (cb) {
- exec( "git", ["submodule", "status"], null, false
+ exec( npm.config.get("git"), ["submodule", "status"], null, false
, npm.prefix, function (er, code, stdout, stderr) {
if (er) return cb(er)
res = stdout.trim().split(/\n/).map(function (line) {
-// XXX Todo:
+// XXX Todo:
// On windows, create a .cmd file.
// Read the #! in the file to see what it uses. The vast majority
// of the time, this will be either:
chain
( [ [fs, "stat", from]
, [rm, to + ".cmd"]
+ , [rm, to]
, [mkdir, path.dirname(to)]
, [writeShim, from, to] ]
, cb )
}
function writeShim (from, to, cb) {
- // make a cmd file
+ // make a cmd file and a sh script
// First, check if the bin is a #! of some sort.
// If not, then assume it's something that'll be compiled, or some other
// sort of script, and just call it directly.
}
function writeShim_ (from, to, prog, args, cb) {
- var target = relativize(from, to).split("/").join("\\")
+ var shTarget = relativize(from, to)
+ , target = shTarget.split("/").join("\\")
, longProg
+ , shProg = prog
+ , shLongProg
args = args || ""
if (!prog) {
prog = "\"%~dp0\\" + target + "\""
+ shProg = "\"`dirname \"$0\"`/" + shTarget + "\""
args = ""
target = ""
+ shTarget = ""
} else {
longProg = "\"%~dp0\"\\\"" + prog + ".exe\""
+ shLongProg = "\"`dirname \"$0\"`/" + prog + "\""
target = "\"%~dp0\\" + target + "\""
+ shTarget = "\"`dirname \"$0\"`/" + shTarget + "\""
}
// @IF EXIST "%~dp0"\"node.exe" (
cmd = ":: Created by npm, please don't edit manually.\r\n" + cmd
+ // #!/bin/sh
+ // if [ -x "`dirname "$0"`/node.exe" ]; then
+ // "`dirname "$0"`/node.exe" "`dirname "$0"`/node_modules/npm/bin/npm-cli.js" "$@"
+ // else
+ // node "`dirname "$0"`/node_modules/npm/bin/npm-cli.js" "$@"
+ // fi
+ var sh = "#!/bin/sh\n"
+
+ if (shLongProg) {
+ sh = sh
+ + "if [ -x "+shLongProg+" ]; then\n"
+ + " " + shLongProg + " " + args + " " + shTarget + " \"$@\"\n"
+ + " ret=$?\n"
+ + "else \n"
+ + " " + shProg + " " + args + " " + shTarget + " \"$@\"\n"
+ + " ret=$?\n"
+ + "fi\n"
+ + "exit $ret\n"
+ } else {
+ sh = shProg + " " + args + " " + shTarget + " \"$@\"\n"
+ + "exit $?\n"
+ }
+
fs.writeFile(to + ".cmd", cmd, "utf8", function (er) {
if (er) {
log.warn("Could not write "+to+".cmd", "cmdShim")
+ return cb(er)
}
- cb(er)
+ fs.writeFile(to, sh, "utf8", function (er) {
+ if (er) {
+ log.warn("Could not write "+to, "shShim")
+ return cb(er)
+ }
+ fs.chmod(to, 0755, cb)
+ })
})
}
, editor : process.env.EDITOR ||
( process.platform === "win32" ? "notepad" : "vi" )
, force : false
+
+ , git: "git"
+
, global : false
, globalconfig : path.resolve(globalPrefix, "etc", "npmrc")
, globalignorefile : path.resolve( globalPrefix, "etc", "npmignore")
, dev : Boolean
, editor : String
, force : Boolean
+ , git: String
, global : Boolean
, globalconfig : path
, globalignorefile: path
, "no-reg" : ["--no-registry"]
, silent : ["--loglevel", "silent"]
, verbose : ["--loglevel", "verbose"]
+ , quiet: ["--loglevel", "warn"]
+ , q: ["--loglevel", "warn"]
, h : ["--usage"]
, H : ["--usage"]
, "?" : ["--usage"]
er.errno = npm[m] || constants[m]
}
- switch (er.errno) {
+ console.error("")
+ switch (er.code || er.errno) {
case "ECONNREFUSED":
case constants.ECONNREFUSED:
log.error(er)
- log.error(["If you are using Cygwin, please set up your /etc/resolv.conf"
- ,"See step 4 in this wiki page:"
- ," http://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29"
- ,"If you are not using Cygwin, please report this"
- ,"at <http://github.com/isaacs/npm/issues>"
- ,"or email it to <npm-@googlegroups.com>"
+ log.error(["\nIf you are behind a proxy, please make sure that the"
+ ,"'proxy' config is set properly. See: 'npm help config'"
].join("\n"))
break
case constants.EACCES:
case constants.EPERM:
log.error(er)
- log.error(["",
- "Please use 'sudo' or log in as root to run this command."
- ,""
- ," sudo npm "
- +npm.config.get("argv").original.map(JSON.stringify).join(" ")
- ,""
- ,"or set the 'unsafe-perm' config var to true."
- ,""
- ," npm config set unsafe-perm true"
+ log.error(["\nPlease try running this command again as root/Administrator."
].join("\n"))
break
er.code = "E404"
if (er.pkgid && er.pkgid !== "-") {
var msg = ["'"+er.pkgid+"' is not in the npm registry."
- ,"You could maybe bug the author to publish it"]
+ ,"You should bug the author to publish it"]
if (er.pkgid.match(/^node[\.\-]|[\.\-]js$/)) {
var s = er.pkgid.replace(/^node[\.\-]|[\.\-]js$/g, "")
if (s !== er.pkgid) {
s = s.replace(/[^a-z0-9]/g, ' ')
- msg.push("Maybe try 'npm search " + s + "'")
+ msg.push("\nMaybe try 'npm search " + s + "'")
}
}
- msg.push("Note that you can also install from a tarball or folder.")
+ msg.push("\nNote that you can also install from a"
+ ,"tarball, folder, or http url, or git url.")
log.error(msg.join("\n"), "404")
}
break
default:
log.error(er)
- log.error(["Report this *entire* log at:"
+ log.error(["You may report this log at:"
," <http://github.com/isaacs/npm/issues>"
,"or email it to:"
," <npm-@googlegroups.com>"
, "arguments"
, "code"
, "message"
+ , "errno"
].forEach(function (k) {
if (er[k]) log.error(er[k], k)
})
if (isPath) {
if (typeof process.env.HOME !== 'undefined') {
if (process.env.HOME.substr(-1) === "/") {
- process.env.HOME = process.env.HOME(0, process.env.HOME.length-1)
+ process.env.HOME = process.env.HOME.slice(0, process.env.HOME.length-1)
}
if (f.indexOf(process.env.HOME) === 0) {
f = "~"+f.substr(process.env.HOME.length)
return [npm.commands, "run-script", [p, stage]]
}), cb)
} else npm.commands["run-script"]([stage], cb)
- }
+ }
CMD.usage = "npm "+stage+" <name>"
var installedShallow = require("./completion/installed-shallow.js")
CMD.completion = function (opts, cb) {
installedData.forEach(function (dep) {
obj.dependencies[dep.realName] = dep
})
+
+ // any strings here are unmet things. however, if it's
+ // optional, then that's fine, so just delete it.
+ if (obj.optionalDependencies) {
+ Object.keys(obj.optionalDependencies).forEach(function (dep) {
+ if (typeof obj.dependencies[dep] === "string") {
+ delete obj.dependencies[dep]
+ }
+ })
+ }
return cb(null, obj)
})
}
}
deps[d] = found
}
+
})
log.verbose([obj._id], "returning")
return obj
delete json["dev-dependencies"]
}
- ;["dependencies", "devDependencies"].forEach(function (d) {
- json[d] = json.hasOwnProperty(d) ? depObjectify(json[d], d, json._id) : {}
+ ; [ "dependencies"
+ , "devDependencies"
+ , "optionalDependencies"
+ ].forEach(function (d) {
+ json[d] = json.hasOwnProperty(d)
+ ? depObjectify(json[d], d, json._id)
+ : {}
+ })
+
+ // always merge optionals into deps
+ Object.keys(json.optionalDependencies).forEach(function (d) {
+ json.dependencies[d] = json.optionalDependencies[d]
})
- if (opts.dev || npm.config.get("dev") || npm.config.get("npat")) {
+ if (opts.dev
+ || npm.config.get("dev")
+ || npm.config.get("npat")) {
// log.warn(json._id, "Adding devdeps")
Object.keys(json.devDependencies || {}).forEach(function (d) {
json.dependencies[d] = json.devDependencies[d]
})
}
function checkGit (data, cb) {
- exec( "git", ["status", "--porcelain"], process.env, false
+ exec( npm.config.get("git"), ["status", "--porcelain"], process.env, false
, function (er, code, stdout, stderr) {
var lines = stdout.trim().split("\n").filter(function (line) {
return line.trim() && !line.match(/^\?\? /)
if (er) return cb(er)
var message = npm.config.get("message").replace(/%s/g, data.version)
chain
- ( [ [ exec, "git", ["add","package.json"], process.env, false ]
- , [ exec, "git", ["commit", "-m", message ]
- , process.env, false ]
- , [ exec, "git", ["tag", "v"+data.version], process.env, false ] ]
+ ( [ [ exec, npm.config.get("git")
+ , ["add","package.json"], process.env, false ]
+ , [ exec, npm.config.get("git")
+ , ["commit", "-m", message ], process.env, false ]
+ , [ exec, npm.config.get("git")
+ , ["tag", "v"+data.version], process.env, false ] ]
, cb )
})
})
\fB\-s\fR, \fB\-\-silent\fR: \fB\-\-loglevel silent\fR
.
.IP "\(bu" 4
+\fB\-q\fR, \fB\-\-quiet\fR: \fB\-\-loglevel warn\fR
+.
+.IP "\(bu" 4
\fB\-d\fR: \fB\-\-loglevel info\fR
.
.IP "\(bu" 4
.
.IP "" 0
.
+.SS "git"
+.
+.IP "\(bu" 4
+Default: \fB"git"\fR
+.
+.IP "\(bu" 4
+Type: String
+.
+.IP "" 0
+.
+.P
+The command to use for git commands\. If git is installed on the
+computer, but is not in the \fBPATH\fR, then set this to the full path to
+the git binary\.
+.
.SS "global"
.
.IP "\(bu" 4
.fi
.
.SH "VERSION"
-1.1.0-beta-10
+1.1.0-2
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
.fi
.
.SH "VERSION"
-1.1.0-beta-10
+1.1.0-2
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
* `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.
if (!this._head) this._head = this._tail
this.length ++
}
+
, pop: function () {
if (this.length === 0) return undefined
var t = 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
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) {
- throw new Error("invalid offset: "+n+","+m)
+ if (m === n) {
+ return []
+ }
+
+ if (m < n) {
+ throw new Error("invalid offset: "+n+","+m+" (length="+this.length+")")
}
var len = m - n
}
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
"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.1",
+ "version": "1.0.2",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/fast-list.git"
"tap": "~0.1.0"
},
"scripts": {
- "test": "node test.js",
+ "test": "tap test.js",
"bench": "node bench.js"
}
}
Consider an ini-file `config.ini` that looks like this:
- ; this comment is beeing ignored
+ ; this comment is being ignored
scope = global
[database]
}
children.forEach(function (k, _, __) {
- out += encode(obj[k], (section ? section + "." : "") + k)
+ var child = encode(obj[k], (section ? section + "." : "") + k)
+ if (out.length && child.length) {
+ out += "\n"
+ }
+ out += child
})
return out
function safe (val) {
return ( typeof val !== "string"
|| val.match(/[\r\n]/)
+ || val.match(/^\[/)
|| (val.length > 1
&& val.charAt(0) === "\""
&& val.slice(-1) === "\"")
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "ini",
"description": "An ini encoder/decoder for node",
- "version": "1.0.1",
+ "version": "1.0.2",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/ini.git"
## Features
-Supports all glob features.
+Supports these glob features:
+
+* Brace Expansion
+* Extended glob matching
+* "Globstar" `**` matching
See:
* `man sh`
-* `man fnmatch`
+* `man bash`
+* `man 3 fnmatch`
* `man 5 gitignore`
-### Departures from zsh/bash/ksh/sh
+### 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.
+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.)
+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 `**` is always supported, instead of requiring a special
-flag.
+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
`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.
+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`.
+supplied argument, suitable for use with `Array.filter`. Example:
+
+```javascript
+var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
+```
### minimatch.match(list, pattern, options)
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.
+Make a regular expression object from the pattern.
## Options
Dump a ton of stuff to stderr.
-### null
+### nobrace
-Return an empty list from minimatch.match, instead of a list
-containing the pattern itself.
+Do not expand `{a,b}` and `{1..3}` brace sets.
-### nocase
+### noglobstar
-Perform a case-insensitive match.
+Disable `**` matching against multiple folder names.
-### cache
+### dot
+
+Allow patterns to match filenames starting with a period, even if
+the pattern does not explicitly have a period in that spot.
-An LRU cache with `.get(k)` and `.set(k,v)` methods. By
-default, an instance of `node-lru-cache` is used, with 1000 max
-entries.
+Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
+is set.
-### slash
+### noext
-If set, then `a/*` will match `a/` as well as `a/b`.
+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 `xyz/123/acb`.
+`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
-### partial
+### nocomment
-Internal. Used by `minimatch.makeRe`.
+Suppress the behavior of treating `#` at the start of a pattern as a
+comment.
-### dot
+### nonegate
-Allow patterns to match paths starting with a period, even if
-the pattern does not explicitly start with a period.
+Suppress the behavior of treating a leading `!` character as negation.
-// This is a JavaScript implementation of the fnmatch-like
-// stuff that git uses in its .gitignore files.
-// See `man 5 gitignore`.
-
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")
- , LRU = require("lru-cache")
+ // 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.filter = function (pattern, options) {
+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)
}
}
-minimatch.match = function (list, pattern, options) {
+function minimatch (p, pattern, options) {
+ if (typeof pattern !== "string") {
+ throw new TypeError("glob pattern string required")
+ }
+
if (!options) options = {}
- var ret = list.filter(minimatch.filter(pattern, options))
- if (options.debug) console.error("\nmatch: %s %j %j", pattern, list, ret)
- // set the null flag to allow empty match sets
- // Note that minimatch itself, and filter(), do not
- // respect this flag, only minimatch.match(list, pattern) does.
- if (!options.null && !ret.length) {
- return [pattern]
+ // shortcut: comments match nothing.
+ if (!options.nocomment && pattern.charAt(0) === "#") {
+ return false
}
- return ret
+ // "" only matches ""
+ if (pattern.trim() === "") return p === ""
+
+ return new Minimatch(pattern, options).match(p)
}
-function minimatch (p, pattern, options) {
+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")
}
- options = options || {}
+ 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()
+}
- // to set the cache, just replace with a different obj
- // supporting set(k,v) and v=get(k) methods.
- var cache = options.cache || minimatch.cache
- if (!cache) cache = minimatch.cache = new LRU(1000)
+Minimatch.prototype.make = make
+function make () {
+ // don't do it more than once.
+ if (this._made) return
- // "" only matches ""
- if (!pattern) return p === ""
+ 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.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 = set.map(function (s) {
+ return s.split(slashSplit)
+ })
+
+ // 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
+ || (p[0].match(/^[a-zA-Z]:$/)) )) {
+ return p
+ }
+ if (options.matchBase && p.length === 1) return p
+ // do prefixing.
+ if (options.root && p[0] === "") {
+ return options.root.split(pathSplit).concat(p)
+ }
+ if (options.cwd && p[0] !== "") {
+ return options.cwd.split(pathSplit).concat(p)
+ }
+ return p
+ })
- // comments.
- if (pattern.trim().charAt(0) === "#") return false
- // check the cache
- var re = cache.get(pattern + "\n" + JSON.stringify(options))
- if (!re && re !== false) {
- cache.set(pattern, re = minimatch.makeRe(pattern, options))
+ 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 (options.debug) {
- console.error(pattern + "\t" + re, JSON.stringify(p))
- }
-
- // some kind of invalid thing
- if (!re) return false
-
-
- // patterns that end in / can only match dirs
- // however, dirs also match the same thing that *doesn't*
- // end in a slash.
- var match =
- // a/ should not match a/*, but will match */
- // accomplish this by not applying the regexp
- // directly, unless the pattern would match
- // trailing slash'ed things, or the thing isn't
- // a trailing slash, or slashes are opted-in
- ( ( options.slash ||
- p.substr(-1) !== "/" ||
- pattern.substr(-1) === "/" )
- && !!p.match(re) )
-
- // a/ should match * or a
- || ( p.substr(-1) === "/" &&
- !!p.slice(0, -1).match(re) )
-
- // a pattern with *no* slashes will match against
- // either the full path, or just the basename.
- || ( options.matchBase &&
- pattern.indexOf("/") === -1 &&
- path.basename(p).match(re) )
-
- //console.error(" MINIMATCH: %j %j %j %j",
- // re.toString(), pattern, p, match)
- return match
+ if (negateOffset) this.pattern = pattern.substr(negateOffset)
+ this.negate = negate
}
-minimatch.makeRe = makeRe
-function makeRe (pattern, options) {
- options = options || {}
+// 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) {
// that wasn't consumed by this pass.
switch (stateChar) {
case "*":
- re += oneStar
+ re += star
+ hasMagic = true
break
case "?":
- re += "."
+ re += qmark
+ hasMagic = true
break
default:
re += "\\"+stateChar
}
}
- var braceDepth = 0
- , re = ""
- , escaping = false
- , oneStar = options.dot ? "[^\\/]*?"
- : "(?:(?!(?:\\\/|^)\\.)[^\\/])*?"
- , twoStar = options.dot ? ".*?"
- // not a ^ or / followed by a dot,
- // followed by anything, any number of times.
- : "(?:(?!(?:\\\/|^)\\.).)*?"
- , reSpecials = "().*{}+?[]^$/\\"
- , patternListStack = []
- , stateChar
- , negate = false
- , negating = false
- , inClass = false
- , reClassStart = -1
- , classStart = -1
- , classStartPattern = options.dot ? ""
- : "(?:(?!(?:\\\/|^)\\.)"
- , classEndPattern = options.dot ? "" : ")"
-
for ( var i = 0, len = pattern.length, c
; (i < len) && (c = pattern.charAt(i))
; i ++ ) {
console.error("%s\t%s %s %j", pattern, i, re, c)
}
- switch (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 "\\":
- if (stateChar) {
- if (stateChar === "*") re += oneStar
- else re += "\\" + stateChar
- stateChar = false
- }
- if (escaping) {
- re += "\\\\" // must match literal \
- escaping = false
- } else {
- escaping = true
- }
+ clearStateChar()
+ escaping = true
continue
// the various stateChar values
- case "!":
- if (i === 0 || negating) {
- negate = !negate
- negating = true
- break
- } else {
- negating = false
- }
- // fallthrough
+ // for the "extglob" stuff.
+ case "?":
+ case "*":
case "+":
case "@":
- case "*":
- case "?":
- if (options.debug) {
- console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
- }
+ case "!":
+ if (options.debug) {
+ console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
+ }
- negating = false
- if (escaping) {
- re += "\\" + c
- escaping = false
- } else if (inClass) {
+ // 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
- } else if (c === "*" && stateChar === "*") { // **
- re += twoStar
- stateChar = false
- } else {
- if (stateChar) {
- if (stateChar === "*") re += oneStar
- else if (stateChar === "?") re += "."
- else re += "\\" + stateChar
- }
- stateChar = 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 (escaping) {
- re += "\\("
- escaping = false
- } else if (inClass) {
+ if (inClass) {
re += "("
- } else if (stateChar) {
- plType = stateChar
- patternListStack.push(plType)
- re += stateChar === "!" ? "(?!" : "(?:"
- stateChar = false
- } else {
+ continue
+ }
+
+ if (!stateChar) {
re += "\\("
+ continue
}
+
+ plType = stateChar
+ patternListStack.push({ type: plType
+ , start: i - 1
+ , reStart: re.length })
+ re += stateChar === "!" ? "(?!" : "(?:"
+ stateChar = false
continue
case ")":
- if (escaping || inClass) {
- re += "\\)"
- escaping = false
- } else if (patternListStack.length) {
- re += ")"
- plType = patternListStack.pop()
- switch (plType) {
- case "?":
- case "+":
- case "*": re += plType
- case "!":
- case "@": break
- }
- } else {
+ 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 (escaping || inClass) {
+ if (inClass || !patternListStack.length || escaping) {
re += "\\|"
escaping = false
- } else if (patternListStack.length) {
- re += "|"
- } else {
- re += "\\|"
+ continue
}
+
+ re += "|"
continue
- // these are mostly the same in regexp and glob :)
+ // these are mostly the same in regexp and glob
case "[":
// swallow any state-tracking char before the [
clearStateChar()
- if (escaping || inClass) {
+ if (inClass) {
re += "\\" + c
- escaping = false
- } else {
- inClass = true
- classStart = i
- reClassStart = re.length
- re += classStartPattern
- re += c
+ continue
}
+
+ inClass = true
+ classStart = i
+ reClassStart = re.length
+ re += c
continue
case "]":
// 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) escaping = true
-
- if (escaping || !inClass) {
+ if (i === classStart + 1 || !inClass) {
re += "\\" + c
escaping = false
- } else {
- inClass = false
- re += c + classEndPattern
- }
- continue
-
- case "{":
- if (escaping || inClass) {
- re += "\\{"
- escaping = false
- } else {
- re += "(?:"
- braceDepth ++
- }
- continue
-
- case "}":
- if (escaping || inClass || braceDepth === 0) {
- re += "\\}"
- escaping = false
- } else {
- // swallow any state char that wasn't consumed
- clearStateChar()
- re += ")"
- braceDepth --
+ continue
}
- continue
- case ",":
- if (escaping || inClass || braceDepth === 0) {
- re += ","
- escaping = false
- } else {
- // swallow any state char that wasn't consumed
- clearStateChar()
- re += "|"
- }
+ // finish up the class.
+ hasMagic = true
+ inClass = false
+ re += c
continue
default:
if (escaping) {
// no need
escaping = false
- } else if (reSpecials.indexOf(c) !== -1
+ } else if (reSpecials[c]
&& !(c === "^" && inClass)) {
re += "\\"
}
re += c
} // switch
-
- if (negating && c !== "!") negating = false
-
} // for
- // handle trailing things that only matter at the very end.
- if (stateChar) {
- clearStateChar()
- } else if (escaping) {
- re += "\\\\"
- }
+ // 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 = re.substr(reClassStart + classStartPattern.length + 1)
- , csOpts = Object.create(options)
- csOpts.partial = true
+ 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
- re = re.substr(0, reClassStart) + "\\["
- + makeRe(cs, csOpts)
+ 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)
}
- if (options.partial) return re
+ 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 + "$"
- // fail on the pattern, but allow anything otherwise.
- if (negate) 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 === ""
+
+ var options = this.options
+
+ // first, normalize any slash-separated path parts.
+ // f = path.normalize(f)
+ var absolute = isAbsolute(f)
+
+ // console.error(this.pattern, f, absolute)
+
+ // 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)
+ // 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
+}
- // really insane glob patterns can cause bad things.
- var flags = ""
- if (options.nocase) flags += "i"
+// 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("/%s/%s", re, flags)
+ console.error("matchOne",
+ { "this": this
+ , file: file
+ , pattern: pattern })
}
- try {
- return new RegExp(re, flags)
- } catch(ex) {
- return false
+ 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, "\\$&")
+}
+
+
+function isAbsolute (p) {
+ if (process.platform !== "win32") return p.charAt(0) === "/"
+
+ // yanked from node/lib/path.js
+ var splitDeviceRe =
+ /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/
+
+ var result = p.match(splitDeviceRe)
+ , device = result[1] || ""
+ , isUnc = device && device.charAt(1) !== ":"
+ , isAbs = !!result[2] || isUnc // UNC always absolute
+
+ return isAbs
}
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
"name": "minimatch",
"description": "a glob matcher in javascript",
- "version": "0.0.5",
+ "version": "0.1.3",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/minimatch.git"
"node": "*"
},
"dependencies": {
- "lru-cache": "~1.0.2"
+ "lru-cache": "~1.0.5"
},
"devDependencies": {
- "tap": "~0.0.5"
+ "tap": "~0.1.3"
},
"licenses" : [
{
* Generate RFC4122 version 1 or version 4 UUIDs
* Runs in node.js and all browsers.
* Cryptographically strong random # generation on supporting platforms
-* 1.1K minified and gzip'ed
+* 1.1K minified and gzip'ed (Want something smaller? Check this [crazy shit](https://gist.github.com/982883) out! )
+* [Annotated source code](http://broofa.github.com/node-uuid/docs/uuid.html)
## Getting Started
* `options` - (Object) Optional uuid state to apply. Properties may include:
- * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomnly generated ID. See note 2.
+ * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomnly generated ID. See note 1.
* `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence. Default: An internally maintained clockseq is used.
- * `msecs` - (Number | Date) Time in milliseconds since unix Epoch. Default: The current time is used. See note 3.
- * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2.
+ * `msecs` - (Number | Date) Time in milliseconds since unix Epoch. Default: The current time is used.
+ * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2.
* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.
* `offset` - (Number) Starting index in `buffer` at which to begin writing.
Notes:
1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.)
-1. Specifying the `msecs` option bypasses the internal logic for ensuring id uniqueness. In this case you may want to also provide `clockseq` and `nsecs` options as well.
Example: Generate string UUID with fully-specified options
Example: In-place generation of two binary IDs
```javascript
-// In browsers: 'new Array(32)'
-var buffer = new Buffer(32).fill(0); // -> <Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
-uuid.v1(null, buffer, 0); // -> <Buffer 02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
-uuid.v1(null, buffer, 16); // -> <Buffer 02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15>
+// Generate two ids in an array
+var arr = new Array(32); // -> []
+uuid.v1(null, arr, 0); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15]
+uuid.v1(null, arr, 16); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15]
// Optionally use uuid.unparse() to get stringify the ids
-uuid.unparse(buffer); // -> '02a2ce90-1432-11e1-8558-0b488e4fc115'
-uuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115'
+uuid.unparse(buffer); // -> '02a2ce90-1432-11e1-8558-0b488e4fc115'
+uuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115'
```
### uuid.v4([`options` [, `buffer` [, `offset`]]])
* `options` - (Object) Optional uuid state to apply. Properties may include:
* `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values
+ * `rng` - (Function) Random # generator to use. Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values.
* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.
* `offset` - (Number) Starting index in `buffer` at which to begin writing.
For browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance).
-### Release notes
+## Release notes
-v1.3: Includes
+v1.3.2:
+* Improve tests and handling of v1() options (Issue #24)
+* Expose RNG option to allow for perf testing with different generators
+v1.3:
* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)!
* Support for node.js crypto API
* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code
"contributors" : [
{"name": "Christoph Tavan <dev@tavan.de>", "github": "https://github.com/ctavan"}
],
- "dependencies" : [],
+ "dependencies" : {},
"lib" : ".",
"main" : "./uuid.js",
- "version" : "1.3.0"
+ "version" : "1.3.3"
}
-/*
- * Generate RFC4122 (v1 and v4) UUIDs
- *
- * Documentation at https://github.com/broofa/node-uuid
- */
+// node-uuid/uuid.js
+//
+// Copyright (c) 2010 Robert Kieffer
+// Dual licensed under the MIT and GPL licenses.
+// Documentation and details at https://github.com/broofa/node-uuid
(function() {
var _global = this;
- // Random number generator (feature-detected below)
- var _rng;
+ // Unique ID creation requires a high quality random # generator, but
+ // Math.random() does not guarantee "cryptographic quality". So we feature
+ // detect for more robust APIs, normalizing each method to return 128-bits
+ // (16 bytes) of random data.
+ var mathRNG, nodeRNG, whatwgRNG;
- // node.js 'crypto' API
- // http://nodejs.org/docs/v0.6.2/api/crypto.html#randomBytes
- try {
- _rng = require('crypto').randomBytes;
- } catch (e) {}
+ // Math.random()-based RNG. All platforms, very fast, unknown quality
+ var _rndBytes = new Array(16);
+ mathRNG = function() {
+ var r, b = _rndBytes, i = 0;
+
+ for (var i = 0, r; i < 16; i++) {
+ if ((i & 0x03) == 0) r = Math.random() * 0x100000000;
+ b[i] = r >>> ((i & 0x03) << 3) & 0xff;
+ }
+
+ return b;
+ }
- // WHATWG crypto api, available in Chrome
- // http://wiki.whatwg.org/wiki/Crypto
- if (!_rng && _global.crypto && crypto.getRandomValues) {
- var _rnds = new Uint32Array(4), _rndBytes = new Array(16);
- var _rng = function() {
- // Get 32-bit rnds
+ // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
+ // WebKit only (currently), moderately fast, high quality
+ if (_global.crypto && crypto.getRandomValues) {
+ var _rnds = new Uint32Array(4);
+ whatwgRNG = function() {
crypto.getRandomValues(_rnds);
- // Unpack into byte array
for (var c = 0 ; c < 16; c++) {
_rndBytes[c] = _rnds[c >> 2] >>> ((c & 0x03) * 8) & 0xff;
}
return _rndBytes;
- };
+ }
}
- // Math.random - least desirable option since it does not guarantee
- // cryptographic quality.
- if (!_rng) {
- var _rndBytes = new Array(16);
- _rng = function() {
- var r, b = _rndBytes, i = 0;
-
- for (var i = 0, r; i < 16; i++) {
- if ((i & 0x03) == 0) r = Math.random() * 0x100000000;
- b[i] = r >>> ((i & 0x03) << 3) & 0xff;
- }
-
- return b;
+ // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html
+ // Node.js only, moderately fast, high quality
+ try {
+ var _rb = require('crypto').randomBytes;
+ nodeRNG = _rb && function() {
+ return _rb(16);
};
- }
+ } catch (e) {}
+
+ // Select RNG with best quality
+ var _rng = nodeRNG || whatwgRNG || mathRNG;
// Buffer class to use
var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array;
_hexToByte[_byteToHex[i]] = i;
}
- /** See docs at https://github.com/broofa/node-uuid */
+ // **`parse()` - Parse a UUID into it's component bytes**
function parse(s, buf, offset) {
var i = (buf && offset) || 0, ii = 0;
// Zero out remaining bytes if string was short
while (ii < 16) {
- buf[i + ii] = 0;
+ buf[i + ii++] = 0;
}
return buf;
}
- /** See docs at https://github.com/broofa/node-uuid */
+ // **`unparse()` - Convert UUID byte array (ala parse()) into a string**
function unparse(buf, offset) {
var i = offset || 0, bth = _byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}
- // Pre allocate array for constructing uuids
- var _buffer = new BufferClass(16);
-
- //
- // v1 UUID support
+ // **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html
- //
-
- // Per 4.1.4 - Offset (in msecs) from JS time to UUID (gregorian) time
- var EPOCH_OFFSET = 12219292800000;
// random #'s we need to init node and clockseq
- var _seedBytes = _rng(10);
+ var _seedBytes = _rng();
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
var _nodeId = [
];
// Per 4.2.2, randomize (14 bit) clockseq
- var _clockSeq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
+ var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
// Previous uuid creation time
- var _last = 0;
+ var _lastMSecs = 0, _lastNSecs = 0;
- // Count of UUIDs created during current time tick
- var _count = 0;
-
- /** See docs at https://github.com/broofa/node-uuid */
+ // See https://github.com/broofa/node-uuid for API details
function v1(options, buf, offset) {
var i = buf && offset || 0;
- var b = buf || _buffer;
+ var b = buf || [];
options = options || {};
- // JS Numbers aren't capable of representing time in the RFC-specified
- // 100-nanosecond units. To deal with this, we represent time as the usual
- // JS milliseconds, plus an additional 100-nanosecond unit offset.
- var msecs = 0; // JS time (msecs since Unix epoch)
- var nsecs = 0; // additional 100-nanosecond units to add to msecs
-
- if (options.msecs != null) {
- // Explicit time specified. Not that this turns off the internal logic
- // around uuid count and clock sequence used insure uniqueness
- msecs = (+options.msecs) + EPOCH_OFFSET;
- nsecs = options.nsecs || 0;
- } else {
- // No time options - Follow the RFC logic (4.2.1.2) for maintaining
- // clock seq and uuid count to help insure UUID uniqueness.
-
- msecs = new Date().getTime() + EPOCH_OFFSET;
-
- if (msecs < _last) {
- // Clock regression - Per 4.2.1.2, increment clock seq
- _clockSeq++;
- _count = 0;
- } else {
- // Per 4.2.1.2, use a count of uuid's generated during the current
- // clock cycle to simulate higher resolution clock
- _count = (msecs == _last) ? _count + 1 : 0;
- }
- _last = msecs;
-
- // Per 4.2.1.2 If generator creates more than one id per uuid 100-ns
- // interval, throw an error
- // (Requires generating > 10M uuids/sec. While unlikely, it's not
- // entirely inconceivable given the benchmark results we're getting)
- if (_count >= 10000) {
- throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
- }
+ var clockseq = options.clockseq != null ? options.clockseq : _clockseq;
+
+ // UUID timestamps are 100 nano-second units since the Gregorian epoch,
+ // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
+ // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
+ // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
+ var msecs = options.msecs != null ? options.msecs : new Date().getTime();
+
+ // Per 4.2.1.2, use count of uuid's generated during the current clock
+ // cycle to simulate higher resolution clock
+ var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1;
+
+ // Time since last uuid creation (in msecs)
+ var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
+
+ // Per 4.2.1.2, Bump clockseq on clock regression
+ if (dt < 0 && options.clockseq == null) {
+ clockseq = clockseq + 1 & 0x3fff;
+ }
+
+ // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
+ // time interval
+ if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
+ nsecs = 0;
+ }
- nsecs = _count;
+ // Per 4.2.1.2 Throw error if too many uuids are requested
+ if (nsecs >= 10000) {
+ throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
}
- // Per 4.1.4, timestamp composition
+ _lastMSecs = msecs;
+ _lastNSecs = nsecs;
+ _clockseq = clockseq;
- // time_low
+ // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
+ msecs += 12219292800000;
+
+ // `time_low`
var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
b[i++] = tl >>> 24 & 0xff;
b[i++] = tl >>> 16 & 0xff;
b[i++] = tl >>> 8 & 0xff;
b[i++] = tl & 0xff;
- // time_mid
+ // `time_mid`
var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
b[i++] = tmh >>> 8 & 0xff;
b[i++] = tmh & 0xff;
- // time_high_and_version
+ // `time_high_and_version`
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
b[i++] = tmh >>> 16 & 0xff;
- // Clock sequence
- var cs = options.clockseq != null ? options.clockseq : _clockSeq;
-
- // clock_seq_hi_and_reserved (Per 4.2.2 - include variant)
- b[i++] = cs >>> 8 | 0x80;
+ // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
+ b[i++] = clockseq >>> 8 | 0x80;
- // clock_seq_low
- b[i++] = cs & 0xff;
+ // `clock_seq_low`
+ b[i++] = clockseq & 0xff;
- // node
+ // `node`
var node = options.node || _nodeId;
for (var n = 0; n < 6; n++) {
b[i + n] = node[n];
return buf ? buf : unparse(b);
}
- //
- // v4 UUID support
- //
+ // **`v4()` - Generate random UUID**
- /** See docs at https://github.com/broofa/node-uuid */
+ // See https://github.com/broofa/node-uuid for API details
function v4(options, buf, offset) {
// Deprecated - 'format' argument, as supported in v1.2
var i = buf && offset || 0;
+
if (typeof(options) == 'string') {
buf = options == 'binary' ? new BufferClass(16) : null;
options = null;
}
+ options = options || {};
+
+ var rnds = options.random || (options.rng || _rng)();
- var rnds = options && options.random || _rng(16);
- // Per 4.4, set bits for version and clock_seq_hi_and_reserved
+ // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
return buf || unparse(rnds);
}
- //
- // Export API
- //
-
+ // Export public API
var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;
uuid.unparse = unparse;
uuid.BufferClass = BufferClass;
+ // Export RNG options
+ uuid.mathRNG = mathRNG;
+ uuid.nodeRNG = nodeRNG;
+ uuid.whatwgRNG = whatwgRNG;
+
if (typeof(module) != 'undefined') {
+ // Play nice with node.js
module.exports = uuid;
} else {
+ // Play nice with browsers
var _previousRoot = _global.uuid;
+
+ // **`noConflict()` - (browser only) to reset global 'uuid' var**
uuid.noConflict = function() {
_global.uuid = _previousRoot;
return uuid;
* `method` - http method, defaults to GET
* `headers` - http headers, defaults to {}
* `body` - entity body for POST and PUT requests. Must be buffer or string.
+* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.
* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.
* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.
* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.
* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.
* `onResponse` - If true the callback will be fired on the "response" event instead of "end". If a function it will be called on "response" and not effect the regular semantics of the main callback on "end".
-* `encoding` - Encoding to be used on response.setEncoding when buffering the response data.
+* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.
* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.
* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.
* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request
* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)
-The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body buffer.
+The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.
## Convenience methods
--- /dev/null
+module.exports = ForeverAgent
+
+var util = require('util')
+ , Agent = require('http').Agent
+ , net = require('net')
+
+function ForeverAgent(options) {
+ var self = this
+ self.options = options || {}
+ self.requests = {}
+ self.sockets = {}
+ self.freeSockets = {}
+ self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets
+ self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets
+ self.on('free', function(socket, host, port) {
+ var name = host + ':' + port
+ if (self.requests[name] && self.requests[name].length) {
+ self.requests[name].shift().onSocket(socket)
+ } else if (self.sockets[name].length < self.minSockets) {
+ if (!self.freeSockets[name]) self.freeSockets[name] = []
+ self.freeSockets[name].push(socket)
+
+ // if an error happens while we don't use the socket anyway, meh, throw the socket away
+ function onIdleError() {
+ socket.destroy()
+ }
+ socket._onIdleError = onIdleError
+ socket.on('error', onIdleError)
+ } else {
+ // If there are no pending requests just destroy the
+ // socket and it will get removed from the pool. This
+ // gets us out of timeout issues and allows us to
+ // default to Connection:keep-alive.
+ socket.destroy();
+ }
+ })
+ self.createConnection = net.createConnection
+}
+util.inherits(ForeverAgent, Agent)
+
+ForeverAgent.defaultMinSockets = 5
+
+ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest
+ForeverAgent.prototype.addRequest = function(req, host, port) {
+ var name = host + ':' + port
+ if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) {
+ var idleSocket = this.freeSockets[name].pop()
+ idleSocket.removeListener('error', idleSocket._onIdleError)
+ delete idleSocket._onIdleError
+ req._reusedSocket = true
+ req.onSocket(idleSocket)
+ } else {
+ this.addRequestNoreuse(req, host, port)
+ }
+}
+
+ForeverAgent.prototype.removeSocket = function(s, name, host, port) {
+ if (this.sockets[name]) {
+ var index = this.sockets[name].indexOf(s);
+ if (index !== -1) {
+ this.sockets[name].splice(index, 1);
+ }
+ } else if (this.sockets[name] && this.sockets[name].length === 0) {
+ // don't leak
+ delete this.sockets[name];
+ delete this.requests[name];
+ }
+
+ if (this.freeSockets[name]) {
+ var index = this.freeSockets[name].indexOf(s)
+ if (index !== -1) {
+ this.freeSockets[name].splice(index, 1)
+ if (this.freeSockets[name].length === 0) {
+ delete this.freeSockets[name]
+ }
+ }
+ }
+
+ if (this.requests[name] && this.requests[name].length) {
+ // If we have pending requests and a socket gets closed a new one
+ // needs to be created to take over in the pool for the one that closed.
+ this.createSocket(name, host, port).emit('free');
+ }
+}
, mimetypes = require('./mimetypes')
, oauth = require('./oauth')
, uuid = require('./uuid')
+ , ForeverAgent = require('./forever')
, Cookie = require('./vendor/cookie')
, CookieJar = require('./vendor/cookie/jar')
, cookieJar = new CookieJar
;
+
+if (process.logging) {
+ var log = process.logging('request')
+}
try {
https = require('https')
// fetch cookie from the global cookie jar
var cookies = cookieJar.get({ url: self.uri.href })
}
- if (cookies) {self.headers.Cookie = cookies}
+ if (cookies) {
+ var cookieString = cookies.map(function (c) {
+ return c.name + "=" + c.value;
+ }).join("; ");
+
+ self.headers.Cookie = cookieString;
+ }
if (!self.uri.pathname) {self.uri.pathname = '/'}
if (!self.uri.port) {
var clientErrorHandler = function (error) {
if (setHost) delete self.headers.host
+ if (self.req._reusedSocket && error.code === 'ECONNRESET') {
+ self.agent = {addRequest: ForeverAgent.prototype.addRequestNoreuse.bind(self.agent)}
+ self.start()
+ self.req.end()
+ return
+ }
if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer)
self.emit('error', error)
}
}
}
self.headers.authorization =
- 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+encodeURIComponent(oa[i])+'"'}).join(',')
- self.headers.authorization += ',oauth_signature="'+encodeURIComponent(signature)+'"'
+ 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',')
+ self.headers.authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"'
}
if (self.uri.auth && !self.headers.authorization) {
}
} else if (self.multipart) {
- self.body = [];
- self.headers['content-type'] = 'multipart/related;boundary="frontier"'
+ self.body = []
+
+ if (!self.headers['content-type']) {
+ self.headers['content-type'] = 'multipart/related;boundary="frontier"';
+ } else {
+ self.headers['content-type'] = self.headers['content-type'].split(';')[0] + ';boundary="frontier"';
+ }
+
if (!self.multipart.forEach) throw new Error('Argument error, options.multipart.')
self.multipart.forEach(function (part) {
Object.keys(part).forEach(function(key){
preamble += key + ': ' + part[key] + '\r\n'
})
- preamble += '\r\n';
- self.body.push(new Buffer(preamble));
- self.body.push(new Buffer(body));
- self.body.push(new Buffer('\r\n'));
+ preamble += '\r\n'
+ self.body.push(new Buffer(preamble))
+ self.body.push(new Buffer(body))
+ self.body.push(new Buffer('\r\n'))
})
- self.body.push(new Buffer('--frontier--'));
+ self.body.push(new Buffer('--frontier--'))
}
if (self.body) {
- var length = 0;
+ var length = 0
if (!Buffer.isBuffer(self.body)) {
if (Array.isArray(self.body)) {
for (var i = 0; i < self.body.length; i++) {
- length += self.body[i].length;
+ length += self.body[i].length
}
} else {
self.body = new Buffer(self.body)
- length = self.body.length;
+ length = self.body.length
}
} else {
- length = self.body.length;
+ length = self.body.length
}
if (length) {
- self.headers['content-length'] = length;
+ self.headers['content-length'] = length
} else {
throw new Error('Argument error, options.body.')
}
}
- self.httpModule =
- {"http:":http, "https:":https}[self.proxy ? self.proxy.protocol : self.uri.protocol]
+ var protocol = self.proxy ? self.proxy.protocol : self.uri.protocol
+ , defaultModules = {'http:':http, 'https:':https}
+ , httpModules = self.httpModules || {}
+ ;
+ self.httpModule = httpModules[protocol] || defaultModules[protocol]
if (!self.httpModule) throw new Error("Invalid protocol")
} else {
if (self.maxSockets) {
// Don't use our pooling if node has the refactored client
- self.agent = self.httpModule.globalAgent || self.getAgent(self.host, self.port)
+ self.agent = self.agent || self.httpModule.globalAgent || self.getAgent(self.host, self.port)
self.agent.maxSockets = self.maxSockets
}
if (self.pool.maxSockets) {
// Don't use our pooling if node has the refactored client
- self.agent = self.httpModule.globalAgent || self.getAgent(self.host, self.port)
+ self.agent = self.agent || self.httpModule.globalAgent || self.getAgent(self.host, self.port)
self.agent.maxSockets = self.pool.maxSockets
}
}
self.start = function () {
self._started = true
self.method = self.method || 'GET'
-
+ self.href = self.uri.href
+ if (log) log('%method %href', self)
self.req = self.httpModule.request(self, function (response) {
self.response = response
response.request = self
if (setHost) delete self.headers.host
if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer)
+
+ if (response.headers['set-cookie'] && (!self._disableCookies)) {
+ response.headers['set-cookie'].forEach(function(cookie) {
+ if (self.jar) self.jar.add(new Cookie(cookie))
+ else cookieJar.add(new Cookie(cookie))
+ })
+ }
if (response.statusCode >= 300 &&
response.statusCode < 400 &&
response.headers.location = url.resolve(self.uri.href, response.headers.location)
}
self.uri = response.headers.location
- self.redirects.push( { statusCode : response.statusCode,
- redirectUri: response.headers.location })
+ self.redirects.push(
+ { statusCode : response.statusCode
+ , redirectUri: response.headers.location
+ }
+ )
delete self.req
delete self.agent
delete self._started
if (self.headers) {
delete self.headers.host
}
+ if (log) log('Redirect to %uri', self)
request(self, self.callback)
return // Ignore the rest of the response
} else {
chunk.copy(body, i, 0, chunk.length)
i += chunk.length
})
- response.body = body.toString()
+ if (self.encoding === null) {
+ response.body = body
+ } else {
+ response.body = body.toString()
+ }
} else if (buffer.length) {
response.body = buffer.join('')
}
response.body = JSON.parse(response.body)
} catch (e) {}
}
- if (response.statusCode == 200 && response.headers['set-cookie'] && (!self._disableCookies)) {
- response.headers['set-cookie'].forEach(function(cookie) {
- if (self.jar) {
- // custom defined jar
- self.jar.add(new Cookie(cookie));
- } else {
- // add to the global cookie jar if user don't define his own
- cookieJar.add(new Cookie(cookie));
- }
- });
- }
self.callback(null, response, response.body)
})
}
})
- if (self.timeout) {
+ if (self.timeout && !self.timeoutTimer) {
self.timeoutTimer = setTimeout(function() {
- self.req.abort()
- var e = new Error("ETIMEDOUT")
- e.code = "ETIMEDOUT"
- self.emit("error", e)
+ self.req.abort()
+ var e = new Error("ETIMEDOUT")
+ e.code = "ETIMEDOUT"
+ self.emit("error", e)
}, self.timeout)
}
-
+
self.req.on('error', clientErrorHandler)
}
if (self.body) {
if (Array.isArray(self.body)) {
self.body.forEach(function(part) {
- self.write(part);
- });
+ self.write(part)
+ })
} else {
self.write(self.body)
}
return de
}
+request.forever = function (agentOptions, optionsArg) {
+ var options = {}
+ if (agentOptions) {
+ for (option in optionsArg) {
+ options[option] = optionsArg[option]
+ }
+ }
+ options.agent = new ForeverAgent(agentOptions)
+ return request.defaults(options)
+}
+
request.get = request
request.post = function (options, callback) {
if (typeof options === 'string') options = {uri:options}
return crypto.createHmac('sha1', key).update(body).digest('base64')
}
+function rfc3986 (str) {
+ return encodeURIComponent(str)
+ .replace('!','%21')
+ .replace('*','%2A')
+ .replace('(','%28')
+ .replace(')','%29')
+ .replace("'",'%27')
+ ;
+}
+
function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret, body) {
// adapted from https://dev.twitter.com/docs/auth/oauth
var base =
encodeURIComponent( base_uri ) + "&" +
Object.keys(params).sort().map(function (i) {
// big WTF here with the escape + encoding but it's what twitter wants
- return encodeURIComponent(qs.escape(i)) + "%3D" + encodeURIComponent(qs.escape(params[i]))
+ return escape(rfc3986(i)) + "%3D" + escape(rfc3986(params[i]))
}).join("%26")
var key = consumer_secret + '&'
if (token_secret) key += token_secret
return sha1(key, base)
}
-exports.hmacsign = hmacsign
\ No newline at end of file
+exports.hmacsign = hmacsign
+exports.rfc3986 = rfc3986
\ No newline at end of file
{ "name" : "request"
, "description" : "Simplified HTTP request client."
, "tags" : ["http", "simple", "util", "utility"]
-, "version" : "2.2.0"
+, "version" : "2.9.3"
, "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>"
, "repository" :
{ "type" : "git"
this.str = str;
// First key is the name
- this.name = str.substr(0, str.indexOf('='));
+ this.name = str.substr(0, str.indexOf('=')).trim();
// Map the key/val pairs
str.split(/ *; */).reduce(function(obj, pair){
- pair = pair.split(/ *= */);
- obj[pair[0].toLowerCase()] = pair[1] || true;
- return obj;
+ var p = pair.indexOf('=');
+ if(p > 0)
+ obj[pair.substring(0, p).trim()] = pair.substring(p + 1).trim();
+ else
+ obj[pair.trim()] = true;
+ return obj;
}, this);
// Assign value
: Infinity;
// Default or trim path
- this.path = this.path || '/';
+ this.path = this.path
+ ? this.path.trim(): req
+ ? url.parse(req.url).pathname: '/';
};
/**
{"name":"rimraf"
-,"version":"1.0.8"
+,"version":"1.0.9"
,"main":"rimraf.js"
,"description":"A deep deletion module for node (like `rm -rf`)"
,"author":"Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)"
rimraf_(p, opts, function CB (er) {
if (er) {
- if (er.message.match(/^EBUSY/) && busyTries < opts.maxBusyTries) {
+ if (er.code === "EBUSY" && busyTries < opts.maxBusyTries) {
var time = (opts.maxBusyTries - busyTries) * 100
busyTries ++
// try again, with the same exact callback as this one.
}
// this one won't happen if graceful-fs is used.
- if (er.message.match(/^EMFILE/) && timeout < EMFILE_MAX) {
+ if (er.code === "EMFILE" && timeout < EMFILE_MAX) {
return setTimeout(function () {
rimraf_(p, opts, CB)
}, timeout ++)
}
// already gone
- if (er.message.match(/^ENOENT/)) er = null
+ if (er.code === "ENOENT") er = null
}
timeout = 0
// if the stat fails, then assume it's already gone.
if (er) {
// already gone
- if (er.message.match(/^ENOENT/)) return cb()
+ if (er.code === "ENOENT") return cb()
// some other kind of error, permissions, etc.
return cb(er)
}
// this looks simpler, but it will fail with big directory trees,
// or on slow stupid awful cygwin filesystems
function rimrafSync (p) {
- var s = fs[lstatSync](p)
+ try {
+ var s = fs[lstatSync](p)
+ } catch (er) {
+ if (er.code === "ENOENT") return
+ throw er
+ }
if (!s.isDirectory()) return fs.unlinkSync(p)
fs.readdirSync(p).forEach(function (f) {
rimrafSync(path.join(p, f))
{ "name" : "semver"
-, "version" : "1.0.12"
+, "version" : "1.0.13"
, "description" : "The semantic version parser used by npm."
, "main" : "semver.js"
, "scripts" : { "test" : "tap test.js" }
+;(function (exports) { // nothing in here is node-specific.
// See http://semver.org/
// This implementation is a *hair* less strict in that it allows
exports.rangeReplace = ">=$1 <=$7"
exports.clean = clean
exports.compare = compare
+exports.rcompare = rcompare
exports.satisfies = satisfies
exports.gt = gt
exports.gte = gte
return stringify(version)
}
-
+})(typeof exports === "object" ? exports : semver = {})
me.writable = true
me.readable = true
me._stream = new BlockStream(512)
+ me.position = 0
me._stream.on("error", function (e) {
me.emit("error", e)
}
}
+
+ this.position += 512
}
// take a header chunk, start the right kind of entry.
, onend
, meta = false
+ if (null === header.size || !header.cksumValid) {
+ var e = new Error("invalid tar file")
+ e.header = header
+ e.tar_file_offset = this.position
+ e.tar_block = this.position / 512
+ this.emit("error", e)
+ }
+
switch (tar.types[header.type]) {
case "File":
case "OldFile":
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "tar",
"description": "tar for node",
- "version": "0.1.10",
+ "version": "0.1.12",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-tar.git"
},
"main": "tar.js",
"scripts": {
- "test": "rm -rf test/tmp; tap test/*.js"
+ "test": "tap test/*.js"
},
"engines": {
"node": "~0.5.9 || 0.6 || 0.7 || 0.8"
-{ "name": "npm"
-, "publishConfig": { "tag": "alpha", "proprietary-attribs": false }
-, "description": "A package manager for node"
-, "keywords": [ "package manager", "modules", "install", "package.json" ]
-, "version": "1.1.0-beta-10"
-, "preferGlobal": true
-, "config": { "publishtest": false }
-, "homepage": "http://npmjs.org/"
-, "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)"
-, "repository":
- { "type": "git"
- , "url": "https://github.com/isaacs/npm"
- }
-, "bugs":
- { "email": "npm-@googlegroups.com"
- , "url": "http://github.com/isaacs/npm/issues"
- }
-, "directories": { "doc": "./doc"
- , "man": "./man"
- , "lib": "./lib"
- , "bin": "./bin"
- }
-, "main": "./lib/npm.js"
-, "bin": { "npm": "./bin/npm-cli.js"
- , "npm_g": "./bin/npm-cli.js"
- , "npm-g": "./bin/npm-cli.js" }
-
-, "dependencies":
- { "semver": "1"
- , "ini": "1"
- , "slide": "1"
- , "abbrev": "1"
- , "graceful-fs": "~1.1.1"
- , "minimatch": "0"
- , "nopt": "1"
- , "node-uuid": "~1.3"
- , "proto-list": "1"
- , "rimraf": "1"
- , "request": "~2.2"
- , "which": "1"
- , "tar": "~0.1.7"
- , "fstream": "~0.1.5"
- , "block-stream": "*"
- , "inherits": "1"
- , "mkdirp": "0.1"
- , "fast-list": "~1.0.1"
- , "read": "0"
- , "lru-cache": "1"
- }
-
-, "bundleDependencies":
- [ "slide"
- , "ini"
- , "semver"
- , "abbrev"
- , "graceful-fs"
- , "minimatch"
- , "nopt"
- , "node-uuid"
- , "rimraf"
- , "request"
- , "proto-list"
- , "which"
- , "tar"
- , "fstream"
- , "block-stream"
- , "inherits"
- , "mkdirp"
- , "fast-list"
- , "read"
- , "lru-cache"
- ]
-
-, "devDependencies":
- { "ronn": "https://github.com/isaacs/ronnjs/tarball/master" }
-
-, "engines": { "node": "0.6 || 0.7 || 0.8", "npm": "1" }
-, "scripts": { "test": "node ./test/run.js"
- , "prepublish": "make -j4 doc"
- , "dumpconf": "env | grep npm | sort | uniq"
- }
-, "licenses":
- [ { "type": "MIT +no-false-attribs"
- , "url": "http://github.com/isaacs/npm/raw/master/LICENSE"
+{
+ "name": "npm",
+ "publishConfig": {
+ "proprietary-attribs": false
+ },
+ "description": "A package manager for node",
+ "keywords": [
+ "package manager",
+ "modules",
+ "install",
+ "package.json"
+ ],
+ "version": "1.1.0-2",
+ "preferGlobal": true,
+ "config": {
+ "publishtest": false
+ },
+ "homepage": "http://npmjs.org/",
+ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/isaacs/npm"
+ },
+ "bugs": {
+ "email": "npm-@googlegroups.com",
+ "url": "http://github.com/isaacs/npm/issues"
+ },
+ "directories": {
+ "doc": "./doc",
+ "man": "./man",
+ "lib": "./lib",
+ "bin": "./bin"
+ },
+ "main": "./lib/npm.js",
+ "bin": "./bin/npm-cli.js",
+ "dependencies": {
+ "semver": "1",
+ "ini": "1",
+ "slide": "1",
+ "abbrev": "1",
+ "graceful-fs": "~1.1.1",
+ "minimatch": "0",
+ "nopt": "1",
+ "node-uuid": "~1.3",
+ "proto-list": "1",
+ "rimraf": "1",
+ "request": "~2.9",
+ "which": "1",
+ "tar": "~0.1.12",
+ "fstream": "~0.1.5",
+ "block-stream": "*",
+ "inherits": "1",
+ "mkdirp": "0.1",
+ "fast-list": "~1.0.1",
+ "read": "0",
+ "lru-cache": "1"
+ },
+ "bundleDependencies": [
+ "slide",
+ "ini",
+ "semver",
+ "abbrev",
+ "graceful-fs",
+ "minimatch",
+ "nopt",
+ "node-uuid",
+ "rimraf",
+ "request",
+ "proto-list",
+ "which",
+ "tar",
+ "fstream",
+ "block-stream",
+ "inherits",
+ "mkdirp",
+ "fast-list",
+ "read",
+ "lru-cache"
+ ],
+ "devDependencies": {
+ "ronn": "https://github.com/isaacs/ronnjs/tarball/master"
+ },
+ "engines": {
+ "node": "0.6 || 0.7 || 0.8",
+ "npm": "1"
+ },
+ "scripts": {
+ "test": "node ./test/run.js",
+ "prepublish": "npm prune; rm -rf node_modules/*/{test,example,bench}*; make -j4 doc",
+ "dumpconf": "env | grep npm | sort | uniq"
+ },
+ "licenses": [
+ {
+ "type": "MIT +no-false-attribs",
+ "url": "http://github.com/isaacs/npm/raw/master/LICENSE"
}
]
}
set -o pipefail
if ! [ -x node_modules/.bin/ronn ]; then
+ ps=0
if [ -f .building_ronn ]; then
+ pid=$(cat .building_ronn)
+ ps=$(ps -p $pid | grep $pid | wc -l) || true
+ fi
+
+ if [ -f .building_ronn ] && [ $ps != 0 ]; then
while [ -f .building_ronn ]; do
sleep 1
done
echo $$ > .building_ronn
sleep 1
if [ $(cat .building_ronn) == $$ ]; then
- make node_modules/ronn
+ make node_modules/.bin/ronn
rm .building_ronn
else
while [ -f .building_ronn ]; do
--- /dev/null
+{ "name": "npm-test-optional-deps"
+, "version": "1.2.5"
+, "optionalDependencies":
+ { "npm-test-foobarzaaakakaka": "http://example.com/"
+ , "dnode": "10.999.14234"
+ , "sax": "*"
+ , "999 invalid name": "1.2.3"
+ , "glob": "some invalid version 99 #! $$ x y z"
+ }
+}