Skip to content

Commit

Permalink
refactor(lib/log.js)
Browse files Browse the repository at this point in the history
- eliminate char-spinner dependency
- use simplified internal spinner adapted from char-spinner
- coverage at 100%

Signed-off-by: Rick Waldron <waldron.rick@gmail.com>
  • Loading branch information
rwaldron committed Jun 23, 2017
1 parent d06d1b7 commit b17e92a
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 113 deletions.
164 changes: 98 additions & 66 deletions lib/log.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

// System Objects
const util = require('util');

// Third Party Dependencies
const charSpinner = require('char-spinner');
const npmlog = require('npmlog');

// "DEBUG ..."
Expand Down Expand Up @@ -62,13 +63,10 @@ npmlog.addLevel('error', 6000, {
bg: 'black'
}, 'ERR!');



npmlog.level = 'basic';

// Internal
var disabled = false;
var logstream = process.stderr;
let disabled = false;

const flags = {
spinner: true,
Expand All @@ -81,71 +79,101 @@ const flags = {
error: true,
};

const spinner = {
interval: null,
start() {
// When there is an active spinner, or spinners are
// disabled, return immediately.
if (this.interval !== null || disabled || exports.isDisabled('spinner')) {
return;
Object.assign(exports, {
//
// Adapted from char-spinner
//
charSpinner(options) {
options = options || {};
const cleanup = typeof options.cleanup !== 'undefined' ? options.cleanup : true;
const ms = typeof options.ms !== 'undefined' ? options.ms : 50;
// '▏▎▍▌▋▊▉█'?
const sprite = (typeof options.sprite !== 'undefined' ? options.sprite : '-\\|/').split('');
const stream = typeof options.stream !== 'undefined' ? options.stream : process.stderr;

const CARRIAGE_RETURN = stream.isTTY ? '\x1B[0G' : '\r';
const CLEAR = stream.isTTY ? '\x1B[2K' : '\r \r';

let index = 0;
let wrote = false;
let delay = typeof options.delay !== 'undefined' ? options.delay : 2;
let interval = setInterval(() => {
if (--delay >= 0) {
return;
}
index = ++index % sprite.length;
stream.write(`${sprite[index]}${CARRIAGE_RETURN}`);
wrote = true;
}, ms);

/* istanbul ignore else */
if (cleanup) {
process.on('exit', () => {
/* istanbul ignore else */
if (wrote) {
stream.write(CLEAR);
}
});
}

this.interval = exports.charSpinner({
cleanup: true,
stream: logstream,
tty: false,
});
exports.charSpinner.clear = () => {
stream.write(CLEAR);
exports.charSpinner.clear = null;
};

return interval;
},
spinner: {
interval: null,
start() {
// When there is an active spinner, or spinners are
// disabled, return immediately.
if (exports.spinner.interval !== null ||
disabled || exports.isDisabled('spinner')) {
return;
}
exports.spinner.interval = exports.charSpinner();
},
stop() {
if (exports.spinner.interval !== null) {
clearInterval(exports.spinner.interval);
exports.spinner.interval = null;
}

if (exports.charSpinner.clear) {
exports.charSpinner.clear();
}
},
},
stop() {
if (this.interval !== null) {
clearInterval(this.interval);
this.interval = null;
// Set a logging level
level(level) {
if (level) {
npmlog.level = level;
} else {
return npmlog.level;
}
}
};

exports.charSpinner = function(options) {
return charSpinner(options);
};

// Spinner control interface
exports.spinner = spinner;


// Set the logging level
exports.level = function(level) {
if (level) {
npmlog.level = level;
} else {
return npmlog.level;
}
};


// Enable or disable ALL logging.
exports.disable = function() {
disabled = true;
};
exports.enable = function() {
disabled = false;
};

// Configure 1 or more log level flags
exports.configure = function(uFlags) {
if (typeof uFlags !== 'object' || uFlags === null) {
throw new Error('Invalid log level configuration flags');
}
Object.assign(flags, uFlags);
};

// Check if a log level is enabled or disabled
exports.isEnabled = function(flag) {
return flags[flag] === true;
};
exports.isDisabled = function(flag) {
return flags[flag] === false;
};

},
// Enable or disable ALL logging.
disable() {
disabled = true;
},
enable() {
disabled = false;
},
// Configure logging flags
configure(uFlags) {
if (typeof uFlags !== 'object' || uFlags === null) {
throw new Error('Invalid log level configuration flags');
}
Object.assign(flags, uFlags);
},
isEnabled(flag) {
return flags[flag] === true;
},
isDisabled(flag) {
return flags[flag] === false;
},
});
// Logging
[
'debug',
Expand All @@ -157,6 +185,10 @@ exports.isDisabled = function(flag) {
'warn',
'error',
].forEach(level => {
// Needs to be a function expression to ensure access
// to `arguments` object. Once we leave Node.js 4.x.x
// behind, we can migrate to an arrow with explicit
// rest `...args`.
exports[level] = function() {
if (disabled || exports.isDisabled(level)) {
return;
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@
"grunt-jscs": "^3.0.1",
"mkdirp": "^0.5.1",
"nyc": "^8.3.2",
"sinon": "^1.14.1"
"sinon": "^1.17.7"
},
"dependencies": {
"async": "^1.4.2",
"bindings": "^1.2.1",
"block-stream2": "^1.1.0",
"char-spinner": "^1.0.1",
"colors": "^1.1.0",
"common-tags": "0.0.1",
"fs-extra": "^0.26.2",
Expand All @@ -67,7 +66,7 @@
"node-rsa": "^0.2.26",
"nomnom": "^1.8.1",
"npm": "^2.7.1",
"npmlog": "^4.0.0",
"npmlog": "^4.1.0",
"osenv": "^0.1.0",
"promzard": "^0.3.0",
"request": "^2.60.0",
Expand Down
1 change: 0 additions & 1 deletion test/common/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ global.Transform = stream.Transform;
// Third Party Dependencies
global.async = require('async');
global.bindings = require('bindings');
global.charSpinner = require('char-spinner');
global.colors = require('colors');
global.concat = require('concat-stream');
global.fs = require('fs-extra');
Expand Down
Loading

0 comments on commit b17e92a

Please sign in to comment.