Skip to content

Commit

Permalink
Add time-remaining counter to progress bar
Browse files Browse the repository at this point in the history
  • Loading branch information
alxndrsn committed Nov 2, 2017
1 parent 5e76e02 commit 005b416
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 24 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "medic-conf",
"version": "1.7.5",
"version": "1.7.6",
"description": "Configure Medic Mobile deployments",
"main": "index.js",
"scripts": {
Expand Down
13 changes: 5 additions & 8 deletions src/fn/upload-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ module.exports = (projectDir, couchUrl) => {

const totalCount = docFiles.length;

const progress = log.level > log.LEVEL_ERROR ?
progressBar.init(totalCount, '{{N}}/{{M}} docs ') : null;

info(`Uploading ${totalCount} docs. This may take some time to start…`);
if(progress) progress.print();

const results = { ok:[], failed:{} };

const progress = log.level > log.LEVEL_ERROR ?
progressBar.init(totalCount, '{{n}}/{{N}} docs ', ' {{%}} {{m}}:{{s}}') : null;

return processNextBatch(docFiles, 100);

function processNextBatch(docFiles, batchSize) {
if(!docFiles.length) {
if(progress) progress.done();
info('Upload failed for:\n' + JSON.stringify(results.failed, null, 2));
info(`Summary: ${results.ok.length} of ${totalCount} docs uploaded OK.`);
return Promise.resolve();
Expand All @@ -56,10 +56,7 @@ module.exports = (projectDir, couchUrl) => {

return db.bulkDocs(docs)
.then(res => {
if(progress) {
progress.increment(docs.length);
progress.print();
}
if(progress) progress.inc(docs.length);
res.forEach(r => {
if(r.error) {
results.failed[r.id] = `${r.error}: ${r.reason}`;
Expand Down
58 changes: 43 additions & 15 deletions src/lib/progress-bar.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
module.exports = {
init: function(target, message) {
init: function(target, prefix, suffix) {
let runningTotal = 0;
if(!message) message = '';
let startTime = Date.now();

return {
increment: (inc) => { runningTotal += inc; },
print: () => {
const percent = Math.floor(runningTotal * 100 / target);
let bar = '', i;
function print() {
let bar = '', i;

const timeTaken = Date.now() - startTime;
const timeLeft = Math.floor(timeTaken * (target - runningTotal) / (runningTotal * 1000));

const format = message => message
.replace('{{n}}', runningTotal)
.replace('{{N}}', target)
.replace('{{s}}', () => roundAndPad(timeLeft % 60))
.replace('{{m}}', () => roundAndPad(timeLeft / 60, 1))
.replace('{{%}}', () => roundAndPad(runningTotal * 100 / target, 3, ' ') + '%');

const fPrefix = prefix ? format(prefix) : '';
const fSuffix = suffix ? format(suffix) : '';

const formattedMessage = message.replace('{{N}}', runningTotal).replace('{{M}}', target);
const barTotal = process.stdout.columns - fPrefix.length - fSuffix.length - 2;
const pBarLen = Math.floor(runningTotal * barTotal / target);

const barTotal = process.stdout.columns - formattedMessage.length - 9;
const pBarLen = Math.floor(runningTotal * barTotal / target);
for(i=pBarLen; i>0; --i) bar += '█';

for(i=pBarLen; i>0; --i) bar += '';
for(i=barTotal-pBarLen; i>0; --i) bar += ' ';

for(i=barTotal-pBarLen; i>0; --i) bar += ' ';
process.stdout.write(`\r${fPrefix}[${bar}]${fSuffix}`);
}

process.stdout.write(`\r${formattedMessage}[${bar}] (${percent}%)`);
},
complete: () => runningTotal >= target,
print();

return {
inc: d => { runningTotal += d; print(); },
done: () => { runningTotal = target; print(); console.log(); },
cancel: () => { console.log(); },
};
},
};

function roundAndPad(n, digits, padWith) {
if(typeof digits === 'undefined') digits = 2;
if(typeof padWith === 'undefined') padWith = '0';
n = Math.round(n);
let s;
if(Number.isFinite(n)) s = n.toString();
else {
padWith = '?';
s = '';
}
while(s.length < digits) s = padWith + s;
return s;
}

0 comments on commit 005b416

Please sign in to comment.