diff options
Diffstat (limited to 'node_modules/gauge')
-rw-r--r-- | node_modules/gauge/.npmignore | 32 | ||||
-rw-r--r-- | node_modules/gauge/LICENSE | 13 | ||||
-rw-r--r-- | node_modules/gauge/README.md | 161 | ||||
-rw-r--r-- | node_modules/gauge/example.png | bin | 0 -> 19689 bytes | |||
-rw-r--r-- | node_modules/gauge/package.json | 83 | ||||
-rw-r--r-- | node_modules/gauge/progress-bar.js | 209 | ||||
-rw-r--r-- | node_modules/gauge/test/progress-bar.js | 148 |
7 files changed, 646 insertions, 0 deletions
diff --git a/node_modules/gauge/.npmignore b/node_modules/gauge/.npmignore new file mode 100644 index 000000000..df22a16c6 --- /dev/null +++ b/node_modules/gauge/.npmignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + +# Editor cruft +*~ +.#* diff --git a/node_modules/gauge/LICENSE b/node_modules/gauge/LICENSE new file mode 100644 index 000000000..e75605296 --- /dev/null +++ b/node_modules/gauge/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2014, Rebecca Turner <me@re-becca.org> + +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/gauge/README.md b/node_modules/gauge/README.md new file mode 100644 index 000000000..fb9eb0a7d --- /dev/null +++ b/node_modules/gauge/README.md @@ -0,0 +1,161 @@ +gauge +===== + +A nearly stateless terminal based horizontal guage / progress bar. + +```javascript +var Gauge = require("gauge") + +var gauge = new Gauge() + +gauge.show("test", 0.20) + +gauge.pulse("this") + +gauge.hide() +``` + +![](example.png) + + +### `var gauge = new Gauge([options], [ansiStream])` + +* **options** – *(optional)* An option object. (See [below] for details.) +* **ansiStream** – *(optional)* A stream that's been blessed by the [ansi] + module to include various commands for controlling the cursor in a terminal. + +[ansi]: https://www.npmjs.com/package/ansi +[below]: #theme-objects + +Constructs a new gauge. Gauges are drawn on a single line, and are not drawn +if the current terminal isn't a tty. + +The **options** object can have the following properties, all of which are +optional: + +* maxUpdateFrequency: defaults to 50 msec, the gauge will not be drawn more + than once in this period of time. This applies to `show` and `pulse` + calls, but if you `hide` and then `show` the gauge it will draw it + regardless of time since last draw. +* theme: defaults to Gauge.unicode` if the terminal supports + unicode according to [has-unicode], otherwise it defaults to `Gauge.ascii`. + Details on the [theme object](#theme-objects) are documented elsewhere. +* template: see [documentation elsewhere](#template-objects) for + defaults and details. + +[has-unicode]: https://www.npmjs.com/package/has-unicode + +If **ansiStream** isn't passed in, then one will be constructed from stderr +with `ansi(process.stderr)`. + +### `gauge.show([name, [completed]])` + +* **name** – *(optional)* The name of the current thing contributing to progress. Defaults to the last value used, or "". +* **completed** – *(optional)* The portion completed as a value between 0 and 1. Defaults to the last value used, or 0. + +If `process.stdout.isTTY` is false then this does nothing. If completed is 0 +and `gauge.pulse` has never been called, then similarly nothing will be printed. + +If `maxUpdateFrequency` msec haven't passed since the last call to `show` or +`pulse` then similarly, nothing will be printed. (Actually, the update is +deferred until `maxUpdateFrequency` msec have passed and if nothing else has +happened, the gauge update will happen.) + +### `gauge.hide()` + +Removes the gauge from the terminal. + +### `gauge.pulse([name])` + +* **name** – *(optional)* The specific thing that triggered this pulse + +Spins the spinner in the gauge to show output. If **name** is included then +it will be combined with the last name passed to `gauge.show` using the +subsection property of the theme (typically a right facing arrow). + +### `gauge.disable()` + +Hides the gauge and ignores further calls to `show` or `pulse`. + +### `gauge.enable()` + +Shows the gauge and resumes updating when `show` or `pulse` is called. + +### `gauge.setTheme(theme)` + +Change the active theme, will be displayed with the next show or pulse + +### `gauge.setTemplate(template)` + +Change the active template, will be displayed with the next show or pulse + +### Theme Objects + +There are two theme objects available as a part of the module, `Gauge.unicode` and `Gauge.ascii`. +Theme objects have the follow properties: + +| Property | Unicode | ASCII | +| ---------- | ------- | ----- | +| startgroup | ╢ | \| | +| endgroup | ╟ | \| | +| complete | █ | # | +| incomplete | ░ | - | +| spinner | ▀▐▄▌ | -\\\|/ | +| subsection | → | -> | + +*startgroup*, *endgroup* and *subsection* can be as many characters as you want. + +*complete* and *incomplete* should be a single character width each. + +*spinner* is a list of characters to use in turn when displaying an activity +spinner. The Gauge will spin as many characters as you give here. + +### Template Objects + +A template is an array of objects and strings that, after being evaluated, +will be turned into the gauge line. The default template is: + +```javascript +[ + {type: "name", separated: true, maxLength: 25, minWidth: 25, align: "left"}, + {type: "spinner", separated: true}, + {type: "startgroup"}, + {type: "completionbar"}, + {type: "endgroup"} +] +``` + +The various template elements can either be **plain strings**, in which case they will +be be included verbatum in the output. + +If the template element is an object, it can have the following keys: + +* *type* can be: + * `name` – The most recent name passed to `show`; if this is in response to a + `pulse` then the name passed to `pulse` will be appended along with the + subsection property from the theme. + * `spinner` – If you've ever called `pulse` this will be one of the characters + from the spinner property of the theme. + * `startgroup` – The `startgroup` property from the theme. + * `completionbar` – This progress bar itself + * `endgroup` – The `endgroup` property from the theme. +* *separated* – If true, the element will be separated with spaces from things on + either side (and margins count as space, so it won't be indented), but only + if its included. +* *maxLength* – The maximum length for this element. If its value is longer it + will be truncated. +* *minLength* – The minimum length for this element. If its value is shorter it + will be padded according to the *align* value. +* *align* – (Default: left) Possible values "left", "right" and "center". Works + as you'd expect from word processors. +* *length* – Provides a single value for both *minLength* and *maxLength*. If both + *length* and *minLength or *maxLength* are specifed then the latter take precedence. + +### Tracking Completion + +If you have more than one thing going on that you want to track completion +of, you may find the related [are-we-there-yet] helpful. It's `change` +event can be wired up to the `show` method to get a more traditional +progress bar interface. + +[are-we-there-yet]: https://www.npmjs.com/package/are-we-there-yet diff --git a/node_modules/gauge/example.png b/node_modules/gauge/example.png Binary files differnew file mode 100644 index 000000000..2667cac45 --- /dev/null +++ b/node_modules/gauge/example.png diff --git a/node_modules/gauge/package.json b/node_modules/gauge/package.json new file mode 100644 index 000000000..ba69205a3 --- /dev/null +++ b/node_modules/gauge/package.json @@ -0,0 +1,83 @@ +{ + "_args": [ + [ + "gauge@~1.2.0", + "/Users/rebecca/code/npm/node_modules/npmlog" + ] + ], + "_from": "gauge@>=1.2.0 <1.3.0", + "_id": "gauge@1.2.0", + "_inCache": true, + "_location": "/gauge", + "_nodeVersion": "1.1.0", + "_npmUser": { + "email": "me@re-becca.org", + "name": "iarna" + }, + "_npmVersion": "2.6.0", + "_phantomChildren": {}, + "_requested": { + "name": "gauge", + "raw": "gauge@~1.2.0", + "rawSpec": "~1.2.0", + "scope": null, + "spec": ">=1.2.0 <1.3.0", + "type": "range" + }, + "_requiredBy": [ + "/npmlog" + ], + "_resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.0.tgz", + "_shasum": "3094ab1285633f799814388fc8f2de67b4c012c5", + "_shrinkwrap": null, + "_spec": "gauge@~1.2.0", + "_where": "/Users/rebecca/code/npm/node_modules/npmlog", + "author": { + "email": "me@re-becca.org", + "name": "Rebecca Turner" + }, + "bugs": { + "url": "https://github.com/iarna/gauge/issues" + }, + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^1.0.0", + "lodash.pad": "^3.0.0", + "lodash.padleft": "^3.0.0", + "lodash.padright": "^3.0.0" + }, + "description": "A terminal based horizontal guage", + "devDependencies": { + "tap": "^0.4.13" + }, + "directories": {}, + "dist": { + "shasum": "3094ab1285633f799814388fc8f2de67b4c012c5", + "tarball": "http://registry.npmjs.org/gauge/-/gauge-1.2.0.tgz" + }, + "gitHead": "db15c35374816b3fc3b9e1e54866f31ed7f4a733", + "homepage": "https://github.com/iarna/gauge", + "keywords": [ + "gauge", + "progress", + "progressbar" + ], + "license": "ISC", + "main": "progress-bar.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "name": "gauge", + "optionalDependencies": {}, + "repository": { + "type": "git", + "url": "https://github.com/iarna/gauge" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.2.0" +} diff --git a/node_modules/gauge/progress-bar.js b/node_modules/gauge/progress-bar.js new file mode 100644 index 000000000..39dbf2ac4 --- /dev/null +++ b/node_modules/gauge/progress-bar.js @@ -0,0 +1,209 @@ +"use strict" +var hasUnicode = require("has-unicode") +var ansi = require("ansi") +var align = { + center: require("lodash.pad"), + left: require("lodash.padright"), + right: require("lodash.padleft") +} +var defaultStream = process.stderr +function isTTY() { + return process.stderr.isTTY +} +function getWritableTTYColumns() { + // One less than the actual as writing to the final column wraps the line + return process.stderr.columns - 1 +} + +var ProgressBar = module.exports = function (options, cursor) { + if (! options) options = {} + if (! cursor && options.write) { + cursor = options + options = {} + } + if (! cursor) { + cursor = ansi(defaultStream) + } + this.cursor = cursor + this.showing = false + this.theme = options.theme || (hasUnicode() ? ProgressBar.unicode : ProgressBar.ascii) + this.template = options.template || [ + {type: "name", separated: true, length: 25}, + {type: "spinner", separated: true}, + {type: "startgroup"}, + {type: "completionbar"}, + {type: "endgroup"} + ] + this.updatefreq = options.maxUpdateFrequency || 50 + this.lastName = "" + this.lastCompleted = 0 + this.spun = 0 + this.last = new Date(0) +} +ProgressBar.prototype = {} + +ProgressBar.unicode = { + startgroup: "╢", + endgroup: "╟", + complete: "█", + incomplete: "░", + spinner: "▀▐▄▌", + subsection: "→" +} + +ProgressBar.ascii = { + startgroup: "|", + endgroup: "|", + complete: "#", + incomplete: "-", + spinner: "-\\|/", + subsection: "->" +} + +ProgressBar.prototype.setTheme = function(theme) { + this.theme = theme +} + +ProgressBar.prototype.setTemplate = function(template) { + this.template = template +} + +ProgressBar.prototype.disable = function() { + this.hide() + this.disabled = true +} + +ProgressBar.prototype.enable = function() { + this.disabled = false + this.show() +} + +ProgressBar.prototype.hide = function() { + if (!isTTY()) return + if (this.disabled) return + this.cursor.show() + if (this.showing) this.cursor.up(1) + this.cursor.horizontalAbsolute(0).eraseLine() + this.showing = false +} + +var repeat = function (str, count) { + var out = "" + for (var ii=0; ii<count; ++ii) out += str + return out +} + +ProgressBar.prototype.pulse = function(name) { + ++ this.spun + if (! this.showing) return + if (this.disabled) return + + var baseName = this.lastName + name = name + ? ( baseName + ? baseName + " " + this.theme.subsection + " " + name + : null ) + : baseName + this.show(name) + this.lastName = baseName +} + +ProgressBar.prototype.show = function(name, completed) { + name = this.lastName = name || this.lastName + completed = this.lastCompleted = completed || this.lastCompleted + + if (!isTTY()) return + if (this.disabled) return + if (! this.spun && ! completed) return + if (this.tryAgain) { + clearTimeout(this.tryAgain) + this.tryAgain = null + } + var self = this + if (this.showing && new Date() - this.last < this.updatefreq) { + this.tryAgain = setTimeout(function () { + if (self.disabled) return + if (! self.spun && ! completed) return + drawBar() + }, this.updatefreq - (new Date() - this.last)) + return + } + + return drawBar() + + function drawBar() { + var values = { + name: name, + spinner: self.spun, + completed: completed + } + + self.last = new Date() + + var statusline = self.renderTemplate(self.theme, self.template, values) + + if (self.showing) self.cursor.up(1) + self.cursor + .hide() + .horizontalAbsolute(0) + .write(statusline.substr(0, getWritableTTYColumns()) + "\n") + .show() + + self.showing = true + } +} + +ProgressBar.prototype.renderTemplate = function (theme, template, values) { + values.startgroup = theme.startgroup + values.endgroup = theme.endgroup + values.spinner = values.spinner + ? theme.spinner.substr(values.spinner % theme.spinner.length,1) + : "" + + var output = {prebar: "", postbar: ""} + var status = "prebar" + var self = this + template.forEach(function(T) { + if (typeof T === "string") { + output[status] += T + return + } + if (T.type === "completionbar") { + status = "postbar" + return + } + if (!values.hasOwnProperty(T.type)) throw new Error("Unknown template value '"+T.type+"'") + var value = self.renderValue(T, values[T.type]) + if (value === "") return + var sofar = output[status].length + var lastChar = sofar ? output[status][sofar-1] : null + if (T.separated && sofar && lastChar !== " ") { + output[status] += " " + } + output[status] += value + if (T.separated) output[status] += " " + }) + + var bar = "" + if (status === "postbar") { + var nonBarLen = output.prebar.length + output.postbar.length + + var barLen = getWritableTTYColumns() - nonBarLen + var sofar = Math.round(barLen * Math.max(0,Math.min(1,values.completed||0))) + var rest = barLen - sofar + bar = repeat(theme.complete, sofar) + + repeat(theme.incomplete, rest) + } + + return output.prebar + bar + output.postbar +} +ProgressBar.prototype.renderValue = function (template, value) { + if (value == null || value === "") return "" + var maxLength = template.maxLength || template.length + var minLength = template.minLength || template.length + var alignWith = align[template.align] || align.left +// if (maxLength) value = value.substr(-1 * maxLength) + if (maxLength) value = value.substr(0, maxLength) + if (minLength) value = alignWith(value, minLength) + return value +} diff --git a/node_modules/gauge/test/progress-bar.js b/node_modules/gauge/test/progress-bar.js new file mode 100644 index 000000000..8e2a5ad64 --- /dev/null +++ b/node_modules/gauge/test/progress-bar.js @@ -0,0 +1,148 @@ +"use strict" +var test = require("tap").test +var ProgressBar = require("../progress-bar.js") + +var cursor = [] +var C +var bar = new ProgressBar({theme: ProgressBar.ascii}, C = { + show: function () { + cursor.push(["show"]) + return C + }, + hide: function () { + cursor.push(["hide"]) + return C + }, + up: function (lines) { + cursor.push(["up",lines]) + return C + }, + horizontalAbsolute: function (col) { + cursor.push(["horizontalAbsolute", col]) + return C + }, + eraseLine: function () { + cursor.push(["eraseLine"]) + return C + }, + write: function (line) { + cursor.push(["write", line]) + return C + } +}) + + +function isOutput(t, msg, output) { + var tests = [] + for (var ii = 0; ii<output.length; ++ii) { + for (var jj = 0; jj<output[ii].length; ++jj) { + tests.push({cmd: ii, arg: jj}) + } + } + tests.forEach(function(test) { + t.is(cursor[test.cmd] ? cursor[test.cmd][test.arg] : null, + output[test.cmd][test.arg], + msg + ": " + output[test.cmd] + (test.arg ? " arg #"+test.arg : "")) + }) +} + +test("hide", function (t) { + t.plan(11) + process.stderr.isTTY = false + bar.hide() + t.is(cursor.length, 0, "We don't progress bar without a tty") + cursor = [] + process.stderr.isTTY = true + bar.hide() + isOutput(t, "hide while not showing",[ + ["show"], // cursor + ["horizontalAbsolute",0], + ["eraseLine"]]) + cursor = [] + bar.showing = true + bar.hide() + isOutput(t, "hide while showing",[ + ["show"], // cursor + ["up", 1], + ["horizontalAbsolute",0], + ["eraseLine"]]) +}) + +test("renderTemplate", function (t) { + t.plan(16) + process.stderr.columns = 11 + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "name"}],{name: "NAME"}) + t.is(result, "NAME", "name substitution") + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 0}) + t.is(result, "----------", "0% bar") + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 0.5}) + t.is(result, "#####-----", "50% bar") + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 1}) + t.is(result, "##########", "100% bar") + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: -100}) + t.is(result, "----------", "0% underflow bar") + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 100}) + t.is(result, "##########", "100% overflow bar") + var result = bar.renderTemplate(ProgressBar.ascii,[{type: "name"},{type: "completionbar"}],{name: "NAME", completed: 0.5}) + t.is(result, "NAME###---", "name + 50%") + var result = bar.renderTemplate(ProgressBar.ascii, ["static"], {}) + t.is(result, "static", "static text") + var result = bar.renderTemplate(ProgressBar.ascii, ["static",{type: "name"}], {name: "NAME"}) + t.is(result, "staticNAME", "static text + var") + var result = bar.renderTemplate(ProgressBar.ascii, ["static",{type: "name", separated: true}], {name: "NAME"}) + t.is(result, "static NAME ", "pre-separated") + var result = bar.renderTemplate(ProgressBar.ascii, [{type: "name", separated: true}, "static"], {name: "NAME"}) + t.is(result, "NAME static", "post-separated") + var result = bar.renderTemplate(ProgressBar.ascii, ["1",{type: "name", separated: true}, "2"], {name: ""}) + t.is(result, "12", "separated no value") + var result = bar.renderTemplate(ProgressBar.ascii, ["1",{type: "name", separated: true}, "2"], {name: "NAME"}) + t.is(result, "1 NAME 2", "separated value") + var result = bar.renderTemplate(ProgressBar.ascii, [{type: "spinner"}], {spinner: 0}) + t.is(result, "", "No spinner") + var result = bar.renderTemplate(ProgressBar.ascii, [{type: "spinner"}], {spinner: 1}) + t.is(result, "\\", "Spinner 1") + var result = bar.renderTemplate(ProgressBar.ascii, [{type: "spinner"}], {spinner: 10}) + t.is(result, "|", "Spinner 10") +}) + +test("show & pulse", function (t) { + t.plan(23) + + process.stderr.columns = 16 + cursor = [] + process.stderr.isTTY = false + bar.template[0].length = 6 + bar.last = new Date(0) + bar.show("NAME", 0) + t.is(cursor.length, 0, "no tty, no progressbar") + + cursor = [] + process.stderr.isTTY = true + bar.last = new Date(0) + bar.show("NAME", 0.1) + isOutput(t, "tty, name, completion", + [ [ 'hide' ], + [ 'horizontalAbsolute', 0 ], + [ 'write', 'NAME |#-----|\n' ], + [ 'show' ] ]) + + bar.show("S") + cursor = [] + bar.last = new Date(0) + bar.pulse() + isOutput(t, "pulsed spinner", + [ [ 'up', 1 ], + [ 'hide' ], + [ 'horizontalAbsolute', 0 ], + [ 'write', 'S \\ |----|\n' ], + [ 'show' ] ]) + cursor = [] + bar.last = new Date(0) + bar.pulse("P") + isOutput(t, "pulsed spinner with subsection", + [ [ 'up', 1 ], + [ 'hide' ], + [ 'horizontalAbsolute', 0 ], + [ 'write', 'S -> P | |----|\n' ], + [ 'show' ] ]) +}) |