Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2014-05-08 02:17:26 +0400
committerisaacs <i@izs.me>2014-05-08 02:18:38 +0400
commitbf761dddd14ce07b7070a38ec0661d4a21e7577f (patch)
tree3e78912ffb5be5c51caa8feee99ef1d34f39c85f
parent7fc87498678ecd602f5f5c37cc930a61670af264 (diff)
Busy Spinner, no http noise
One step closer to #5213
-rw-r--r--doc/misc/npm-config.md11
-rw-r--r--lib/help.js1
-rw-r--r--lib/init.js1
-rw-r--r--lib/npm.js18
-rw-r--r--lib/utils/lifecycle.js3
-rw-r--r--lib/version.js5
-rw-r--r--lib/view.js2
-rw-r--r--node_modules/char-spinner/LICENSE15
-rw-r--r--node_modules/char-spinner/README.md31
-rw-r--r--node_modules/char-spinner/package.json40
-rw-r--r--node_modules/char-spinner/spin.js41
-rw-r--r--node_modules/char-spinner/test/basic.js35
-rw-r--r--package.json2
13 files changed, 204 insertions, 1 deletions
diff --git a/doc/misc/npm-config.md b/doc/misc/npm-config.md
index a70de8121..4792d808f 100644
--- a/doc/misc/npm-config.md
+++ b/doc/misc/npm-config.md
@@ -712,6 +712,17 @@ using `-s` to add a signature.
Note that git requires you to have set up GPG keys in your git configs
for this to work properly.
+### spin
+
+* Default: true
+* Type: Boolean or `"always"`
+
+When set to `true`, npm will display an ascii spinner while it is doing
+things, if `process.stderr` is a TTY.
+
+Set to `false` to suppress the spinner, or set to `always` to output
+the spinner even for non-TTY outputs.
+
### strict-ssl
* Default: true
diff --git a/lib/help.js b/lib/help.js
index 72b4393b6..c68f322ab 100644
--- a/lib/help.js
+++ b/lib/help.js
@@ -15,6 +15,7 @@ var fs = require("graceful-fs")
, glob = require("glob")
function help (args, cb) {
+ npm.spinner.stop()
var argv = npm.config.get("argv").cooked
var argnum = 0
diff --git a/lib/init.js b/lib/init.js
index d064ae8bc..74cd806f6 100644
--- a/lib/init.js
+++ b/lib/init.js
@@ -12,6 +12,7 @@ init.usage = "npm init"
function init (args, cb) {
var dir = process.cwd()
log.pause()
+ npm.spinner.stop()
var initFile = npm.config.get('init-module')
console.log(
diff --git a/lib/npm.js b/lib/npm.js
index 613bf0095..44c132f2c 100644
--- a/lib/npm.js
+++ b/lib/npm.js
@@ -30,6 +30,7 @@ var EventEmitter = require("events").EventEmitter
, slide = require("slide")
, chain = slide.chain
, RegClient = require("npm-registry-client")
+ , charSpin = require("char-spinner")
npm.config = {
loaded: false,
@@ -182,6 +183,21 @@ var commandCache = {}
})
, abbrevs = abbrev(fullList)
+npm.spinner =
+ { int: null
+ , start: function () {
+ if (npm.spinner.int) return
+ var c = npm.config.get("spin")
+ if (!c) return
+ var stream = npm.config.get("logstream")
+ var opt = { tty: c !== "always", stream: stream }
+ npm.spinner.int = charSpin(opt)
+ }
+ , stop: function () {
+ clearInterval(npm.spinner.int)
+ }
+ }
+
Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) {
Object.defineProperty(npm.commands, c, { get : function () {
if (!loaded) throw new Error(
@@ -204,6 +220,8 @@ Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) {
}
if (args.length === 1) args.unshift([])
+ npm.spinner.start()
+
if (!npm.registry.refer) {
npm.registry.refer = [a].concat(args[0]).map(function (arg) {
// exclude anything that might be a URL, path, or private module
diff --git a/lib/utils/lifecycle.js b/lib/utils/lifecycle.js
index 1af5bddca..af009cc21 100644
--- a/lib/utils/lifecycle.js
+++ b/lib/utils/lifecycle.js
@@ -162,6 +162,9 @@ function runCmd (note, cmd, pkg, env, stage, wd, unsafe, cb) {
, group = unsafe ? null : npm.config.get("group")
if (log.level !== 'silent') {
+ if (npm.spinner.int) {
+ npm.config.get("logstream").write("\r \r")
+ }
console.log(note)
}
log.verbose("unsafe-perm in lifecycle", unsafe)
diff --git a/lib/version.js b/lib/version.js
index bc4871592..ec3f93b20 100644
--- a/lib/version.js
+++ b/lib/version.js
@@ -105,6 +105,11 @@ function checkGit (data, cb) {
chain
( [ [ exec, git, [ "add", "package.json" ], {env: process.env} ]
, [ exec, git, [ "commit", "-m", message ], {env: process.env} ]
+ , sign && function (cb) {
+ npm.spinner.stop()
+ cb()
+ }
+
, [ exec, git, [ "tag", "v" + data.version, flag, message ]
, {env: process.env} ] ]
, cb )
diff --git a/lib/view.js b/lib/view.js
index 18484b2bd..6b7382378 100644
--- a/lib/view.js
+++ b/lib/view.js
@@ -208,7 +208,7 @@ function printData (data, name, cb) {
d = JSON.stringify(d)
}
if (f && showFields) f += " = "
- if (d.indexOf("\n") !== -1) d = "\n" + d
+ if (d.indexOf("\n") !== -1) d = " \n" + d
msg += (showVersions ? name + "@" + v + " " : "")
+ (showFields ? f : "") + d + "\n"
})
diff --git a/node_modules/char-spinner/LICENSE b/node_modules/char-spinner/LICENSE
new file mode 100644
index 000000000..05eeeb88c
--- /dev/null
+++ b/node_modules/char-spinner/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/node_modules/char-spinner/README.md b/node_modules/char-spinner/README.md
new file mode 100644
index 000000000..b202f4cdd
--- /dev/null
+++ b/node_modules/char-spinner/README.md
@@ -0,0 +1,31 @@
+# char-spinner
+
+Put a little spinner on process.stderr, as unobtrusively as possible.
+
+## USAGE
+
+```javascript
+var spinner = require("spinner")
+
+// All options are optional
+// even the options argument itself is optional
+spinner(options)
+```
+
+## OPTIONS
+
+Usually the defaults are what you want. Mostly they're just
+configurable for testing purposes.
+
+* `stream` Output stream. Default=`process.stderr`
+* `tty` Only show spinner if output stream has a truish `.isTTY`. Default=`true`
+* `string` String of chars to spin. Default=`'/-\\|'`
+* `interval` Number of ms between frames, bigger = slower. Default=`50`
+* `cleanup` Print `'\r \r'` to stream on process exit. Default=`true`
+* `unref` Unreference the spinner interval so that the process can
+ exit normally. Default=`true`
+* `delay` Number of frames to "skip over" before printing the spinner.
+ Useful if you want to avoid showing the spinner for very fast
+ actions. Default=`2`
+
+Returns the generated interval, if one was created.
diff --git a/node_modules/char-spinner/package.json b/node_modules/char-spinner/package.json
new file mode 100644
index 000000000..b2760afa6
--- /dev/null
+++ b/node_modules/char-spinner/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "char-spinner",
+ "version": "1.0.0",
+ "description": "Put a little spinner on process.stderr, as unobtrusively as possible.",
+ "main": "spin.js",
+ "directories": {
+ "test": "test"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "tap": "^0.4.10"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/char-spinner"
+ },
+ "keywords": [
+ "char",
+ "spinner"
+ ],
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/isaacs/char-spinner/issues"
+ },
+ "homepage": "https://github.com/isaacs/char-spinner",
+ "readme": "# char-spinner\n\nPut a little spinner on process.stderr, as unobtrusively as possible.\n\n## USAGE\n\n```javascript\nvar spinner = require(\"spinner\")\n\n// All options are optional\n// even the options argument itself is optional\nspinner(options)\n```\n\n## OPTIONS\n\nUsually the defaults are what you want. Mostly they're just\nconfigurable for testing purposes.\n\n* `stream` Output stream. Default=`process.stderr`\n* `tty` Only show spinner if output stream has a truish `.isTTY`. Default=`true`\n* `string` String of chars to spin. Default=`'/-\\\\|'`\n* `interval` Number of ms between frames, bigger = slower. Default=`50`\n* `cleanup` Print `'\\r \\r'` to stream on process exit. Default=`true`\n* `unref` Unreference the spinner interval so that the process can\n exit normally. Default=`true`\n* `delay` Number of frames to \"skip over\" before printing the spinner.\n Useful if you want to avoid showing the spinner for very fast\n actions. Default=`2`\n\nReturns the generated interval, if one was created.\n",
+ "readmeFilename": "README.md",
+ "_id": "char-spinner@1.0.0",
+ "_shasum": "b5fadba903f242a31c1e93b2f532482d62bb56b2",
+ "_from": "char-spinner@latest",
+ "_resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.0.tgz"
+}
diff --git a/node_modules/char-spinner/spin.js b/node_modules/char-spinner/spin.js
new file mode 100644
index 000000000..1068d3253
--- /dev/null
+++ b/node_modules/char-spinner/spin.js
@@ -0,0 +1,41 @@
+module.exports = spinner
+
+function spinner(opt) {
+ opt = opt || {}
+ var str = opt.stream || process.stderr
+ var tty = typeof opt.tty === 'boolean' ? opt.tty : true
+ var string = opt.string || '/-\\|'
+ var ms = typeof opt.interval === 'number' ? opt.interval : 50
+ if (ms < 0) ms = 0
+ if (tty && !str.isTTY) return false
+
+ var s = 0
+ var sprite = string.split('')
+ var wrote = false
+
+ var delay = typeof opt.delay === 'number' ? opt.delay : 2
+
+ var interval = setInterval(function() {
+ if (--delay >= 0) return
+ s = ++s % sprite.length
+ var c = sprite[s]
+ str.write('\r \r' + c + '\r')
+ wrote = true
+ }, ms)
+
+ var unref = typeof opt.unref === 'boolean' ? opt.unref : true
+ if (unref && typeof interval.unref === 'function') {
+ interval.unref()
+ }
+
+ var cleanup = typeof opt.cleanup === 'boolean' ? opt.cleanup : true
+ if (cleanup) {
+ process.on('exit', function() {
+ if (wrote) {
+ str.write('\r \r')
+ }
+ })
+ }
+
+ return interval
+}
diff --git a/node_modules/char-spinner/test/basic.js b/node_modules/char-spinner/test/basic.js
new file mode 100644
index 000000000..f3c1dfe2b
--- /dev/null
+++ b/node_modules/char-spinner/test/basic.js
@@ -0,0 +1,35 @@
+var test = require('tap').test
+var spinner = require('../spin.js')
+
+test('does nothing when not a tty', function(t) {
+ var int = spinner({
+ stream: { write: function(c) {
+ throw new Error('wrote something: ' + JSON.stringify(c))
+ }, isTTY: false },
+ })
+ t.notOk(int)
+ t.end()
+})
+
+test('write spinny stuff', function(t) {
+ var output = ''
+ var written = 0
+ var expect = "\r \rb\r\r \rc\r\r \rd\r\r \re\r\r \rf\r\r \rg\r\r \rh\r\r \ri\r\r \rj\r\r \rk\r\r \rl\r\r \rm\r\r \rn\r\r \ro\r\r \rp\r\r \ra\r\r \rb\r\r \rc\r\r \rd\r\r \re\r\r \rf\r\r \rg\r\r \rh\r\r \ri\r\r \rj\r\r \rk\r\r \rl\r\r \rm\r\r \rn\r\r \ro\r\r \rp\r\r \ra\r\r \rb\r\r \rc\r\r \rd\r\r \re\r\r \rf\r\r \rg\r\r \rh\r\r \ri\r\r \rj\r\r \rk\r\r \rl\r\r \rm\r\r \rn\r\r \ro\r\r \rp\r\r \ra\r\r \rb\r\r \rc\r"
+
+ var int = spinner({
+ interval: 0,
+ string: 'abcdefghijklmnop',
+ stream: {
+ write: function(c) {
+ output += c
+ if (++written == 50) {
+ t.equal(output, expect)
+ clearInterval(int)
+ t.end()
+ }
+ },
+ isTTY: true
+ },
+ cleanup: false
+ })
+})
diff --git a/package.json b/package.json
index 31511a141..051a2afe1 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"ansistyles": "~0.1.3",
"archy": "0",
"block-stream": "0.0.7",
+ "char-spinner": "~1.0.0",
"child-process-close": "~0.1.1",
"chmodr": "~0.1.0",
"chownr": "0",
@@ -91,6 +92,7 @@
"ansistyles",
"archy",
"block-stream",
+ "char-spinner",
"child-process-close",
"chmodr",
"chownr",