diff options
Diffstat (limited to 'node_modules/gauge/progress-bar.js')
-rw-r--r-- | node_modules/gauge/progress-bar.js | 209 |
1 files changed, 209 insertions, 0 deletions
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 +} |