git clone https://github.com/isaacs/npm.git
cd npm
- git submodule update --init --recursive
sudo make install # (or: `node cli.js install -gf`)
If you're sitting in the code folder reading this document in your
terminal, then you've already got the code. Just do:
- git submodule update --init --recursive
sudo make install
and npm will install itself.
-Note that github tarballs **do not contain submodules**, so
-those won't work. You'll have to also fetch the appropriate submodules
-listed in the .gitmodules file.
-
## Permissions when Using npm to Install Other Stuff
**tl;dr**
A white-space separated list of glob patterns of files to always exclude
from packages when building tarballs.
+### init-module
+
+* Default: ~/.npm-init.js
+* Type: path
+
+A module that will be loaded by the `npm init` command. See the
+documentation for the
+[init-package-json](https://github.com/isaacs/init-package-json) module
+for more information, or npm-init(1).
+
### init.version
* Default: "0.0.0"
## SEE ALSO
+* <https://github.com/isaacs/init-package-json>
* npm-json(1)
* npm-version(1)
<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.26</p>
+<p id="footer">bin — npm@1.1.27</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.26</p>
+<p id="footer">bugs — npm@1.1.27</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.26</p>
+<p id="footer">commands — npm@1.1.27</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.26</p>
+<p id="footer">config — npm@1.1.27</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.26</p>
+<p id="footer">deprecate — npm@1.1.27</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.26</p>
+<p id="footer">docs — npm@1.1.27</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.26</p>
+<p id="footer">edit — npm@1.1.27</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.26</p>
+<p id="footer">explore — npm@1.1.27</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.26</p>
+<p id="footer">help-search — npm@1.1.27</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.26</p>
+<p id="footer">init — npm@1.1.27</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.26</p>
+<p id="footer">install — npm@1.1.27</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.26</p>
+<p id="footer">link — npm@1.1.27</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.26</p>
+<p id="footer">load — npm@1.1.27</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.26</p>
+<p id="footer">ls — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.26</p>
+<p>1.1.27</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.26</p>
+<p id="footer">npm — npm@1.1.27</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.26</p>
+<p id="footer">outdated — npm@1.1.27</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.26</p>
+<p id="footer">owner — npm@1.1.27</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.26</p>
+<p id="footer">pack — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">prefix — npm@1.1.26</p>
+<p id="footer">prefix — npm@1.1.27</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.26</p>
+<p id="footer">prune — npm@1.1.27</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.26</p>
+<p id="footer">publish — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>See <code>npm help build</code></p>
</div>
-<p id="footer">rebuild — npm@1.1.26</p>
+<p id="footer">rebuild — npm@1.1.27</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.26</p>
+<p id="footer">restart — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically.</p>
</div>
-<p id="footer">root — npm@1.1.26</p>
+<p id="footer">root — npm@1.1.27</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.26</p>
+<p id="footer">run-script — npm@1.1.27</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.26</p>
+<p id="footer">search — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when the shrinkwrap has
been saved.</p>
</div>
-<p id="footer">shrinkwrap — npm@1.1.26</p>
+<p id="footer">shrinkwrap — npm@1.1.27</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.26</p>
+<p id="footer">start — npm@1.1.27</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.26</p>
+<p id="footer">stop — npm@1.1.27</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.26</p>
+<p id="footer">submodule — npm@1.1.27</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.26</p>
+<p id="footer">tag — npm@1.1.27</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.26</p>
+<p id="footer">test — npm@1.1.27</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.26</p>
+<p id="footer">uninstall — npm@1.1.27</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.26</p>
+<p id="footer">unpublish — npm@1.1.27</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.26</p>
+<p id="footer">update — npm@1.1.27</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.26</p>
+<p id="footer">version — npm@1.1.27</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.26</p>
+<p id="footer">view — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">whoami — npm@1.1.26</p>
+<p id="footer">whoami — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<pre><code>git clone https://github.com/isaacs/npm.git
cd npm
-git submodule update --init --recursive
sudo make install # (or: `node cli.js install -gf`)</code></pre>
<p>If you're sitting in the code folder reading this document in your
terminal, then you've already got the code. Just do:</p>
-<pre><code>git submodule update --init --recursive
-sudo make install</code></pre>
+<pre><code>sudo make install</code></pre>
<p>and npm will install itself.</p>
-<p>Note that github tarballs <strong>do not contain submodules</strong>, so
-those won't work. You'll have to also fetch the appropriate submodules
-listed in the .gitmodules file.</p>
-
<h2 id="Permissions-when-Using-npm-to-Install-Other-Stuff">Permissions when Using npm to Install Other Stuff</h2>
<p><strong>tl;dr</strong></p>
<ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.26</p>
+<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.27</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.26</p>
+<p id="footer">adduser — npm@1.1.27</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.26</p>
+<p id="footer">bin — npm@1.1.27</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.26</p>
+<p id="footer">bugs — npm@1.1.27</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.26</p>
+<p id="footer">build — npm@1.1.27</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.26</p>
+<p id="footer">bundle — npm@1.1.27</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.26</p>
+<p id="footer">cache — npm@1.1.27</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.26</p>
+<p id="footer">changelog — npm@1.1.27</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.26</p>
+<p id="footer">coding-style — npm@1.1.27</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.26</p>
+<p id="footer">completion — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>A white-space separated list of glob patterns of files to always exclude
from packages when building tarballs.</p>
+<h3 id="init-module">init-module</h3>
+
+<ul><li>Default: ~/.npm-init.js</li><li>Type: path</li></ul>
+
+<p>A module that will be loaded by the <code>npm init</code> command. See the
+documentation for the
+<a href="https://github.com/isaacs/init-package-json">init-package-json</a> module
+for more information, or <a href="../doc/init.html">init(1)</a>.</p>
+
<h3 id="init-version">init.version</h3>
<ul><li>Default: "0.0.0"</li><li>Type: semver</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.26</p>
+<p id="footer">config — npm@1.1.27</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.26</p>
+<p id="footer">deprecate — npm@1.1.27</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.26</p>
+<p id="footer">developers — npm@1.1.27</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.26</p>
+<p id="footer">disputes — npm@1.1.27</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.26</p>
+<p id="footer">docs — npm@1.1.27</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.26</p>
+<p id="footer">edit — npm@1.1.27</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.26</p>
+<p id="footer">explore — npm@1.1.27</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.26</p>
+<p id="footer">faq — npm@1.1.27</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.26</p>
+<p id="footer">folders — npm@1.1.27</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.26</p>
+<p id="footer">help-search — npm@1.1.27</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.26</p>
+<p id="footer">help — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p> Display npm username</p>
</div>
-<p id="footer">index — npm@1.1.26</p>
+<p id="footer">index — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="SEE-ALSO">SEE ALSO</h2>
-<ul><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
+<ul><li><a href="https://github.com/isaacs/init-package-json">https://github.com/isaacs/init-package-json</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
</div>
-<p id="footer">init — npm@1.1.26</p>
+<p id="footer">init — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></li></ul>
</div>
-<p id="footer">install — npm@1.1.26</p>
+<p id="footer">install — npm@1.1.27</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.26</p>
+<p id="footer">json — npm@1.1.27</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.26</p>
+<p id="footer">link — npm@1.1.27</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.26</p>
+<p id="footer">list — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.26</p>
+<p>1.1.27</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.26</p>
+<p id="footer">npm — npm@1.1.27</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.26</p>
+<p id="footer">outdated — npm@1.1.27</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.26</p>
+<p id="footer">owner — npm@1.1.27</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.26</p>
+<p id="footer">pack — npm@1.1.27</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.26</p>
+<p id="footer">prefix — npm@1.1.27</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.26</p>
+<p id="footer">prune — npm@1.1.27</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.26</p>
+<p id="footer">publish — npm@1.1.27</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.26</p>
+<p id="footer">rebuild — npm@1.1.27</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.26</p>
+<p id="footer">registry — npm@1.1.27</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.26</p>
+<p id="footer">removing-npm — npm@1.1.27</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.26</p>
+<p id="footer">restart — npm@1.1.27</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.26</p>
+<p id="footer">root — npm@1.1.27</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.26</p>
+<p id="footer">run-script — npm@1.1.27</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.26</p>
+<p id="footer">scripts — npm@1.1.27</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.26</p>
+<p id="footer">search — npm@1.1.27</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.26</p>
+<p id="footer">semver — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
-<p id="footer">shrinkwrap — npm@1.1.26</p>
+<p id="footer">shrinkwrap — npm@1.1.27</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.26</p>
+<p id="footer">star — npm@1.1.27</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.26</p>
+<p id="footer">start — npm@1.1.27</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.26</p>
+<p id="footer">stop — npm@1.1.27</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.26</p>
+<p id="footer">submodule — npm@1.1.27</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.26</p>
+<p id="footer">tag — npm@1.1.27</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.26</p>
+<p id="footer">test — npm@1.1.27</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.26</p>
+<p id="footer">uninstall — npm@1.1.27</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.26</p>
+<p id="footer">unpublish — npm@1.1.27</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.26</p>
+<p id="footer">update — npm@1.1.27</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.26</p>
+<p id="footer">version — npm@1.1.27</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.26</p>
+<p id="footer">view — npm@1.1.27</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.26</p>
+<p id="footer">whoami — npm@1.1.27</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
, npm = require("./npm.js")
, registry = npm.registry
, read = require("read")
- , promiseChain = require("./utils/promise-chain.js")
, crypto
try {
if (!crypto) return cb(new Error(
"You must compile node with ssl support to use the adduser feature"))
- var u = { u : npm.config.get("username")
+ var c = { u : npm.config.get("username")
, p : npm.config.get("_password")
, e : npm.config.get("email")
}
, changed = false
+ , u = {}
+ , fns = [readUsername, readPassword, readEmail, save]
- promiseChain(cb)
- (read, [{prompt: "Username: ", default: u.u}], function (un) {
- changed = u.u !== un
- u.u = un
- })
- (function (cb) {
- if (u.p && !changed) return cb(null, u.p)
- read({prompt: "Password: ", default: u.p, silent: true}, cb)
- }, [], function (pw) { u.p = pw })
- (read, [{prompt: "Email: ", default: u.e}], function (em) { u.e = em })
- (function (cb) {
- if (changed) npm.config.del("_auth")
- registry.adduser(u.u, u.p, u.e, function (er) {
- if (er) return cb(er)
- registry.username = u.u
- registry.password = u.p
- registry.email = u.e
- ini.set("username", u.u, "user")
- ini.set("_password", u.p, "user")
- ini.set("email", u.e, "user")
- log.info("adduser", "Authorized user %s", u.u)
- ini.save("user", cb)
- })
- })
- ()
+ loop()
+ function loop (er) {
+ if (er) return cb(er)
+ var fn = fns.shift()
+ if (fn) return fn(c, u, loop)
+ cb()
+ }
+}
+
+function readUsername (c, u, cb) {
+ read({prompt: "Username: ", default: c.u}, function (er, un) {
+ c.changed = c.u !== un
+ u.u = un
+ cb(er)
+ })
+}
+
+function readPassword (c, u, cb) {
+ if (!c.changed) {
+ u.p = c.p
+ return cb()
+ }
+ read({prompt: "Password: ", silent: true}, function (er, pw) {
+ u.p = pw
+ cb(er)
+ })
+}
+
+function readEmail (c, u, cb) {
+ read({prompt: "Email: ", default: c.e}, function (er, em) {
+ u.e = em
+ cb(er)
+ })
+}
+
+function save (c, u, cb) {
+ if (c.changed) {
+ delete registry.auth
+ delete registry.username
+ delete registry.password
+ registry.username = u.u
+ registry.password = u.p
+ }
+
+ // save existing configs, but yank off for this PUT
+ registry.adduser(u.u, u.p, u.e, function (er) {
+ if (er) return cb(er)
+ registry.username = u.u
+ registry.password = u.p
+ registry.email = u.e
+ ini.set("username", u.u, "user")
+ ini.set("_password", u.p, "user")
+ ini.set("email", u.e, "user")
+ log.info("adduser", "Authorized user %s", u.u)
+ ini.save("user", cb)
+ })
}
module.exports = init
-var read = require("read")
- , path = require("path")
- , fs = require("graceful-fs")
- , promiseChain = require("./utils/promise-chain.js")
- , exec = require("./utils/exec.js")
- , semver = require("semver")
- , log = require("npmlog")
+var log = require("npmlog")
, npm = require("./npm.js")
- , output = require("./utils/output.js")
+ , initJson = require("init-package-json")
-init.usage = "npm init [folder]"
+init.usage = "npm init"
function init (args, cb) {
- var folder = args[0] || "."
+ var dir = process.cwd()
log.pause()
- if (folder.charAt(0) !== "/") folder = path.join(process.cwd(), folder)
+ var initFile = npm.config.get('init-module')
- fs.readFile(path.join(folder, "package.json"), "utf8", function (er, data) {
- if (er) data = {}
- else try {
- data = JSON.parse(data)
- } catch (_) {
- data = {}
- }
-
- if (data.author) data.author = parseAuthor(data.author)
-
- data.author = data.author ||
- { name: npm.config.get("init.author.name")
- , email: npm.config.get("init.author.email")
- , url: npm.config.get("init.author.url") }
-
- init_(data, folder, function (er) {
- log.resume()
- if (!er) log.info("written", path.resolve(folder, "package.json"))
- cb(er)
- })
- })
-}
-
-function init_ (data, folder, cb) {
- var nv = npm.config.get("node-version")
- , p = semver.parse(nv)
- , eng = ""
-
- if (!p[5]) eng = "~" + nv
- else eng = "~" + [p[1], p[2], p[3]].join(".") + " || " + nv
-
- // node version 0.n is api-compatible with 0.(n+1) when n is odd.
- if (p[2] % 2) {
- eng += " || " + [p[1], +(p[2]) + 1].join(".")
- }
-
-
- output.write(
+ console.log(
["This utility will walk you through creating a package.json file."
,"It only covers the most common items, and tries to guess sane defaults."
,""
,"save it as a dependency in the package.json file."
,""
,"Press ^C at any time to quit."
- ,""
].join("\n"))
- promiseChain(cb)
- ( read
- , [{prompt: "Package name: ", default: defaultName(folder, data)}]
- , function (n) { data.name = n }
- )
- ( read
- , [{prompt: "Description: ", default: data.description}]
- , function (d) { data.description = d }
- )
- ( defaultVersion, [folder, data], function (v) { data.version = v } )
- (function (cb) {
- read( { prompt: "Package version: ", default: data.version }
- , function (er, v) {
- if (er) return cb(er)
- data.version = v
- cb()
- })
- }, [])
- ( read
- , [ { prompt: "Project homepage: "
- , default: data.homepage || data.url || "none" } ]
- , function (u) {
- if (u === "none") return
- data.homepage = u
- delete data.url
- }
- )
- ( defaultRepo, [folder, data], function (r) { data.repository = r } )
- (function (cb) {
- read( { prompt: "Project git repository: "
- , default: data.repository && data.repository.url || "none" }
- , function (er, r) {
- if (er) return cb(er)
- if (r !== "none") {
- data.repository = (data.repository || {})
- data.repository.url = r
- } else {
- delete data.repository
- }
- cb()
- }
- )
- }, [])
- ( read
- , [{ prompt: "Author name: ", default: data.author && data.author.name }]
- , function (n) {
- if (!n) return
- (data.author = data.author || {}).name = n
- }
- )
- ( read
- , [ { prompt: "Author email: "
- , default: data.author && data.author.email || "none" } ]
- , function (n) {
- if (n === "none") return
- (data.author = data.author || {}).email = n
- }
- )
- ( read
- , [ { prompt: "Author url: "
- , default: data.author && data.author.url || "none" } ]
- , function (n) {
- if (n === "none") return
- (data.author = data.author || {}).url = n
- }
- )
- ( read
- , [ { prompt: "Main module/entry point: ", default: data.main || "none" } ]
- , function (m) {
- if (m === "none") {
- delete data.main
- return
- }
- data.main = m
- }
- )
- ( read
- , [ { prompt: "Test command: "
- , default: data.scripts && data.scripts.test || "none" } ]
- , function (t) {
- if (t === "none") return
- (data.scripts = data.scripts || {}).test = t
- }
- )
- (cleanupPaths, [data, folder])
- (function (cb) {
- if (data.author) data.author = unparseAuthor(data.author)
-
- var str = JSON.stringify(data, null, 2)
- , msg = "About to write to "
- + path.join(folder, "package.json")
- + "\n\n"
- + str
- + "\n\n"
- output.write(msg, cb)
- })
- (function (cb) {
- read({ prompt: "\nIs this ok? ", default: "yes" }, function (er, ok) {
- if (er) return cb(er)
- if (ok.toLowerCase().charAt(0) !== "y") {
- return cb(new Error("cancelled"))
- }
- return cb()
- })
- })
- (function (cb) {
- fs.writeFile( path.join(folder, "package.json")
- , JSON.stringify(data, null, 2) + "\n"
- , cb )
- })
- ()
-}
-// sync - no io
-function defaultName (folder, data) {
- if (data.name) return data.name
- return path.basename(folder)
- .replace(/^node[-\._]?|([-\._]node)[-\._]?(js)?$/g, "")
-}
-
-function defaultVersion (folder, data, cb) {
- if (data.version) return cb(null, data.version)
- 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)
- out = npm.config.get("init.version")
- if (semver.valid(out)) return cb(null, out)
- return cb(null, "0.0.0")
+ initJson(dir, initFile, npm.config.get(), function (er, data) {
+ log.resume()
+ log.silly('package data', data)
+ log.info('init', 'written successfully')
+ cb(er, data)
})
}
-
-function defaultRepo (folder, data, cb) {
- if (data.repository) return cb(null, data.repository)
- exec( npm.config.get("git"), ["remote", "-v"], process.env, false, folder
- , function (er, code, out) {
- out = (out || "")
- .trim()
- .split("\n").filter(function (line) {
- return line.search(/^origin/) !== -1
- })[0]
- if (!out) return cb(null, {})
- var repo =
- { type: "git"
- , url: out.split(/\s/)[1]
- .replace("git@github.com:", "git://github.com/")
- }
- return cb(null, repo)
- })
-}
-
-function cleanupPaths (data, folder, cb) {
- if (data.main) {
- data.main = cleanupPath(data.main, folder)
- }
- var dirs = data.directories
- if (dirs) {
- Object.keys(dirs).forEach(function (dir) {
- dirs[dir] = cleanupPath(dirs[dir], folder)
- })
- }
- cb()
-}
-
-function cleanupPath (m, folder) {
- if (m.indexOf(folder) === 0) m = path.join(".", m.substr(folder.length))
- return m
-}
-
-function parseAuthor (person) {
- if (typeof person !== "string") return person
- var name = person.match(/^([^\(<]+)/)
- var url = person.match(/\(([^\)]+)\)/)
- var email = person.match(/<([^>]+)>/)
- var obj = {}
- if (name && name[0].trim()) obj.name = name[0].trim()
- if (email) obj.email = email[1];
- if (url) obj.url = url[1];
- return obj
-}
-
-function unparseAuthor (a) {
- if (!a) return ""
- if (typeof a === "string") return a
- var s = a.name
- if (a.email) s += " <" + a.email + ">"
- if (a.url) s += " (" + a.url + ")"
- return s
-}
if (er || silent) return cb_(er)
var outList = list.map(makePretty)
- require("./utils/output.js").write(outList.join("\n"), cb_)
+ require("./utils/output.js").write(outList.join("\n"))
+ cb_()
})
}
var deps = null
readJson(path.resolve(dir, "package.json"), function (er, d) {
- deps = (er) ? true : d.dependencies
+ deps = (er) ? true : (d.dependencies || {})
return next()
})
pvs.forEach(function (pv) {
has[pv[0]] = pv[1]
})
+
next()
})
})
return l
}, {})
}
+
// now get what we should have, based on the dep.
// if has[dep] !== shouldHave[dep], then cb with the data
// otherwise dive into the folder
, group : process.platform === "win32" ? 0
: process.env.SUDO_GID || (process.getgid && process.getgid())
, ignore: ""
+ , "init-module": path.resolve(home, '.npm-init.js')
, "init.version" : "0.0.0"
, "init.author.name" : ""
, "init.author.email" : ""
, "https-proxy" : [null, url]
, "user-agent" : String
, ignore : String
+ , "init-module": path
, "init.version" : [null, semver]
, "init.author.name" : String
, "init.author.email" : String
+++ /dev/null
-
-module.exports = promiseChain
-
-// usage:
-//
-// promiseChain(cb) <-- this is the callback for eventual success or error
-// ( fn, [arg, arg, arg], function (a,b,c) { success(a,b,c) })
-// ( fn2, [args] )
-// () <-- this kicks it off.
-//
-// promiseChain.call(someObj, cb) <-- bind this-context for all functions
-
-function promiseChain (cb) {
- var steps = []
- , vals = []
- , context = this
- function go () {
- var step = steps.shift()
- if (!step) return cb()
- try { step[0].apply(context, step[1]) }
- catch (ex) { cb(ex) }
- }
- return function pc (fn, args, success) {
- if (arguments.length === 0) return go()
- // add the step
- steps.push
- ( [ fn
- , (args || []).concat([ function (er) {
- if (er) return cb(er)
- var a = Array.prototype.slice.call(arguments, 1)
- try { success && success.apply(context, a) }
- catch (ex) { return cb(ex) }
- go()
- }])
- ]
- )
- return pc
- }
-}
.nf
git clone https://github\.com/isaacs/npm\.git
cd npm
-git submodule update \-\-init \-\-recursive
sudo make install # (or: `node cli\.js install \-gf`)
.
.fi
.IP "" 4
.
.nf
-git submodule update \-\-init \-\-recursive
sudo make install
.
.fi
.P
and npm will install itself\.
.
-.P
-Note that github tarballs \fBdo not contain submodules\fR, so
-those won\'t work\. You\'ll have to also fetch the appropriate submodules
-listed in the \.gitmodules file\.
-.
.SH "Permissions when Using npm to Install Other Stuff"
\fBtl;dr\fR
.
A white\-space separated list of glob patterns of files to always exclude
from packages when building tarballs\.
.
+.SS "init\-module"
+.
+.IP "\(bu" 4
+Default: ~/\.npm\-init\.js
+.
+.IP "\(bu" 4
+Type: path
+.
+.IP "" 0
+.
+.P
+A module that will be loaded by the \fBnpm init\fR command\. See the
+documentation for the init\-package\-json \fIhttps://github\.com/isaacs/init\-package\-json\fR module
+for more information, or npm help init\.
+.
.SS "init\.version"
.
.IP "\(bu" 4
.SH "SEE ALSO"
.
.IP "\(bu" 4
+\fIhttps://github\.com/isaacs/init\-package\-json\fR
+.
+.IP "\(bu" 4
npm help json
.
.IP "\(bu" 4
.fi
.
.SH "VERSION"
-1.1.26
+1.1.27
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
.fi
.
.SH "VERSION"
-1.1.26
+1.1.27
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
--- /dev/null
+# init-package-json
+
+A node module to get your node module started.
+
+## Usage
+
+```javascript
+var init = require('init-package-json')
+var path = require('path')
+
+// a path to a promzard module. In the event that this file is
+// not found, one will be provided for you.
+var initFile = path.resolve(process.env.HOME, '.npm-init')
+
+// the dir where we're doin stuff.
+var dir = process.cwd()
+
+// extra stuff that gets put into the PromZard module's context.
+// In npm, this is the resolved config object. Exposed as 'config'
+// Optional.
+var configData = { some: 'extra stuff' }
+
+// Any existing stuff from the package.json file is also exposed in the
+// PromZard module as the `package` object. There will also be free
+// vars for:
+// * `filename` path to the package.json file
+// * `basename` the tip of the package dir
+// * `dirname` the parent of the package dir
+
+init(dir, initFile, configData, function (er, data) {
+ // the data's already been written to {dir}/package.json
+ // now you can do stuff with it
+})
+```
+
+Or from the command line:
+
+```
+$ npm-init
+```
+
+See [PromZard](https://github.com/isaacs/promzard) for details about
+what can go in the config file.
--- /dev/null
+var fs = require('fs')
+var path = require('path')
+var glob = require('glob')
+
+// more popular packages should go here, maybe?
+function isTestPkg (p) {
+ return !!p.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/)
+}
+
+function niceName (n) {
+ return n.replace(/^node-|[.-]js$/g, '')
+}
+
+function readDeps (test) { return function (cb) {
+ fs.readdir('node_modules', function (er, dir) {
+ if (er) return cb()
+ var deps = {}
+ var n = dir.length
+ dir.forEach(function (d) {
+ if (d.match(/^\./)) return next()
+ if (test !== isTestPkg(d))
+ return next()
+
+ var dp = path.join(dirname, 'node_modules', d, 'package.json')
+ fs.readFile(dp, 'utf8', function (er, p) {
+ if (er) return next()
+ try { p = JSON.parse(p) }
+ catch (e) { return next() }
+ if (!p.version) return next()
+ deps[d] = '~' + p.version
+ return next()
+ })
+ })
+ function next () {
+ if (--n === 0) return cb(null, deps)
+ }
+ })
+}}
+
+
+exports.name = prompt('name', package.name || basename)
+exports.version = prompt('version', package.version || '0.0.0')
+
+if (!package.main) {
+ exports.main = function (cb) {
+ fs.readdir(dirname, function (er, f) {
+ if (er) f = []
+
+ f = f.filter(function (f) {
+ return f.match(/\.js$/)
+ })
+
+ if (f.indexOf('index.js') !== -1)
+ f = 'index.js'
+ else if (f.indexOf('main.js') !== -1)
+ f = 'main.js'
+ else if (f.indexOf(basename + '.js') !== -1)
+ f = basename + '.js'
+ else
+ f = f[0]
+
+ return cb(null, prompt('entry point', f || 'index.js'))
+ })
+ }
+}
+
+if (!package.bin) {
+ exports.bin = function (cb) {
+ fs.readdir(path.resolve(dirname, 'bin'), function (er, d) {
+ // no bins
+ if (er) return cb()
+ // just take the first js file we find there, or nada
+ return cb(null, d.filter(function (f) {
+ return f.match(/\.js$/)
+ })[0])
+ })
+ }
+}
+
+exports.directories = function (cb) {
+ fs.readdir(dirname, function (er, dirs) {
+ if (er) return cb(er)
+ var res = {}
+ dirs.forEach(function (d) {
+ switch (d) {
+ case 'example': case 'examples': return res.example = d
+ case 'test': case 'tests': return res.test = d
+ case 'doc': case 'docs': return res.doc = d
+ case 'man': return res.man = d
+ }
+ })
+ if (Object.keys(res).length === 0) res = undefined
+ return cb(null, res)
+ })
+}
+
+if (!package.dependencies) {
+ exports.dependencies = readDeps(false)
+}
+
+if (!package.devDependencies) {
+ exports.devDependencies = readDeps(true)
+}
+
+// MUST have a test script!
+var s = package.scripts || {}
+var notest = 'echo "Error: no test specified" && exit 1'
+if (!package.scripts) {
+ exports.scripts = function (cb) {
+ fs.readdir(path.join(dirname, 'node_modules'), function (er, d) {
+ setupScripts(d || [], cb)
+ })
+ }
+}
+function setupScripts (d, cb) {
+ // check to see what framework is in use, if any
+ function tx (test) {
+ return test || notest
+ }
+
+ if (!s.test || s.test === notest) {
+ if (d.indexOf('tap') !== -1)
+ s.test = prompt('test command', 'tap test/*.js', tx)
+ else if (d.indexOf('expresso') !== -1)
+ s.test = prompt('test command', 'expresso test', tx)
+ else if (d.indexOf('mocha') !== -1)
+ s.test = prompt('test command', 'mocha', tx)
+ else
+ s.test = prompt('test command', tx)
+ }
+
+ return cb(null, s)
+}
+
+if (!package.repository) {
+ exports.repository = function (cb) {
+ fs.readFile('.git/config', 'utf8', function (er, gconf) {
+ if (er || !gconf) return cb(null, prompt('git repository'))
+
+ gconf = gconf.split(/\r?\n/)
+ var i = gconf.indexOf('[remote "origin"]')
+ if (i !== -1) {
+ var u = gconf[i + 1]
+ if (!u.match(/^\s*url =/)) u = gconf[i + 2]
+ if (!u.match(/^\s*url =/)) u = null
+ else u = u.replace(/^\s*url = /, '')
+ }
+ if (u && u.match(/^git@github.com:/))
+ u = u.replace(/^git@github.com:/, 'git://github.com/')
+
+ return cb(null, prompt('git repository', u))
+ })
+ }
+}
+
+if (!package.keywords) {
+ exports.keywords = prompt('keywords', function (s) {
+ if (!s) return undefined
+ if (Array.isArray(s)) s = s.join(' ')
+ if (typeof s !== 'string') return s
+ return s.split(/[\s,]+/)
+ })
+}
+
+if (!package.author) {
+ exports.author = config['init.author.name']
+ ? {
+ "name" : config['init.author.name'],
+ "email" : config['init.author.email'],
+ "url" : config['init.author.url']
+ }
+ : prompt('author')
+}
+
+exports.license = prompt('license', 'BSD')
--- /dev/null
+
+module.exports = init
+
+var PZ = require('promzard').PromZard
+var path = require('path')
+var def = require.resolve('./default-input.js')
+
+var fs = require('fs')
+var semver = require('semver')
+var read = require('read')
+
+// to validate the data object at the end as a worthwhile package
+// and assign default values for things.
+// readJson.extras(file, data, cb)
+var readJson = require('read-package-json')
+
+function init (dir, input, config, cb) {
+ if (typeof config === 'function')
+ cb = config, config = {}
+ var package = path.resolve(dir, 'package.json')
+ input = path.resolve(input)
+ var pkg
+ var ctx = {}
+
+ var es = readJson.extraSet
+ readJson.extraSet = es.filter(function (fn) {
+ return fn.name !== 'authors' && fn.name !== 'mans'
+ })
+ readJson(package, function (er, d) {
+ readJson.extraSet = es
+
+ if (er) pkg = {}
+ else pkg = d
+
+ ctx.filename = package
+ ctx.dirname = path.dirname(package)
+ ctx.basename = path.basename(ctx.dirname)
+ if (!pkg.version || !semver.valid(pkg.version))
+ delete pkg.version
+
+ ctx.package = pkg
+ ctx.config = config || {}
+
+ // make sure that the input is valid.
+ // if not, use the default
+ var pz = new PZ(input, ctx)
+ pz.backupFile = def
+ pz.on('error', cb)
+ pz.on('data', function (data) {
+ Object.keys(data).forEach(function (k) {
+ if (data[k] !== undefined && data[k] !== null) pkg[k] = data[k]
+ })
+
+ // only do a few of these.
+ // no need for mans or contributors if they're in the files
+ var es = readJson.extraSet
+ readJson.extraSet = es.filter(function (fn) {
+ return fn.name !== 'authors' && fn.name !== 'mans'
+ })
+ readJson.extras(package, pkg, function (er, pkg) {
+ readJson.extraSet = es
+ if (er) return cb(er, pkg)
+ pkg = unParsePeople(pkg)
+ // no need for the readme now.
+ delete pkg.readme
+ // really don't want to have this lying around in the file
+ delete pkg._id
+ var d = JSON.stringify(pkg, null, 2) + '\n'
+ console.log('About to write to %s:\n\n%s\n', package, d)
+ read({prompt:'Is this ok? ', default: 'yes'}, function (er, ok) {
+ if (!ok || ok.toLowerCase().charAt(0) !== 'y') {
+ console.log('Aborted.')
+ } else {
+ fs.writeFile(package, d, 'utf8', function (er) {
+ return cb(er, pkg)
+ })
+ }
+ })
+ })
+ })
+ })
+
+}
+
+// turn the objects into somewhat more humane strings.
+function unParsePeople (data) {
+ if (data.author) data.author = unParsePerson(data.author)
+ ;["maintainers", "contributors"].forEach(function (set) {
+ if (!Array.isArray(data[set])) return;
+ data[set] = data[set].map(unParsePerson)
+ })
+ return data
+}
+
+function unParsePerson (person) {
+ if (typeof person === "string") return person
+ var name = person.name || ""
+ var u = person.url || person.web
+ var url = u ? (" ("+u+")") : ""
+ var e = person.email || person.mail
+ var email = e ? (" <"+e+">") : ""
+ return name+email+url
+}
+
--- /dev/null
+example/npm-init/package.json
--- /dev/null
+# promzard
+
+A reimplementation of @SubStack's
+[prompter](https://github.com/substack/node-prompter), which does not
+use AST traversal.
+
+From another point of view, it's a reimplementation of
+[@Marak](https://github.com/marak)'s
+[wizard](https://github.com/Marak/wizard) which doesn't use schemas.
+
+The goal is a nice drop-in enhancement for `npm init`.
+
+## Usage
+
+```javascript
+var promzard = require('promzard')
+promzard(inputFile, optionalContextAdditions, function (er, data) {
+ // .. you know what you doing ..
+})
+```
+
+In the `inputFile` you can have something like this:
+
+```javascript
+var fs = require('fs')
+module.exports = {
+ "greeting": prompt("Who shall you greet?", "world", function (who) {
+ return "Hello, " + who
+ }),
+ "filename": __filename,
+ "directory": function (cb) {
+ fs.readdir(__dirname, cb)
+ }
+}
+```
+
+When run, promzard will display the prompts and resolve the async
+functions in order, and then either give you an error, or the resolved
+data, ready to be dropped into a JSON file or some other place.
+
+
+### promzard(inputFile, ctx, callback)
+
+The inputFile is just a node module. You can require() things, set
+module.exports, etc. Whatever that module exports is the result, and it
+is walked over to call any functions as described below.
+
+The only caveat is that you must give PromZard the full absolute path
+to the module (you can get this via Node's `require.resolve`.) Also,
+the `prompt` function is injected into the context object, so watch out.
+
+Whatever you put in that `ctx` will of course also be available in the
+module. You can get quite fancy with this, passing in existing configs
+and so on.
+
+### Class: promzard.PromZard(file, ctx)
+
+Just like the `promzard` function, but the EventEmitter that makes it
+all happen. Emits either a `data` event with the data, or a `error`
+event if it blows up.
+
+If `error` is emitted, then `data` never will be.
+
+### prompt(...)
+
+In the promzard input module, you can call the `prompt` function.
+This prompts the user to input some data. The arguments are interpreted
+based on type:
+
+1. `string` The first string encountered is the prompt. The second is
+ the default value.
+2. `function` A transformer function which receives the data and returns
+ something else. More than meets the eye.
+3. `object` The `prompt` member is the prompt, the `default` member is
+ the default value, and the `transform` is the transformer.
+
+Whatever the final value is, that's what will be put on the resulting
+object.
+
+### Functions
+
+If there are any functions on the promzard input module's exports, then
+promzard will call each of them with a callback. This way, your module
+can do asynchronous actions if necessary to validate or ascertain
+whatever needs verification.
+
+The functions are called in the context of the ctx object, and are given
+a single argument, which is a callback that should be called with either
+an error, or the result to assign to that spot.
+
+In the async function, you can also call prompt() and return the result
+of the prompt in the callback.
+
+For example, this works fine in a promzard module:
+
+```
+exports.asyncPrompt = function (cb) {
+ fs.stat(someFile, function (er, st) {
+ // if there's an error, no prompt, just error
+ // otherwise prompt and use the actual file size as the default
+ cb(er, prompt('file size', st.size))
+ })
+}
+```
+
+You can also return other async functions in the async function
+callback. Though that's a bit silly, it could be a handy way to reuse
+functionality in some cases.
+
+### Sync vs Async
+
+The `prompt()` function is not synchronous, though it appears that way.
+It just returns a token that is swapped out when the data object is
+walked over asynchronously later, and returns a token.
+
+For that reason, prompt() calls whose results don't end up on the data
+object are never shown to the user. For example, this will only prompt
+once:
+
+```
+exports.promptThreeTimes = prompt('prompt me once', 'shame on you')
+exports.promptThreeTimes = prompt('prompt me twice', 'um....')
+exports.promptThreeTimes = prompt('you cant prompt me again')
+```
+
+### Isn't this exactly the sort of 'looks sync' that you said was bad about other libraries?
+
+Yeah, sorta. I wouldn't use promzard for anything more complicated than
+a wizard that spits out prompts to set up a config file or something.
+Maybe there are other use cases I haven't considered.
--- /dev/null
+var pz = require('../promzard')
+
+var path = require('path')
+var file = path.resolve(__dirname, 'substack-input.js')
+var ctx = { basename: path.basename(path.dirname(file)) }
+
+pz(file, ctx, function (er, res) {
+ if (er)
+ throw er
+ console.error(JSON.stringify(res, null, 2))
+})
--- /dev/null
+# npm-init
+
+An initter you init wit, innit?
+
+## More stuff here
+
+Blerp derp herp lerg borgle pop munch efemerate baz foo a gandt synergy
+jorka chatt slurm.
--- /dev/null
+var fs = require('fs')
+var path = require('path');
+
+module.exports = {
+ "name" : prompt('name',
+ typeof name === 'undefined'
+ ? basename.replace(/^node-|[.-]js$/g, ''): name),
+ "version" : prompt('version', typeof version !== "undefined"
+ ? version : '0.0.0'),
+ "description" : (function () {
+ if (typeof description !== 'undefined' && description) {
+ return description
+ }
+ var value;
+ try {
+ var src = fs.readFileSync('README.md', 'utf8');
+ value = src.split('\n').filter(function (line) {
+ return /\s+/.test(line)
+ && line.trim() !== basename.replace(/^node-/, '')
+ && !line.trim().match(/^#/)
+ ;
+ })[0]
+ .trim()
+ .replace(/^./, function (c) { return c.toLowerCase() })
+ .replace(/\.$/, '')
+ ;
+ }
+ catch (e) {
+ try {
+ // Wouldn't it be nice if that file mattered?
+ var d = fs.readFileSync('.git/description', 'utf8')
+ } catch (e) {}
+ if (d.trim() && !value) value = d
+ }
+ return prompt('description', value);
+ })(),
+ "main" : (function () {
+ var f
+ try {
+ f = fs.readdirSync(dirname).filter(function (f) {
+ return f.match(/\.js$/)
+ })
+ if (f.indexOf('index.js') !== -1)
+ f = 'index.js'
+ else if (f.indexOf('main.js') !== -1)
+ f = 'main.js'
+ else if (f.indexOf(basename + '.js') !== -1)
+ f = basename + '.js'
+ else
+ f = f[0]
+ } catch (e) {}
+
+ return prompt('entry point', f || 'index.js')
+ })(),
+ "bin" : function (cb) {
+ fs.readdir(dirname + '/bin', function (er, d) {
+ // no bins
+ if (er) return cb()
+ // just take the first js file we find there, or nada
+ return cb(null, d.filter(function (f) {
+ return f.match(/\.js$/)
+ })[0])
+ })
+ },
+ "directories" : function (cb) {
+ fs.readdir('.', function (er, dirs) {
+ if (er) return cb(er)
+ var res = {}
+ dirs.forEach(function (d) {
+ switch (d) {
+ case 'example': case 'examples': return res.example = d
+ case 'test': case 'tests': return res.test = d
+ case 'doc': case 'docs': return res.doc = d
+ case 'man': return res.man = d
+ }
+ })
+ if (Object.keys(res).length === 0) res = undefined
+ return cb(null, res)
+ })
+ },
+ "dependencies" : typeof dependencies !== 'undefined' ? dependencies
+ : function (cb) {
+ fs.readdir('node_modules', function (er, dir) {
+ if (er) return cb()
+ var deps = {}
+ var n = dir.length
+ dir.forEach(function (d) {
+ if (d.match(/^\./)) return next()
+ if (d.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/))
+ return next()
+ fs.readFile('node_modules/' + d + '/package.json', function (er, p) {
+ if (er) return next()
+ try { p = JSON.parse(p) } catch (e) { return next() }
+ if (!p.version) return next()
+ deps[d] = '~' + p.version
+ return next()
+ })
+ })
+ function next () {
+ if (--n === 0) return cb(null, deps)
+ }
+ })
+ },
+ "devDependencies" : typeof devDependencies !== 'undefined' ? devDependencies
+ : function (cb) {
+ // same as dependencies but for dev deps
+ fs.readdir('node_modules', function (er, dir) {
+ if (er) return cb()
+ var deps = {}
+ var n = dir.length
+ dir.forEach(function (d) {
+ if (d.match(/^\./)) return next()
+ if (!d.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/))
+ return next()
+ fs.readFile('node_modules/' + d + '/package.json', function (er, p) {
+ if (er) return next()
+ try { p = JSON.parse(p) } catch (e) { return next() }
+ if (!p.version) return next()
+ deps[d] = '~' + p.version
+ return next()
+ })
+ })
+ function next () {
+ if (--n === 0) return cb(null, deps)
+ }
+ })
+ },
+ "scripts" : (function () {
+ // check to see what framework is in use, if any
+ try { var d = fs.readdirSync('node_modules') }
+ catch (e) { d = [] }
+ var s = typeof scripts === 'undefined' ? {} : scripts
+
+ if (d.indexOf('coffee-script') !== -1)
+ s.prepublish = prompt('build command',
+ s.prepublish || 'coffee src/*.coffee -o lib')
+
+ var notest = 'echo "Error: no test specified" && exit 1'
+ function tx (test) {
+ return test || notest
+ }
+
+ if (!s.test || s.test === notest) {
+ if (d.indexOf('tap') !== -1)
+ s.test = prompt('test command', 'tap test/*.js', tx)
+ else if (d.indexOf('expresso') !== -1)
+ s.test = prompt('test command', 'expresso test', tx)
+ else if (d.indexOf('mocha') !== -1)
+ s.test = prompt('test command', 'mocha', tx)
+ else
+ s.test = prompt('test command', tx)
+ }
+
+ return s
+
+ })(),
+
+ "repository" : (function () {
+ try { var gconf = fs.readFileSync('.git/config') }
+ catch (e) { gconf = null }
+ if (gconf) {
+ gconf = gconf.split(/\r?\n/)
+ var i = gconf.indexOf('[remote "origin"]')
+ if (i !== -1) {
+ var u = gconf[i + 1]
+ if (!u.match(/^\s*url =/)) u = gconf[i + 2]
+ if (!u.match(/^\s*url =/)) u = null
+ else u = u.replace(/^\s*url = /, '')
+ }
+ if (u && u.match(/^git@github.com:/))
+ u = u.replace(/^git@github.com:/, 'git://github.com/')
+ }
+
+ return prompt('git repository', u)
+ })(),
+
+ "keywords" : prompt(function (s) {
+ if (!s) return undefined
+ if (Array.isArray(s)) s = s.join(' ')
+ if (typeof s !== 'string') return s
+ return s.split(/[\s,]+/)
+ }),
+ "author" : config['init.author.name']
+ ? {
+ "name" : config['init.author.name'],
+ "email" : config['init.author.email'],
+ "url" : config['init.author.url']
+ }
+ : undefined,
+ "license" : prompt('license', 'BSD')
+}
--- /dev/null
+var PZ = require('../../promzard').PromZard
+var path = require('path')
+var input = path.resolve(__dirname, 'init-input.js')
+
+var fs = require('fs')
+var package = path.resolve(__dirname, 'package.json')
+var pkg
+
+fs.readFile(package, 'utf8', function (er, d) {
+ if (er) ctx = {}
+ try { ctx = JSON.parse(d); pkg = JSON.parse(d) }
+ catch (e) { ctx = {} }
+
+ ctx.dirname = path.dirname(package)
+ ctx.basename = path.basename(ctx.dirname)
+ if (!ctx.version) ctx.version = undefined
+
+ // this should be replaced with the npm conf object
+ ctx.config = {}
+
+ console.error('ctx=', ctx)
+
+ var pz = new PZ(input, ctx)
+
+ pz.on('data', function (data) {
+ console.error('pz data', data)
+ if (!pkg) pkg = {}
+ Object.keys(data).forEach(function (k) {
+ if (data[k] !== undefined && data[k] !== null) pkg[k] = data[k]
+ })
+ console.error('package data %s', JSON.stringify(data, null, 2))
+ fs.writeFile(package, JSON.stringify(pkg, null, 2), function (er) {
+ if (er) throw er
+ console.log('ok')
+ })
+ })
+})
--- /dev/null
+{
+ "name": "npm-init",
+ "version": "0.0.0",
+ "description": "an initter you init wit, innit?",
+ "main": "index.js",
+ "scripts": {
+ "test": "asdf"
+ },
+ "license": "BSD"
+}
\ No newline at end of file
--- /dev/null
+module.exports = {
+ "name" : basename.replace(/^node-/, ''),
+ "version" : "0.0.0",
+ "description" : (function (cb) {
+ var fs = require('fs');
+ var value;
+ try {
+ var src = fs.readFileSync('README.markdown', 'utf8');
+ value = src.split('\n').filter(function (line) {
+ return /\s+/.test(line)
+ && line.trim() !== basename.replace(/^node-/, '')
+ ;
+ })[0]
+ .trim()
+ .replace(/^./, function (c) { return c.toLowerCase() })
+ .replace(/\.$/, '')
+ ;
+ }
+ catch (e) {}
+
+ return prompt('description', value);
+ })(),
+ "main" : prompt('entry point', 'index.js'),
+ "bin" : function (cb) {
+ var path = require('path');
+ var fs = require('fs');
+ var exists = fs.exists || path.exists;
+ exists('bin/cmd.js', function (ex) {
+ var bin
+ if (ex) {
+ var bin = {}
+ bin[basename.replace(/^node-/, '')] = 'bin/cmd.js'
+ }
+ cb(null, bin);
+ });
+ },
+ "directories" : {
+ "example" : "example",
+ "test" : "test"
+ },
+ "dependencies" : {},
+ "devDependencies" : {
+ "tap" : "~0.2.5"
+ },
+ "scripts" : {
+ "test" : "tap test/*.js"
+ },
+ "repository" : {
+ "type" : "git",
+ "url" : "git://github.com/substack/" + basename + ".git"
+ },
+ "homepage" : "https://github.com/substack/" + basename,
+ "keywords" : prompt(function (s) { return s.split(/\s+/) }),
+ "author" : {
+ "name" : "James Halliday",
+ "email" : "mail@substack.net",
+ "url" : "http://substack.net"
+ },
+ "license" : "MIT",
+ "engine" : { "node" : ">=0.6" }
+}
--- /dev/null
+{
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "name": "promzard",
+ "description": "A reimplementation of @SubStack's",
+ "version": "0.1.5",
+ "repository": {
+ "url": "git://github.com/isaacs/promzard"
+ },
+ "dependencies": {
+ "read": "0"
+ },
+ "devDependencies": {
+ "tap": "~0.2.5"
+ },
+ "main": "promzard.js",
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "readme": "# promzard\n\nA reimplementation of @SubStack's\n[prompter](https://github.com/substack/node-prompter), which does not\nuse AST traversal.\n\nFrom another point of view, it's a reimplementation of\n[@Marak](https://github.com/marak)'s\n[wizard](https://github.com/Marak/wizard) which doesn't use schemas.\n\nThe goal is a nice drop-in enhancement for `npm init`.\n\n## Usage\n\n```javascript\nvar promzard = require('promzard')\npromzard(inputFile, optionalContextAdditions, function (er, data) {\n // .. you know what you doing ..\n})\n```\n\nIn the `inputFile` you can have something like this:\n\n```javascript\nvar fs = require('fs')\nmodule.exports = {\n \"greeting\": prompt(\"Who shall you greet?\", \"world\", function (who) {\n return \"Hello, \" + who\n }),\n \"filename\": __filename,\n \"directory\": function (cb) {\n fs.readdir(__dirname, cb)\n }\n}\n```\n\nWhen run, promzard will display the prompts and resolve the async\nfunctions in order, and then either give you an error, or the resolved\ndata, ready to be dropped into a JSON file or some other place.\n\n\n### promzard(inputFile, ctx, callback)\n\nThe inputFile is just a node module. You can require() things, set\nmodule.exports, etc. Whatever that module exports is the result, and it\nis walked over to call any functions as described below.\n\nThe only caveat is that you must give PromZard the full absolute path\nto the module (you can get this via Node's `require.resolve`.) Also,\nthe `prompt` function is injected into the context object, so watch out.\n\nWhatever you put in that `ctx` will of course also be available in the\nmodule. You can get quite fancy with this, passing in existing configs\nand so on.\n\n### Class: promzard.PromZard(file, ctx)\n\nJust like the `promzard` function, but the EventEmitter that makes it\nall happen. Emits either a `data` event with the data, or a `error`\nevent if it blows up.\n\nIf `error` is emitted, then `data` never will be.\n\n### prompt(...)\n\nIn the promzard input module, you can call the `prompt` function.\nThis prompts the user to input some data. The arguments are interpreted\nbased on type:\n\n1. `string` The first string encountered is the prompt. The second is\n the default value.\n2. `function` A transformer function which receives the data and returns\n something else. More than meets the eye.\n3. `object` The `prompt` member is the prompt, the `default` member is\n the default value, and the `transform` is the transformer.\n\nWhatever the final value is, that's what will be put on the resulting\nobject.\n\n### Functions\n\nIf there are any functions on the promzard input module's exports, then\npromzard will call each of them with a callback. This way, your module\ncan do asynchronous actions if necessary to validate or ascertain\nwhatever needs verification.\n\nThe functions are called in the context of the ctx object, and are given\na single argument, which is a callback that should be called with either\nan error, or the result to assign to that spot.\n\nIn the async function, you can also call prompt() and return the result\nof the prompt in the callback.\n\nFor example, this works fine in a promzard module:\n\n```\nexports.asyncPrompt = function (cb) {\n fs.stat(someFile, function (er, st) {\n // if there's an error, no prompt, just error\n // otherwise prompt and use the actual file size as the default\n cb(er, prompt('file size', st.size))\n })\n}\n```\n\nYou can also return other async functions in the async function\ncallback. Though that's a bit silly, it could be a handy way to reuse\nfunctionality in some cases.\n\n### Sync vs Async\n\nThe `prompt()` function is not synchronous, though it appears that way.\nIt just returns a token that is swapped out when the data object is\nwalked over asynchronously later, and returns a token.\n\nFor that reason, prompt() calls whose results don't end up on the data\nobject are never shown to the user. For example, this will only prompt\nonce:\n\n```\nexports.promptThreeTimes = prompt('prompt me once', 'shame on you')\nexports.promptThreeTimes = prompt('prompt me twice', 'um....')\nexports.promptThreeTimes = prompt('you cant prompt me again')\n```\n\n### Isn't this exactly the sort of 'looks sync' that you said was bad about other libraries?\n\nYeah, sorta. I wouldn't use promzard for anything more complicated than\na wizard that spits out prompts to set up a config file or something.\nMaybe there are other use cases I haven't considered.\n",
+ "_id": "promzard@0.1.5",
+ "_from": "promzard@~0.1.5"
+}
--- /dev/null
+module.exports = promzard
+promzard.PromZard = PromZard
+
+var fs = require('fs')
+var vm = require('vm')
+var util = require('util')
+var files = {}
+var crypto = require('crypto')
+var EventEmitter = require('events').EventEmitter
+var read = require('read')
+
+var Module = require('module').Module
+var path = require('path')
+
+function promzard (file, ctx, cb) {
+ if (typeof ctx === 'function') cb = ctx, ctx = null;
+ if (!ctx) ctx = {};
+ var pz = new PromZard(file, ctx)
+ pz.on('error', cb)
+ pz.on('data', function (data) {
+ cb(null, data)
+ })
+}
+
+function PromZard (file, ctx) {
+ if (!(this instanceof PromZard))
+ return new PromZard(file, ctx)
+ EventEmitter.call(this)
+ this.file = file
+ this.ctx = ctx
+ this.unique = crypto.randomBytes(8).toString('hex')
+ this.load()
+}
+
+PromZard.prototype = Object.create(
+ EventEmitter.prototype,
+ { constructor: {
+ value: PromZard,
+ readable: true,
+ configurable: true,
+ writable: true,
+ enumerable: false } } )
+
+PromZard.prototype.load = function () {
+ if (files[this.file])
+ return this.loaded()
+
+ fs.readFile(this.file, 'utf8', function (er, d) {
+ if (er && this.backupFile) {
+ this.file = this.backupFile
+ delete this.backupFile
+ return this.load()
+ }
+ if (er)
+ return this.emit('error', this.error = er)
+ files[this.file] = d
+ this.loaded()
+ }.bind(this))
+}
+
+PromZard.prototype.loaded = function () {
+ this.ctx.prompt = this.makePrompt()
+ this.ctx.__filename = this.file
+ this.ctx.__dirname = path.dirname(this.file)
+ this.ctx.__basename = path.basename(this.file)
+ var mod = this.ctx.module = this.makeModule()
+ this.ctx.require = function (path) {
+ return mod.require(path)
+ }
+ this.ctx.require.resolve = function(path) {
+ return Module._resolveFilename(path, mod);
+ }
+ this.ctx.exports = mod.exports
+
+ this.script = this.wrap(files[this.file])
+ var fn = vm.runInThisContext(this.script, this.file)
+ var args = Object.keys(this.ctx).map(function (k) {
+ return this.ctx[k]
+ }.bind(this))
+ try { var res = fn.apply(this.ctx, args) }
+ catch (er) { this.emit('error', er) }
+ if (res &&
+ typeof res === 'object' &&
+ exports === mod.exports &&
+ Object.keys(exports).length === 1) {
+ this.result = res
+ } else {
+ this.result = mod.exports
+ }
+ this.walk()
+}
+
+PromZard.prototype.makeModule = function () {
+ var mod = new Module(this.file, module)
+ mod.loaded = true
+ mod.filename = this.file
+ mod.id = this.file
+ mod.paths = Module._nodeModulePaths(path.dirname(this.file))
+ return mod
+}
+
+PromZard.prototype.wrap = function (body) {
+ var s = '(function( %s ) { %s\n })'
+ var args = Object.keys(this.ctx).join(', ')
+ return util.format(s, args, body)
+}
+
+PromZard.prototype.makePrompt = function () {
+ this.prompts = []
+ return prompt.bind(this)
+ function prompt () {
+ var p, d, t
+ for (var i = 0; i < arguments.length; i++) {
+ var a = arguments[i]
+ if (typeof a === 'string' && p)
+ d = a
+ else if (typeof a === 'string')
+ p = a
+ else if (typeof a === 'function')
+ t = a
+ else if (a && typeof a === 'object') {
+ p = a.prompt || p
+ d = a.default || d
+ t = a.tranform || t
+ }
+ }
+
+ try { return this.unique + '-' + this.prompts.length }
+ finally { this.prompts.push([p, d, t]) }
+ }
+}
+
+PromZard.prototype.walk = function (o, cb) {
+ o = o || this.result
+ cb = cb || function (er, res) {
+ if (er)
+ return this.emit('error', this.error = er)
+ this.result = res
+ return this.emit('data', res)
+ }
+ cb = cb.bind(this)
+ var keys = Object.keys(o)
+ var i = 0
+ var len = keys.length
+
+ L.call(this)
+ function L () {
+ if (this.error)
+ return
+ while (i < len) {
+ var k = keys[i]
+ var v = o[k]
+ i++
+
+ if (v && typeof v === 'object') {
+ return this.walk(v, function (er, res) {
+ if (er) return cb(er)
+ o[k] = res
+ L.call(this)
+ }.bind(this))
+ } else if (v &&
+ typeof v === 'string' &&
+ v.indexOf(this.unique) === 0) {
+ var n = +v.substr(this.unique.length + 1)
+ var prompt = this.prompts[n]
+ if (isNaN(n) || !prompt)
+ continue
+
+ // default to the key
+ if (undefined === prompt[0])
+ prompt[0] = k
+
+ // default to the ctx value, if there is one
+ if (undefined === prompt[1])
+ prompt[1] = this.ctx[k]
+
+ return this.prompt(prompt, function (er, res) {
+ if (er)
+ return this.emit('error', this.error = er);
+ o[k] = res
+ L.call(this)
+ }.bind(this))
+ } else if (typeof v === 'function') {
+ try { return v.call(this.ctx, function (er, res) {
+ if (er)
+ return this.emit('error', this.error = er)
+ o[k] = res
+ // back up so that we process this one again.
+ // this is because it might return a prompt() call in the cb.
+ i --
+ L.call(this)
+ }.bind(this)) }
+ catch (er) { this.emit('error', er) }
+ }
+ }
+ // made it to the end of the loop, maybe
+ if (i >= len)
+ return cb(null, o)
+ }
+}
+
+PromZard.prototype.prompt = function (pdt, cb) {
+ var prompt = pdt[0]
+ var def = pdt[1]
+ var tx = pdt[2]
+
+ if (tx) {
+ cb = function (cb) { return function (er, data) {
+ try { return cb(er, tx(data)) }
+ catch (er) { this.emit('error', er) }
+ }}(cb).bind(this)
+ }
+
+ read({ prompt: prompt + ': ' , default: def }, cb)
+}
+
--- /dev/null
+var tap = require('tap')
+var pz = require('../promzard.js')
+var spawn = require('child_process').spawn
+
+tap.test('run the example', function (t) {
+
+ var example = require.resolve('../example/index.js')
+ var node = process.execPath
+
+ var expect = {
+ "name": "example",
+ "version": "0.0.0",
+ "description": "testing description",
+ "main": "test-entry.js",
+ "directories": {
+ "example": "example",
+ "test": "test"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "tap": "~0.2.5"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/substack/example.git"
+ },
+ "homepage": "https://github.com/substack/example",
+ "keywords": [
+ "fugazi",
+ "function",
+ "waiting",
+ "room"
+ ],
+ "author": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "license": "MIT",
+ "engine": {
+ "node": ">=0.6"
+ }
+ }
+
+ console.error('%s %s', node, example)
+ var c = spawn(node, [example], { customFds: [-1,-1,-1] })
+ var output = ''
+ c.stdout.on('data', function (d) {
+ output += d
+ respond()
+ })
+
+ var actual = ''
+ c.stderr.on('data', function (d) {
+ actual += d
+ })
+
+ function respond () {
+ console.error('respond', output)
+ if (output.match(/description: $/)) {
+ c.stdin.write('testing description\n')
+ return
+ }
+ if (output.match(/entry point: \(index\.js\) $/)) {
+ c.stdin.write('test-entry.js\n')
+ return
+ }
+ if (output.match(/keywords: $/)) {
+ c.stdin.write('fugazi function waiting room\n')
+ return
+ }
+ }
+
+ c.on('close', function () {
+ console.error('actual', actual)
+ actual = JSON.parse(actual)
+ t.deepEqual(actual, expect)
+ t.end()
+ })
+})
--- /dev/null
+exports.a = 1 + 2
+exports.b = prompt('To be or not to be?', '!2b')
+exports.c = {}
+exports.c.x = prompt()
+exports.c.y = tmpdir + "/y/file.txt"
--- /dev/null
+var test = require('tap').test;
+var promzard = require('../');
+
+test('exports', function (t) {
+ t.plan(1);
+
+ var ctx = { tmpdir : '/tmp' }
+ var file = __dirname + '/exports.input';
+ promzard(file, ctx, function (err, output) {
+ t.same(
+ {
+ a : 3,
+ b : '!2b',
+ c : {
+ x : 55,
+ y : '/tmp/y/file.txt',
+ }
+ },
+ output
+ );
+ });
+
+ setTimeout(function () {
+ process.stdin.emit('data', '\n');
+ }, 100);
+
+ setTimeout(function () {
+ process.stdin.emit('data', '55\n');
+ }, 200);
+});
--- /dev/null
+var fs = require('fs')
+
+module.exports = {
+ "a": 1 + 2,
+ "b": prompt('To be or not to be?', '!2b', function (s) {
+ return s.toUpperCase() + '...'
+ }),
+ "c": {
+ "x": prompt(function (x) { return x * 100 }),
+ "y": tmpdir + "/y/file.txt"
+ },
+ a_function: function (cb) {
+ fs.readFile(__filename, 'utf8', cb)
+ },
+ asyncPrompt: function (cb) {
+ return cb(null, prompt('a prompt at any other time would smell as sweet'))
+ }
+}
--- /dev/null
+var test = require('tap').test;
+var promzard = require('../');
+var fs = require('fs')
+
+test('prompt callback param', function (t) {
+ t.plan(1);
+
+ var ctx = { tmpdir : '/tmp' }
+ var file = __dirname + '/fn.input';
+ promzard(file, ctx, function (err, output) {
+ var expect =
+ {
+ a : 3,
+ b : '!2B...',
+ c : {
+ x : 5500,
+ y : '/tmp/y/file.txt',
+ }
+ }
+ expect.a_function = fs.readFileSync(file, 'utf8')
+ expect.asyncPrompt = 'async prompt'
+ t.same(
+ output,
+ expect
+ );
+ });
+
+ setTimeout(function () {
+ process.stdin.emit('data', '\n');
+ }, 100);
+
+ setTimeout(function () {
+ process.stdin.emit('data', '55\n');
+ }, 200);
+
+ setTimeout(function () {
+ process.stdin.emit('data', 'async prompt')
+ }, 300)
+});
--- /dev/null
+module.exports = {
+ "a": 1 + 2,
+ "b": prompt('To be or not to be?', '!2b'),
+ "c": {
+ "x": prompt(),
+ "y": tmpdir + "/y/file.txt"
+ }
+}
--- /dev/null
+var test = require('tap').test;
+var promzard = require('../');
+
+test('simple', function (t) {
+ t.plan(1);
+
+ var ctx = { tmpdir : '/tmp' }
+ var file = __dirname + '/simple.input';
+ promzard(file, ctx, function (err, output) {
+ t.same(
+ {
+ a : 3,
+ b : '!2b',
+ c : {
+ x : 55,
+ y : '/tmp/y/file.txt',
+ }
+ },
+ output
+ );
+ });
+
+ setTimeout(function () {
+ process.stdin.emit('data', '\n');
+ }, 100);
+
+ setTimeout(function () {
+ process.stdin.emit('data', '55\n');
+ }, 200);
+});
--- /dev/null
+{
+ "name": "init-package-json",
+ "version": "0.0.2",
+ "main": "init-package-json.js",
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/init-package-json"
+ },
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "license": "BSD",
+ "description": "A node module to get your node module started",
+ "dependencies": {
+ "promzard": "~0.1.5",
+ "read": "~0.1.0",
+ "read-package-json": "0.0.6",
+ "semver": "~1.0.14"
+ },
+ "devDependencies": {
+ "tap": "~0.2.5",
+ "rimraf": "~2.0.2"
+ },
+ "keywords": [
+ "init",
+ "package.json",
+ "package",
+ "helper",
+ "wizard",
+ "wizerd",
+ "prompt",
+ "start"
+ ],
+ "readme": "# init-package-json\n\nA node module to get your node module started.\n\n## Usage\n\n```javascript\nvar init = require('init-package-json')\nvar path = require('path')\n\n// a path to a promzard module. In the event that this file is\n// not found, one will be provided for you.\nvar initFile = path.resolve(process.env.HOME, '.npm-init')\n\n// the dir where we're doin stuff.\nvar dir = process.cwd()\n\n// extra stuff that gets put into the PromZard module's context.\n// In npm, this is the resolved config object. Exposed as 'config'\n// Optional.\nvar configData = { some: 'extra stuff' }\n\n// Any existing stuff from the package.json file is also exposed in the\n// PromZard module as the `package` object. There will also be free\n// vars for:\n// * `filename` path to the package.json file\n// * `basename` the tip of the package dir\n// * `dirname` the parent of the package dir\n\ninit(dir, initFile, configData, function (er, data) {\n // the data's already been written to {dir}/package.json\n // now you can do stuff with it\n})\n```\n\nOr from the command line:\n\n```\n$ npm-init\n```\n\nSee [PromZard](https://github.com/isaacs/promzard) for details about\nwhat can go in the config file.\n",
+ "_id": "init-package-json@0.0.2",
+ "_from": "init-package-json@0"
+}
, which = require('which')
, semver = require('semver')
, mkdirp = require('mkdirp')
+ , exec = require('child_process').exec
, win = process.platform == 'win32'
exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module'
return
}
log.verbose('`which` succeeded for `' + python + '`', execPath)
- // TODO: ensure compatible Python version
- getNodeDir()
+ checkPythonVersion()
})
}
if (err.code == 'ENOENT') {
failNoPython()
} else {
- callbackk(err)
+ callback(err)
}
return
}
python = pythonPath
- getNodeDir()
+ checkPythonVersion()
+ })
+ }
+
+ function checkPythonVersion () {
+ exec(python + ' --version', function (err, stdout, stderr) {
+ if (err) {
+ return callback(err)
+ }
+ var version = stderr.trim().replace(/[^\d\.]+/g, '')
+ if (semver.lt(version, '3.0.0')) {
+ getNodeDir()
+ } else {
+ failPython3()
+ }
})
}
+ '", you can set the PYTHON env variable.'))
}
+ function failPython3 () {
+ callback(new Error('Python executable "' + python
+ + '" is Python 3, which is not supported.\n'
+ + 'You can set the PYTHON env variable to point to a Python 2 interpreter.'))
+ }
+
function getNodeDir () {
// 'python' should be set by now
if (err && err.code != 'ENOENT') {
return callback(err)
}
- if (versions) {
+ if (Array.isArray(versions)) {
versions = versions.filter(function (v) { return v != 'current' })
} else {
versions = []
, 'rm': 'remove'
}
+// differentiate node-gyp's logs from npm's
log.heading = 'gyp'
/**
{
"name": "node-gyp",
- "description": "Node.js native addon build tool",
+ "description": "`node-gyp` is a cross-platform command-line tool written in Node.js for compiling",
"keywords": [
"native",
"addon",
"bindings",
"gyp"
],
- "version": "0.5.0",
+ "version": "0.5.2",
"installVersion": 9,
"author": {
"name": "Nathan Rajlich",
"node": ">= 0.6.0"
},
"readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n * On Unix:\n * `python`\n * `make`\n * A proper C/C++ compiler toolchain, like GCC\n * On Windows:\n * [Python][windows-python] ([`v2.7.2`][windows-python-v2.7.2] recommended, `v3.x.x` not yet supported)\n * Microsoft Visual C++ ([Express][msvc] version works well)\n * For 64-bit builds of node and native modules you will _also_ need the [Windows 7 64-bit SDK][win7sdk]\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n \"targets\": [\n {\n \"target_name\": \"binding\",\n \"sources\": [ \"src/binding.cc\" ]\n }\n ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * ['\"binding.gyp\" files out in the wild' wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n * `build` - Invokes `make`/`msbuild.exe` and builds the native addon\n * `clean` - Removes any generated project files and the `out` dir\n * `configure` - Generates project build files for the current platform\n * `rebuild` - Runs \"clean\", \"configure\" and \"build\" all at once\n * `install` - Installs node development files for the given version.\n * `list` - Lists the currently installed node development file versions\n * `remove` - Removes a node development files for a given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.2]: http://www.python.org/download/releases/2.7.2#download\n[msvc]: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express\n[win7sdk]: http://www.microsoft.com/download/en/details.aspx?displayLang=en&id=8279\n",
- "_id": "node-gyp@0.5.0",
+ "_id": "node-gyp@0.5.2",
"dist": {
- "shasum": "88ad842c9f3ccd29a8d2a393107896c99fe32d63"
+ "shasum": "7410e3dd9d950592ee80d09c7e5ef22286f79c0f"
},
- "_from": "node-gyp@~0.5"
+ "_from": "node-gyp@0.5.2"
}
return this.request('GET'
, '/-/user/org.couchdb.user:'+encodeURIComponent(username)
, function (er, data, json, response) {
+ if (er || data.error) {
+ return cb(er, data, json, response)
+ }
Object.keys(data).forEach(function (k) {
- userobj[k] = data[k]
+ if (!userobj[k]) {
+ userobj[k] = data[k]
+ }
})
this.log.verbose("adduser", "userobj", userobj)
this.request('PUT'
var remote = url.parse(where)
, auth = authRequired && this.auth
+ if (authRequired && !auth && this.username && this.password) {
+ var a = this.username + ":" + this.password
+ a = new Buffer(a, "utf8").toString("base64")
+ auth = this.auth = a
+ }
+
if (authRequired && !auth) {
return cb(new Error(
"Cannot insert data into the registry without auth"))
"url": "http://blog.izs.me/"
},
"name": "npm-registry-client",
- "description": "Client for the npm registry",
- "version": "0.0.5",
+ "description": "The code that npm uses to talk to the registry",
+ "version": "0.0.6",
"repository": {
"url": "git://github.com/isaacs/npm-registry-client"
},
"node": "*"
},
"readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(options)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Options\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `alwaysAuth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strictSSL` {Boolean} Whether or not to be strict with SSL\n certificates. Default = `true`\n* `userAgent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a request to the registry. All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder. However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment. Mostly used by `client.publish()`.\n",
- "_id": "npm-registry-client@0.0.5",
+ "_id": "npm-registry-client@0.0.6",
"_from": "npm-registry-client@0"
}
{
"name": "read-package-json",
- "version": "0.0.4",
+ "version": "0.0.6",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"glob": "~3.1.9",
"lru-cache": "~1.1.0",
"semver": "~1.0.14",
+ "slide": "~1.1.3",
"npmlog": "0",
"graceful-fs": "~1.1.8"
},
"graceful-fs": "~1.1.8"
},
"readme": "# read-package-json\n\nThis is the thing that npm uses to read package.json files. It\nvalidates some stuff, and loads some default things.\n\nIt keeps a cache of the files you've read, so that you don't end\nup reading the same package.json file multiple times.\n\nNote that if you just want to see what's literally in the package.json\nfile, you can usually do `var data = require('some-module/package.json')`.\n\nThis module is basically only needed by npm, but it's handy to see what\nnpm will see when it looks at your package.\n\n## Usage\n\n```javascript\nvar readJson = require('read-package-json')\n\nreadJson('/path/to/package.json', function (er, data) {\n if (er) {\n console.error(\"There was an error reading the file\")\n return\n }\n\n console.error('the package data is', data)\n}\n```\n\n## readJson(file, cb)\n\n* `file` {String} The path to the package.json file\n* `cb` {Function}\n\nReads the JSON file and does the things.\n\n## `package.json` Fields\n\nSee `man 5 package.json` or `npm help json`.\n\n## readJson.log\n\nBy default this is a reference to the `npmlog` module. But if that\nmodule can't be found, then it'll be set to just a dummy thing that does\nnothing.\n\nReplace with your own `{log,warn,error}` object for fun loggy time.\n\n## readJson.extras(file, data, cb)\n\nRun all the extra stuff relative to the file, with the parsed data.\n\nModifies the data as it does stuff. Calls the cb when it's done.\n\n## readJson.extraSet = [fn, fn, ...]\n\nArray of functions that are called by `extras`. Each one receives the\narguments `fn(file, data, cb)` and is expected to call `cb(er, data)`\nwhen done or when an error occurs.\n\nOrder is indeterminate, so each function should be completely\nindependent.\n\nMix and match!\n\n## readJson.cache\n\nThe `lru-cache` object that readJson uses to not read the same file over\nand over again. See\n[lru-cache](https://github.com/isaacs/node-lru-cache) for details.\n\n## Other Relevant Files Besides `package.json`\n\nSome other files have an effect on the resulting data object, in the\nfollowing ways:\n\n### `README?(.*)`\n\nIf there is a `README` or `README.*` file present, then npm will attach\na `readme` field to the data with the contents of this file.\n\nOwing to the fact that roughly 100% of existing node modules have\nMarkdown README files, it will generally be assumed to be Markdown,\nregardless of the extension. Please plan accordingly.\n\n### `server.js`\n\nIf there is a `server.js` file, and there is not already a\n`scripts.start` field, then `scripts.start` will be set to `node\nserver.js`.\n\n### `AUTHORS`\n\nIf there is not already a `contributors` field, then the `contributors`\nfield will be set to the contents of the `AUTHORS` file, split by lines,\nand parsed.\n\n### `bindings.gyp`\n\nIf a bindings.gyp file exists, and there is not already a\n`scripts.install` field, then the `scripts.install` field will be set to\n`node-gyp rebuild`.\n\n### `wscript`\n\nIf a wscript file exists, and there is not already a `scripts.install`\nfield, then the `scripts.install` field will be set to `node-waf clean ;\nnode-waf configure build`.\n\nNote that the `bindings.gyp` file supercedes this, since node-waf has\nbeen deprecated in favor of node-gyp.\n\n### `index.js`\n\nIf the json file does not exist, but there is a `index.js` file\npresent instead, and that file has a package comment, then it will try\nto parse the package comment, and use that as the data instead.\n\nA package comment looks like this:\n\n```javascript\n/**package\n * { \"name\": \"my-bare-module\"\n * , \"version\": \"1.2.3\"\n * , \"description\": \"etc....\" }\n **/\n\n// or...\n\n/**package\n{ \"name\": \"my-bare-module\"\n, \"version\": \"1.2.3\"\n, \"description\": \"etc....\" }\n**/\n```\n\nThe important thing is that it starts with `/**package`, and ends with\n`**/`. If the package.json file exists, then the index.js is not\nparsed.\n\n### `{directories.man}/*.[0-9]`\n\nIf there is not already a `man` field defined as an array of files or a\nsingle file, and\nthere is a `directories.man` field defined, then that directory will\nbe searched for manpages.\n\nAny valid manpages found in that directory will be assigned to the `man`\narray, and installed in the appropriate man directory at package install\ntime, when installed globally on a Unix system.\n\n### `{directories.bin}/*`\n\nIf there is not already a `bin` field defined as a string filename or a\nhash of `<name> : <filename>` pairs, then the `directories.bin`\ndirectory will be searched and all the files within it will be linked as\nexecutables at install time.\n\nWhen installing locally, npm links bins into `node_modules/.bin`, which\nis in the `PATH` environ when npm runs scripts. When\ninstalling globally, they are linked into `{prefix}/bin`, which is\npresumably in the `PATH` environment variable.\n",
- "_id": "read-package-json@0.0.4",
- "dist": {
- "shasum": "c6241ec84f4577117dbf96a9a290570ff3aaf8d0"
- },
- "_from": "read-package-json@0"
+ "_id": "read-package-json@0.0.6",
+ "_from": "read-package-json@latest"
}
return cb(null, data)
}
+var defDesc = "Unnamed repository; edit this file " +
+ "'description' to name the repository."
+function gitDescription (file, data, cb) {
+ if (data.description) return cb(null, data);
+ var dir = path.dirname(file)
+ // just cuz it'd be nice if this file mattered...
+ var gitDesc = path.resolve(dir, '.git/description')
+ fs.readFile(gitDesc, 'utf8', function (er, desc) {
+ desc = desc.trim()
+ if (!er && desc.trim() !== defDesc)
+ data.description = desc
+ return cb(null, data)
+ })
+}
+
+function readmeDescription (file, data) {
+ var d = data.readme
+ if (!d) return
+ d = d.split('\n')
+ d = d.filter(function (line) {
+ return /\s+/.test(line)
+ && line.trim() !== data.name
+ && !line.trim().match(/^#/)
+ })[0]
+ d = d.trim()
+ d = d.replace(/\.$/, '')
+ if (d) data.description = d
+}
+
function readme (file, data, cb) {
if (data.readme) return cb(null, data);
var dir = path.dirname(file)
unParsePeople(file, data)
parsePeople(file, data)
+ if (data.readme)
+ readmeDescription(file, data)
+
readJson.cache.set(file, data)
cb(null, data)
}
* `prompt` What to write to stdout before reading input.
* `silent` Don't echo the output as the user types it.
* `num` Max number of chars to read from terminal.
-* `delim` The char that means we're done. Default: `"\n"`
* `timeout` Number of ms to wait for user input before giving up.
* `default` The default value if the user enters nothing.
-If silent is true, or num is set, or delim is something other than
-`"\n"`, then read will set raw mode, and read character by character.
+If silent is true, or num is set, and the input is a TTY,
+then read will set raw mode, and read character by character.
-At this time, backspace and arrow keys are not supported in raw mode.
+At this time, backspace and arrow keys are not supported very well.
It's probably not too hard to add support for this, perhaps using node's
built-in readline module.
, StringDecoder = require("string_decoder").StringDecoder
function raw (mode) {
+ if (process.stdin.setRawMode) {
+ if (process.stdin.isTTY) {
+ process.stdin.setRawMode(mode)
+ }
+ return
+ }
+ // old style
try {
- process.stdin.setRawMode(mode)
- } catch (e) {
tty.setRawMode(mode)
- }
+ } catch (e) {}
}
+
function read (opts, cb) {
if (!cb) cb = opts, opts = {}
, silent = opts.silent
, timeout = opts.timeout
, num = opts.num || null
- , delim = opts.delim || "\n"
if (p && def) p += "("+(silent ? "<default hidden>" : def)+") "
// switching into raw mode is a little bit painful.
// avoid if possible.
- var r = silent || num || delim !== "\n" ? rawRead : normalRead
+ var r = silent || num ? rawRead : normalRead
+ if (r === rawRead && !process.stdin.isTTY) r = normalRead
if (timeout) {
cb = (function (cb) {
if (p && !process.stdout.write(p)) {
process.stdout.on("drain", function D () {
process.stdout.removeListener("drain", D)
- r(def, timeout, delim, silent, num, cb)
+ r(def, timeout, silent, num, cb)
})
} else {
process.nextTick(function () {
- r(def, timeout, delim, silent, num, cb)
+ r(def, timeout, silent, num, cb)
})
}
}
-function normalRead (def, timeout, delim, silent, num, cb) {
+function normalRead (def, timeout, silent, num, cb) {
var stdin = process.openStdin()
, val = ""
, decoder = new StringDecoder("utf8")
buffer = ""
// \r has no place here.
- // XXX But what if \r is the delim or something dumb like that?
- // Meh. If anyone complains about this, deal with it.
val = val.replace(/\r/g, "")
- // TODO Make delim configurable
- if (val.indexOf(delim) !== -1) {
+ if (val.indexOf("\n") !== -1) {
// pluck off any delims at the beginning.
- if (val !== delim) {
+ if (val !== "\n") {
var i, l
for (i = 0, l = val.length; i < l; i ++) {
- if (val.charAt(i) !== delim) break
+ if (val.charAt(i) !== "\n") break
}
if (i !== 0) val = val.substr(i)
}
+ // hack. if we get the number of chars, just pretend there was a delim
+ if (num > 0 && val.length >= num) {
+ val = val.substr(0, num) + "\n" + val.substr(num)
+ }
+
// buffer whatever might have come *after* the delimter
- var delimIndex = val.indexOf(delim)
+ var delimIndex = val.indexOf("\n")
if (delimIndex !== -1) {
buffer = val.substr(delimIndex)
val = val.substr(0, delimIndex)
})
}
-function rawRead (def, timeout, delim, silent, num, cb) {
+function rawRead (def, timeout, silent, num, cb) {
var stdin = process.openStdin()
, val = ""
, decoder = new StringDecoder
stdin.on("error", cb)
stdin.on("data", function D (c) {
// \r is my enemy.
- c = decoder.write(c).replace(/\r/g, "\n")
+ var s = decoder.write(c).replace(/\r/g, "\n")
+ var i = 0
- switch (c) {
- case "": // probably just a \r that was ignored.
+ LOOP: while (c = s.charAt(i++)) switch (c) {
+ case "\u007f": // backspace
+ val = val.substr(0, val.length - 1)
+ if (!silent) process.stdout.write('\b \b')
break
case "\u0004": // EOF
- case delim:
+ case "\n":
raw(false)
stdin.removeListener("data", D)
stdin.removeListener("error", cb)
stdin.removeListener("error", cb)
stdin.pause()
return cb(new Error("cancelled"))
- break
default: // just a normal char
val += buffer + c
buffer = ""
if (!silent) process.stdout.write(c)
- // explicitly process a delim if we have enough chars.
- if (num && val.length >= num) D(delim)
- break
+ // explicitly process a delim if we have enough chars
+ // and stop the processing.
+ if (num && val.length >= num) D("\n")
+ break LOOP
}
})
}
{
"name": "read",
- "version": "0.0.2",
+ "version": "0.1.0",
"main": "lib/read.js",
"dependencies": {},
- "devDependencies": {},
+ "devDependencies": {
+ "tap": "*"
+ },
"engines": {
"node": ">=0.6"
},
"url": "git://github.com/isaacs/read.git"
},
"license": "BSD",
- "_id": "read@0.0.2",
- "optionalDependencies": {},
- "_engineSupported": true,
- "_npmVersion": "1.1.15",
- "_nodeVersion": "v0.7.7",
- "_defaultsLoaded": true,
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "readme": "For reading user input from stdin.\n\n## USAGE\n\n```javascript\nvar read = require(\"read\")\nread(options, callback)\n```\n\nThe callback gets called with either the user input, or the default\nspecified, or an error, in the traditional `callback(error, result)`\nnode style.\n\n## OPTIONS\n\nEvery option is optional.\n\n* `prompt` What to write to stdout before reading input.\n* `silent` Don't echo the output as the user types it.\n* `num` Max number of chars to read from terminal.\n* `timeout` Number of ms to wait for user input before giving up.\n* `default` The default value if the user enters nothing.\n\nIf silent is true, or num is set, and the input is a TTY,\nthen read will set raw mode, and read character by character.\n\nAt this time, backspace and arrow keys are not supported very well.\nIt's probably not too hard to add support for this, perhaps using node's\nbuilt-in readline module.\n\n## CONTRIBUTING\n\nPatches welcome.\n\n## BUGS\n\nIn node 0.6.0 through 0.6.5, you must explicitly call\n`process.stdin.destroy()` or `process.exit()` when you know that your\nprogram is done reading, or else it will keep the event loop running\nforever.\n\nSee: <https://github.com/joyent/node/issues/2257>\n",
+ "_id": "read@0.1.0",
"_from": "read@0"
}
{
- "version": "1.1.26",
+ "version": "1.1.27",
"name": "npm",
"publishConfig": {
"proprietary-attribs": false
"npm-registry-client": "0",
"read-package-json": "0",
"read-installed": "0",
- "glob": "~3.1.9"
+ "glob": "~3.1.9",
+ "init-package-json": "0"
},
"bundleDependencies": [
- "slide",
- "ini",
"semver",
+ "ini",
+ "slide",
"abbrev",
"graceful-fs",
"minimatch",
"nopt",
"node-uuid",
+ "proto-list",
"rimraf",
"request",
- "proto-list",
"which",
"tar",
"fstream",
"npm-registry-client",
"read-package-json",
"read-installed",
- "glob"
+ "glob",
+ "init-package-json"
],
"devDependencies": {
"ronn": "https://github.com/isaacs/ronnjs/tarball/master"