package/package.json000644 0000001150 3560116604 011543 0ustar00000000 000000 { "name": "progress", "version": "2.0.3", "description": "Flexible ascii progress bar", "repository": { "type": "git", "url": "git://github.com/visionmedia/node-progress" }, "keywords": [ "cli", "progress" ], "author": "TJ Holowaychuk ", "contributors": [ "Christoffer Hallas ", "Jordan Scales ", "Andrew Rhyne ", "Marco Brack " ], "dependencies": {}, "main": "./index.js", "engines": { "node": ">=0.4.0" }, "license": "MIT" } package/CHANGELOG.md000644 0000006474 3560116604 011104 0ustar00000000 000000 2.0.0 / 2017-04-04 ================== * Fix: check before using stream.clearLine to prevent crash in Docker * Fix: fixed output multiline on windows cmd * Fix: Bug with array length when window is too small * Fix: Don't clear whole line every time; instead, clear everything after end of line * Fix: Use `this.stream` instead of `console.log` when terminating a progress bar to ensure that, if a writable stream is provided, it uses that rather than process.stdout * Fix: Bug causing potentially stale tokens on render * Feature: configurable cursor * Feature: feature to interrupt the bar and display a message * Feature: Add rate reporting to progress bar * Improvement: Add head option to specify head character * Improvement: Rename tickTokens to tokens * Improvement: Change default throttle time to 16ms * Improvement: Rename renderDelay to renderThrottle * Improvement: Add delay between render updates * Docs: Add example and documentation for custom token usage * Docs: Add head option to readme * Docs: Updated README example for public use * Docs: Add renderThrottle option to code documentation 1.1.7 / 2014-06-30 ================== * fixed a bug that occurs when a progress bar attempts to draw itself on a console with very few columns 1.1.6 / 2014-06-16 ================== * now prevents progress bar from exceeding TTY width by limiting its width to the with of the TTY 1.1.5 / 2014-03-25 ================== * updated documentation and various other repo maintenance * updated makefile to run examples with `make` * removed dependency on readline module 1.1.4 / 2014-03-14 ================== * now supports streams, for example output progress bar to stderr, while piping stdout * increases performance and flicker by remembering the last drawn progress bar 1.1.3 / 2013-12-31 ================== * fixes a bug where bar would bug when initializing * allows to pass updated tokens when ticking or updating the bar * fixes a bug where the bar would throw if skipping to far 1.1.2 / 2013-10-17 ================== * lets you pass an `fmt` and a `total` instead of an options object 1.1.0 / 2013-09-18 ================== * eta and elapsed tokens default to 0.0 instead of ?.? * better JSDocs * added back and forth example * added method to update the progress bar to a specific percentage * added an option to hide the bar on completion 1.0.1 / 2013-08-07 ================== * on os x readline now works, reverting the terminal hack 1.0.0 / 2013-06-18 ================== * remove .version * merge pull request #15 from davglass/readline-osx * on OSX revert back to terminal hack to avoid a readline bug 0.1.0 / 2012-09-19 ================== * fixed logic bug that caused bar to jump one extra space at the end [davglass] * working with readline impl, even on Windows [davglass] * using readline instead of the \r hack [davglass] 0.0.5 / 2012-08-07 ================== * add ability to tick by zero chunks - tick(0) * fix ETA. Closes #4 [lwille] 0.0.4 / 2011-11-14 ================== * allow more recent versions of node 0.0.3 / 2011-04-20 ================== * changed; erase the line when complete 0.0.2 / 2011-04-20 ================== * added custom tokens support * fixed; clear line before writing 0.0.1 / 2010-01-03 ================== * initial release package/index.js000644 0000000061 3560116604 010722 0ustar00000000 000000 module.exports = require('./lib/node-progress'); package/LICENSE000644 0000002112 3560116604 010261 0ustar00000000 000000 (The MIT License) Copyright (c) 2017 TJ Holowaychuk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. package/Makefile000644 0000000232 3560116604 010715 0ustar00000000 000000 EXAMPLES = $(foreach EXAMPLE, $(wildcard examples/*.js), $(EXAMPLE)) .PHONY: test test: $(EXAMPLES) .PHONY: $(EXAMPLES) $(EXAMPLES): ; node $@ && echo package/Readme.md000644 0000006674 3560116604 011014 0ustar00000000 000000 Flexible ascii progress bar. ## Installation ```bash $ npm install progress ``` ## Usage First we create a `ProgressBar`, giving it a format string as well as the `total`, telling the progress bar when it will be considered complete. After that all we need to do is `tick()` appropriately. ```javascript var ProgressBar = require('progress'); var bar = new ProgressBar(':bar', { total: 10 }); var timer = setInterval(function () { bar.tick(); if (bar.complete) { console.log('\ncomplete\n'); clearInterval(timer); } }, 100); ``` ### Options These are keys in the options object you can pass to the progress bar along with `total` as seen in the example above. - `curr` current completed index - `total` total number of ticks to complete - `width` the displayed width of the progress bar defaulting to total - `stream` the output stream defaulting to stderr - `head` head character defaulting to complete character - `complete` completion character defaulting to "=" - `incomplete` incomplete character defaulting to "-" - `renderThrottle` minimum time between updates in milliseconds defaulting to 16 - `clear` option to clear the bar on completion defaulting to false - `callback` optional function to call when the progress bar completes ### Tokens These are tokens you can use in the format of your progress bar. - `:bar` the progress bar itself - `:current` current tick number - `:total` total ticks - `:elapsed` time elapsed in seconds - `:percent` completion percentage - `:eta` estimated completion time in seconds - `:rate` rate of ticks per second ### Custom Tokens You can define custom tokens by adding a `{'name': value}` object parameter to your method (`tick()`, `update()`, etc.) calls. ```javascript var bar = new ProgressBar(':current: :token1 :token2', { total: 3 }) bar.tick({ 'token1': "Hello", 'token2': "World!\n" }) bar.tick(2, { 'token1': "Goodbye", 'token2': "World!" }) ``` The above example would result in the output below. ``` 1: Hello World! 3: Goodbye World! ``` ## Examples ### Download In our download example each tick has a variable influence, so we pass the chunk length which adjusts the progress bar appropriately relative to the total length. ```javascript var ProgressBar = require('progress'); var https = require('https'); var req = https.request({ host: 'download.github.com', port: 443, path: '/visionmedia-node-jscoverage-0d4608a.zip' }); req.on('response', function(res){ var len = parseInt(res.headers['content-length'], 10); console.log(); var bar = new ProgressBar(' downloading [:bar] :rate/bps :percent :etas', { complete: '=', incomplete: ' ', width: 20, total: len }); res.on('data', function (chunk) { bar.tick(chunk.length); }); res.on('end', function () { console.log('\n'); }); }); req.end(); ``` The above example result in a progress bar like the one below. ``` downloading [===== ] 39/bps 29% 3.7s ``` ### Interrupt To display a message during progress bar execution, use `interrupt()` ```javascript var ProgressBar = require('progress'); var bar = new ProgressBar(':bar :current/:total', { total: 10 }); var timer = setInterval(function () { bar.tick(); if (bar.complete) { clearInterval(timer); } else if (bar.curr === 5) { bar.interrupt('this message appears above the progress bar\ncurrent progress is ' + bar.curr + '/' + bar.total); } }, 1000); ``` You can see more examples in the `examples` folder. ## License MIT package/lib/node-progress.js000644 0000015026 3560116604 013157 0ustar00000000 000000 /*! * node-progress * Copyright(c) 2011 TJ Holowaychuk * MIT Licensed */ /** * Expose `ProgressBar`. */ exports = module.exports = ProgressBar; /** * Initialize a `ProgressBar` with the given `fmt` string and `options` or * `total`. * * Options: * * - `curr` current completed index * - `total` total number of ticks to complete * - `width` the displayed width of the progress bar defaulting to total * - `stream` the output stream defaulting to stderr * - `head` head character defaulting to complete character * - `complete` completion character defaulting to "=" * - `incomplete` incomplete character defaulting to "-" * - `renderThrottle` minimum time between updates in milliseconds defaulting to 16 * - `callback` optional function to call when the progress bar completes * - `clear` will clear the progress bar upon termination * * Tokens: * * - `:bar` the progress bar itself * - `:current` current tick number * - `:total` total ticks * - `:elapsed` time elapsed in seconds * - `:percent` completion percentage * - `:eta` eta in seconds * - `:rate` rate of ticks per second * * @param {string} fmt * @param {object|number} options or total * @api public */ function ProgressBar(fmt, options) { this.stream = options.stream || process.stderr; if (typeof(options) == 'number') { var total = options; options = {}; options.total = total; } else { options = options || {}; if ('string' != typeof fmt) throw new Error('format required'); if ('number' != typeof options.total) throw new Error('total required'); } this.fmt = fmt; this.curr = options.curr || 0; this.total = options.total; this.width = options.width || this.total; this.clear = options.clear this.chars = { complete : options.complete || '=', incomplete : options.incomplete || '-', head : options.head || (options.complete || '=') }; this.renderThrottle = options.renderThrottle !== 0 ? (options.renderThrottle || 16) : 0; this.lastRender = -Infinity; this.callback = options.callback || function () {}; this.tokens = {}; this.lastDraw = ''; } /** * "tick" the progress bar with optional `len` and optional `tokens`. * * @param {number|object} len or tokens * @param {object} tokens * @api public */ ProgressBar.prototype.tick = function(len, tokens){ if (len !== 0) len = len || 1; // swap tokens if ('object' == typeof len) tokens = len, len = 1; if (tokens) this.tokens = tokens; // start time for eta if (0 == this.curr) this.start = new Date; this.curr += len // try to render this.render(); // progress complete if (this.curr >= this.total) { this.render(undefined, true); this.complete = true; this.terminate(); this.callback(this); return; } }; /** * Method to render the progress bar with optional `tokens` to place in the * progress bar's `fmt` field. * * @param {object} tokens * @api public */ ProgressBar.prototype.render = function (tokens, force) { force = force !== undefined ? force : false; if (tokens) this.tokens = tokens; if (!this.stream.isTTY) return; var now = Date.now(); var delta = now - this.lastRender; if (!force && (delta < this.renderThrottle)) { return; } else { this.lastRender = now; } var ratio = this.curr / this.total; ratio = Math.min(Math.max(ratio, 0), 1); var percent = Math.floor(ratio * 100); var incomplete, complete, completeLength; var elapsed = new Date - this.start; var eta = (percent == 100) ? 0 : elapsed * (this.total / this.curr - 1); var rate = this.curr / (elapsed / 1000); /* populate the bar template with percentages and timestamps */ var str = this.fmt .replace(':current', this.curr) .replace(':total', this.total) .replace(':elapsed', isNaN(elapsed) ? '0.0' : (elapsed / 1000).toFixed(1)) .replace(':eta', (isNaN(eta) || !isFinite(eta)) ? '0.0' : (eta / 1000) .toFixed(1)) .replace(':percent', percent.toFixed(0) + '%') .replace(':rate', Math.round(rate)); /* compute the available space (non-zero) for the bar */ var availableSpace = Math.max(0, this.stream.columns - str.replace(':bar', '').length); if(availableSpace && process.platform === 'win32'){ availableSpace = availableSpace - 1; } var width = Math.min(this.width, availableSpace); /* TODO: the following assumes the user has one ':bar' token */ completeLength = Math.round(width * ratio); complete = Array(Math.max(0, completeLength + 1)).join(this.chars.complete); incomplete = Array(Math.max(0, width - completeLength + 1)).join(this.chars.incomplete); /* add head to the complete string */ if(completeLength > 0) complete = complete.slice(0, -1) + this.chars.head; /* fill in the actual progress bar */ str = str.replace(':bar', complete + incomplete); /* replace the extra tokens */ if (this.tokens) for (var key in this.tokens) str = str.replace(':' + key, this.tokens[key]); if (this.lastDraw !== str) { this.stream.cursorTo(0); this.stream.write(str); this.stream.clearLine(1); this.lastDraw = str; } }; /** * "update" the progress bar to represent an exact percentage. * The ratio (between 0 and 1) specified will be multiplied by `total` and * floored, representing the closest available "tick." For example, if a * progress bar has a length of 3 and `update(0.5)` is called, the progress * will be set to 1. * * A ratio of 0.5 will attempt to set the progress to halfway. * * @param {number} ratio The ratio (between 0 and 1 inclusive) to set the * overall completion to. * @api public */ ProgressBar.prototype.update = function (ratio, tokens) { var goal = Math.floor(ratio * this.total); var delta = goal - this.curr; this.tick(delta, tokens); }; /** * "interrupt" the progress bar and write a message above it. * @param {string} message The message to write. * @api public */ ProgressBar.prototype.interrupt = function (message) { // clear the current line this.stream.clearLine(); // move the cursor to the start of the line this.stream.cursorTo(0); // write the message text this.stream.write(message); // terminate the line after writing the message this.stream.write('\n'); // re-display the progress bar with its lastDraw this.stream.write(this.lastDraw); }; /** * Terminates a progress bar. * * @api public */ ProgressBar.prototype.terminate = function () { if (this.clear) { if (this.stream.clearLine) { this.stream.clearLine(); this.stream.cursorTo(0); } } else { this.stream.write('\n'); } };