feat: remove colors in favour of chalk (#10142)

* feat: remove colors in favour of chalk

* fix: bad conversion from colors to chalk in src/cli/index.js

* fix: padWidth calculation to account for control characters

* fix: termWidth calculation, but swapped one problem for another

* fix: formatItem, implement my own padRight to take control characters into account
isekai-main
Julian Lam 3 years ago committed by GitHub
parent c7a5643932
commit cf8f62aed9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -38,6 +38,7 @@
"body-parser": "1.19.1", "body-parser": "1.19.1",
"bootbox": "5.5.2", "bootbox": "5.5.2",
"bootstrap": "3.4.1", "bootstrap": "3.4.1",
"chalk": "4.1.2",
"chart.js": "2.9.4", "chart.js": "2.9.4",
"cli-graph": "3.2.2", "cli-graph": "3.2.2",
"clipboard": "2.0.9", "clipboard": "2.0.9",

@ -4,7 +4,8 @@
// to include color styling in the output // to include color styling in the output
// so the CLI looks nice // so the CLI looks nice
const { Command, Help } = require('commander'); const { Command } = require('commander');
const chalk = require('chalk');
const colors = [ const colors = [
// depth = 0, top-level command // depth = 0, top-level command
@ -23,6 +24,11 @@ function humanReadableArgName(arg) {
return arg.required ? `<${nameOutput}>` : `[${nameOutput}]`; return arg.required ? `<${nameOutput}>` : `[${nameOutput}]`;
} }
function getControlCharacterSpaces(term) {
const matches = term.match(/.\[\d+m/g);
return matches ? matches.length * 5 : 0;
}
// get depth of command // get depth of command
// 0 = top, 1 = subcommand of top, etc // 0 = top, 1 = subcommand of top, etc
Command.prototype.depth = function () { Command.prototype.depth = function () {
@ -49,38 +55,50 @@ module.exports = {
let parentCmd = cmd.parent; let parentCmd = cmd.parent;
let parentDepth = depth - 1; let parentDepth = depth - 1;
while (parentCmd) { while (parentCmd) {
parentCmdNames = `${parentCmd.name()[colors[parentDepth].command]} ${parentCmdNames}`; parentCmdNames = `${chalk[colors[parentDepth].command](parentCmd.name())} ${parentCmdNames}`;
parentCmd = parentCmd.parent; parentCmd = parentCmd.parent;
parentDepth -= 1; parentDepth -= 1;
} }
// from Command.prototype.usage() // from Command.prototype.usage()
const args = cmd._args.map(arg => humanReadableArgName(arg)[colors[depth].arg]); const args = cmd._args.map(arg => chalk[colors[depth].arg](humanReadableArgName(arg)));
const cmdUsage = [].concat( const cmdUsage = [].concat(
(cmd.options.length || cmd._hasHelpOption ? '[options]'[colors[depth].option] : []), (cmd.options.length || cmd._hasHelpOption ? chalk[colors[depth].option]('[options]') : []),
(cmd.commands.length ? '[command]'[colors[depth + 1].command] : []), (cmd.commands.length ? chalk[colors[depth + 1].command]('[command]') : []),
(cmd._args.length ? args : []) (cmd._args.length ? args : [])
).join(' '); ).join(' ');
return `${parentCmdNames}${cmdName[colors[depth].command]} ${cmdUsage}`; return `${parentCmdNames}${chalk[colors[depth].command](cmdName)} ${cmdUsage}`;
}, },
subcommandTerm(cmd) { subcommandTerm(cmd) {
const depth = cmd.depth(); const depth = cmd.depth();
// Legacy. Ignores custom usage string, and nested commands. // Legacy. Ignores custom usage string, and nested commands.
const args = cmd._args.map(arg => humanReadableArgName(arg)).join(' '); const args = cmd._args.map(arg => humanReadableArgName(arg)).join(' ');
return (cmd._name + ( return chalk[colors[depth].command](cmd._name + (
cmd._aliases[0] ? `|${cmd._aliases[0]}` : '' cmd._aliases[0] ? `|${cmd._aliases[0]}` : ''
))[colors[depth].command] + )) +
(cmd.options.length ? ' [options]' : '')[colors[depth].option] + // simplistic check for non-help option chalk[colors[depth].option](cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option
(args ? ` ${args}` : '')[colors[depth].arg]; chalk[colors[depth].arg](args ? ` ${args}` : '');
}, },
longestOptionTermLength(cmd, helper) { longestOptionTermLength(cmd, helper) {
return Help.prototype.longestOptionTermLength.call(this, cmd, helper) + ''.red.length; return helper.visibleOptions(cmd).reduce((max, option) => Math.max(
max,
helper.optionTerm(option).length - getControlCharacterSpaces(helper.optionTerm(option))
), 0);
},
longestSubcommandTermLength(cmd, helper) {
return helper.visibleCommands(cmd).reduce((max, command) => Math.max(
max,
helper.subcommandTerm(command).length - getControlCharacterSpaces(helper.subcommandTerm(command))
), 0);
}, },
longestArgumentTermLength(cmd, helper) { longestArgumentTermLength(cmd, helper) {
return Help.prototype.longestArgumentTermLength.call(this, cmd, helper) + ''.red.length; return helper.visibleArguments(cmd).reduce((max, argument) => Math.max(
max,
helper.argumentTerm(argument).length - getControlCharacterSpaces(helper.argumentTerm(argument))
), 0);
}, },
formatHelp(cmd, helper) { formatHelp(cmd, helper) {
const depth = cmd.depth(); const depth = cmd.depth();
@ -90,8 +108,9 @@ module.exports = {
const itemIndentWidth = 2; const itemIndentWidth = 2;
const itemSeparatorWidth = 2; // between term and description const itemSeparatorWidth = 2; // between term and description
function formatItem(term, description) { function formatItem(term, description) {
const padding = ' '.repeat((termWidth + itemSeparatorWidth) - (term.length - getControlCharacterSpaces(term)));
if (description) { if (description) {
const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`; const fullText = `${term}${padding}${description}`;
return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth); return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
} }
return term; return term;
@ -111,7 +130,7 @@ module.exports = {
// Arguments // Arguments
const argumentList = helper.visibleArguments(cmd).map(argument => formatItem( const argumentList = helper.visibleArguments(cmd).map(argument => formatItem(
argument.term[colors[depth].arg], chalk[colors[depth].arg](argument.term),
argument.description argument.description
)); ));
if (argumentList.length > 0) { if (argumentList.length > 0) {
@ -120,7 +139,7 @@ module.exports = {
// Options // Options
const optionList = helper.visibleOptions(cmd).map(option => formatItem( const optionList = helper.visibleOptions(cmd).map(option => formatItem(
helper.optionTerm(option)[colors[depth].option], chalk[colors[depth].option](helper.optionTerm(option)),
helper.optionDescription(option) helper.optionDescription(option)
)); ));
if (optionList.length > 0) { if (optionList.length > 0) {

@ -22,10 +22,10 @@ try {
packageInstall.preserveExtraneousPlugins(); packageInstall.preserveExtraneousPlugins();
try { try {
fs.accessSync(path.join(paths.nodeModules, 'colors/package.json'), fs.constants.R_OK); fs.accessSync(path.join(paths.nodeModules, 'chalk/package.json'), fs.constants.R_OK);
require('colors'); const chalk = require('chalk');
console.log('OK'.green); console.log(chalk.green('OK'));
} catch (e) { } catch (e) {
console.log('OK'); console.log('OK');
} }
@ -52,7 +52,7 @@ try {
checkVersion('nconf'); checkVersion('nconf');
checkVersion('async'); checkVersion('async');
checkVersion('commander'); checkVersion('commander');
checkVersion('colors'); checkVersion('chalk');
} catch (e) { } catch (e) {
if (['ENOENT', 'DEP_WRONG_VERSION', 'MODULE_NOT_FOUND'].includes(e.code)) { if (['ENOENT', 'DEP_WRONG_VERSION', 'MODULE_NOT_FOUND'].includes(e.code)) {
console.warn('Dependencies outdated or not yet installed.'); console.warn('Dependencies outdated or not yet installed.');
@ -61,14 +61,14 @@ try {
packageInstall.updatePackageFile(); packageInstall.updatePackageFile();
packageInstall.installAll(); packageInstall.installAll();
require('colors'); const chalk = require('chalk');
console.log('OK'.green + '\n'.reset); console.log(`${chalk.green('OK')}\n`);
} else { } else {
throw e; throw e;
} }
} }
require('colors'); const chalk = require('chalk');
const nconf = require('nconf'); const nconf = require('nconf');
const { program } = require('commander'); const { program } = require('commander');
const yargs = require('yargs'); const yargs = require('yargs');
@ -173,7 +173,7 @@ program
try { try {
initConfig = JSON.parse(initConfig); initConfig = JSON.parse(initConfig);
} catch (e) { } catch (e) {
console.warn('Invalid JSON passed as initial config value.'.red); console.warn(chalk.red('Invalid JSON passed as initial config value.'));
console.log('If you meant to pass in an initial config value, please try again.\n'); console.log('If you meant to pass in an initial config value, please try again.\n');
throw e; throw e;
@ -190,7 +190,7 @@ program
}); });
program program
.command('build [targets...]') .command('build [targets...]')
.description(`Compile static assets ${'(JS, CSS, templates, languages)'.red}`) .description(`Compile static assets ${chalk.red('(JS, CSS, templates, languages)')}`)
.option('-s, --series', 'Run builds in series without extra processes') .option('-s, --series', 'Run builds in series without extra processes')
.action((targets, options) => { .action((targets, options) => {
if (program.opts().dev) { if (program.opts().dev) {
@ -240,7 +240,7 @@ resetCommand
.action((options) => { .action((options) => {
const valid = ['theme', 'plugin', 'widgets', 'settings', 'all'].some(x => options[x]); const valid = ['theme', 'plugin', 'widgets', 'settings', 'all'].some(x => options[x]);
if (!valid) { if (!valid) {
console.warn('\n No valid options passed in, so nothing was reset.'.red); console.warn(`\n${chalk.red('No valid options passed in, so nothing was reset.')}`);
resetCommand.help(); resetCommand.help();
} }
@ -270,8 +270,8 @@ program
console.log(`\n${[ console.log(`\n${[
'When running particular upgrade scripts, options are ignored.', 'When running particular upgrade scripts, options are ignored.',
'By default all options are enabled. Passing any options disables that default.', 'By default all options are enabled. Passing any options disables that default.',
`Only package and dependency updates: ${'./nodebb upgrade -mi'.yellow}`, `Only package and dependency updates: ${chalk.yellow('./nodebb upgrade -mi')}`,
`Only database update: ${'./nodebb upgrade -s'.yellow}`, `Only database update: ${chalk.yellow('./nodebb upgrade -s')}`,
].join('\n')}`); ].join('\n')}`);
}) })
.action((scripts, options) => { .action((scripts, options) => {
@ -289,7 +289,7 @@ program
if (err) { if (err) {
throw err; throw err;
} }
console.log('OK'.green); console.log(chalk.green('OK'));
process.exit(); process.exit();
}); });
}); });

@ -3,6 +3,7 @@
const winston = require('winston'); const winston = require('winston');
const childProcess = require('child_process'); const childProcess = require('child_process');
const CliGraph = require('cli-graph'); const CliGraph = require('cli-graph');
const chalk = require('chalk');
const build = require('../meta/build'); const build = require('../meta/build');
const db = require('../database'); const db = require('../database');
@ -76,9 +77,9 @@ async function listPlugins() {
process.stdout.write('Active plugins:\n'); process.stdout.write('Active plugins:\n');
combined.forEach((plugin) => { combined.forEach((plugin) => {
process.stdout.write(`\t* ${plugin.id}${plugin.version ? `@${plugin.version}` : ''} (`); process.stdout.write(`\t* ${plugin.id}${plugin.version ? `@${plugin.version}` : ''} (`);
process.stdout.write(plugin.installed ? 'installed'.green : 'not installed'.red); process.stdout.write(plugin.installed ? chalk.green('installed') : chalk.red('not installed'));
process.stdout.write(', '); process.stdout.write(', ');
process.stdout.write(plugin.active ? 'enabled'.green : 'disabled'.yellow); process.stdout.write(plugin.active ? chalk.green('enabled') : chalk.yellow('disabled'));
process.stdout.write(')\n'); process.stdout.write(')\n');
}); });
@ -88,9 +89,9 @@ async function listPlugins() {
async function listEvents(count = 10) { async function listEvents(count = 10) {
await db.init(); await db.init();
const eventData = await events.getEvents('', 0, count - 1); const eventData = await events.getEvents('', 0, count - 1);
console.log((`\nDisplaying last ${count} administrative events...`).bold); console.log(chalk.bold(`\nDisplaying last ${count} administrative events...`));
eventData.forEach((event) => { eventData.forEach((event) => {
console.log(` * ${String(event.timestampISO).green} ${String(event.type).yellow}${event.text ? ` ${event.text}` : ''}${' (uid: '.reset}${event.uid ? event.uid : 0})`); console.log(` * ${chalk.green(String(event.timestampISO))} ${chalk.yellow(String(event.type))}${event.text ? ` ${event.text}` : ''} (uid: ${event.uid ? event.uid : 0})`);
}); });
process.exit(); process.exit();
} }

@ -1,9 +1,9 @@
'use strict'; 'use strict';
require('colors');
const path = require('path'); const path = require('path');
const winston = require('winston'); const winston = require('winston');
const fs = require('fs'); const fs = require('fs');
const chalk = require('chalk');
const db = require('../database'); const db = require('../database');
const events = require('../events'); const events = require('../events');
@ -57,8 +57,8 @@ exports.reset = async function (options) {
if (!tasks.length) { if (!tasks.length) {
console.log([ console.log([
'No arguments passed in, so nothing was reset.\n'.yellow, chalk.yellow('No arguments passed in, so nothing was reset.\n'),
`Use ./nodebb reset ${'{-t|-p|-w|-s|-a}'.red}`, `Use ./nodebb reset ${chalk.red('{-t|-p|-w|-s|-a}')}`,
' -t\tthemes', ' -t\tthemes',
' -p\tplugins', ' -p\tplugins',
' -w\twidgets', ' -w\twidgets',

@ -2,6 +2,7 @@
const fs = require('fs'); const fs = require('fs');
const childProcess = require('child_process'); const childProcess = require('child_process');
const chalk = require('chalk');
const fork = require('../meta/debugFork'); const fork = require('../meta/debugFork');
const { paths } = require('../constants'); const { paths } = require('../constants');
@ -39,17 +40,17 @@ function start(options) {
} }
if (options.log) { if (options.log) {
console.log(`\n${[ console.log(`\n${[
'Starting NodeBB with logging output'.bold, chalk.bold('Starting NodeBB with logging output'),
'Hit '.red + 'Ctrl-C '.bold + 'to exit'.red, chalk.red('Hit ') + chalk.bold('Ctrl-C ') + chalk.red('to exit'),
'The NodeBB process will continue to run in the background', 'The NodeBB process will continue to run in the background',
`Use "${'./nodebb stop'.yellow}" to stop the NodeBB server`, `Use "${chalk.yellow('./nodebb stop')}" to stop the NodeBB server`,
].join('\n')}`); ].join('\n')}`);
} else if (!options.silent) { } else if (!options.silent) {
console.log(`\n${[ console.log(`\n${[
'Starting NodeBB'.bold, chalk.bold('Starting NodeBB'),
` "${'./nodebb stop'.yellow}" to stop the NodeBB server`, ` "${chalk.yellow('./nodebb stop')}" to stop the NodeBB server`,
` "${'./nodebb log'.yellow}" to view server output`, ` "${chalk.yellow('./nodebb log')}" to view server output`,
` "${'./nodebb help'.yellow}${'" for more commands\n'.reset}`, ` "${chalk.yellow('./nodebb help')}" for more commands\n`,
].join('\n')}`); ].join('\n')}`);
} }
@ -82,7 +83,7 @@ function stop() {
function restart(options) { function restart(options) {
getRunningPid((err, pid) => { getRunningPid((err, pid) => {
if (!err) { if (!err) {
console.log('\nRestarting NodeBB'.bold); console.log(chalk.bold('\nRestarting NodeBB'));
process.kill(pid, 'SIGTERM'); process.kill(pid, 'SIGTERM');
options.silent = true; options.silent = true;
@ -97,20 +98,20 @@ function status() {
getRunningPid((err, pid) => { getRunningPid((err, pid) => {
if (!err) { if (!err) {
console.log(`\n${[ console.log(`\n${[
'NodeBB Running '.bold + (`(pid ${pid.toString()})`).cyan, chalk.bold('NodeBB Running ') + chalk.cyan(`(pid ${pid.toString()})`),
`\t"${'./nodebb stop'.yellow}" to stop the NodeBB server`, `\t"${chalk.yellow('./nodebb stop')}" to stop the NodeBB server`,
`\t"${'./nodebb log'.yellow}" to view server output`, `\t"${chalk.yellow('./nodebb log')}" to view server output`,
`\t"${'./nodebb restart'.yellow}" to restart NodeBB\n`, `\t"${chalk.yellow('./nodebb restart')}" to restart NodeBB\n`,
].join('\n')}`); ].join('\n')}`);
} else { } else {
console.log('\nNodeBB is not running'.bold); console.log(chalk.bold('\nNodeBB is not running'));
console.log(`\t"${'./nodebb start'.yellow}${'" to launch the NodeBB server\n'.reset}`); console.log(`\t"${chalk.yellow('./nodebb start')}" to launch the NodeBB server\n`);
} }
}); });
} }
function log() { function log() {
console.log('\nHit '.red + 'Ctrl-C '.bold + 'to exit\n'.red + '\n'.reset); console.log(`${chalk.red('\nHit ') + chalk.bold('Ctrl-C ') + chalk.red('to exit\n')}\n`);
childProcess.spawn('tail', ['-F', './logs/output.log'], { childProcess.spawn('tail', ['-F', './logs/output.log'], {
stdio: 'inherit', stdio: 'inherit',
cwd, cwd,

@ -7,6 +7,7 @@ const semver = require('semver');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const nconf = require('nconf'); const nconf = require('nconf');
const chalk = require('chalk');
const { paths, pluginNamePattern } = require('../constants'); const { paths, pluginNamePattern } = require('../constants');
@ -96,11 +97,11 @@ async function checkPlugins() {
const toCheck = Object.keys(plugins); const toCheck = Object.keys(plugins);
if (!toCheck.length) { if (!toCheck.length) {
process.stdout.write(' OK'.green + ''.reset); process.stdout.write(chalk.green(' OK'));
return []; // no extraneous plugins installed return []; // no extraneous plugins installed
} }
const suggestedModules = await getSuggestedModules(nbbVersion, toCheck); const suggestedModules = await getSuggestedModules(nbbVersion, toCheck);
process.stdout.write(' OK'.green + ''.reset); process.stdout.write(chalk.green(' OK'));
let current; let current;
let suggested; let suggested;
@ -125,12 +126,12 @@ async function upgradePlugins() {
try { try {
const found = await checkPlugins(); const found = await checkPlugins();
if (found && found.length) { if (found && found.length) {
process.stdout.write(`\n\nA total of ${String(found.length).bold} package(s) can be upgraded:\n\n`); process.stdout.write(`\n\nA total of ${chalk.bold(String(found.length))} package(s) can be upgraded:\n\n`);
found.forEach((suggestObj) => { found.forEach((suggestObj) => {
process.stdout.write(`${' * '.yellow + suggestObj.name.reset} (${suggestObj.current.yellow}${' -> '.reset}${suggestObj.suggested.green}${')\n'.reset}`); process.stdout.write(`${chalk.yellow(' * ') + suggestObj.name} (${chalk.yellow(suggestObj.current)}' -> '${chalk.green(suggestObj.suggested)}')\n'`);
}); });
} else { } else {
console.log('\nAll packages up-to-date!'.green + ''.reset); console.log(chalk.green('\nAll packages up-to-date!'));
return; return;
} }
@ -140,7 +141,7 @@ async function upgradePlugins() {
prompt.start(); prompt.start();
const result = await prompt.get({ const result = await prompt.get({
name: 'upgrade', name: 'upgrade',
description: '\nProceed with upgrade (y|n)?'.reset, description: '\nProceed with upgrade (y|n)?',
type: 'string', type: 'string',
}); });
@ -150,10 +151,10 @@ async function upgradePlugins() {
cproc.execFileSync(packageManagerExecutable, args, { stdio: 'ignore' }); cproc.execFileSync(packageManagerExecutable, args, { stdio: 'ignore' });
} else { } else {
console.log('Package upgrades skipped'.yellow + '. Check for upgrades at any time by running "'.reset + './nodebb upgrade -p'.green + '".'.reset); console.log(`${chalk.yellow('Package upgrades skipped')}. Check for upgrades at any time by running "${chalk.green('./nodebb upgrade -p')}".`);
} }
} catch (err) { } catch (err) {
console.log('Warning'.yellow + ': An unexpected error occured when attempting to verify plugin upgradability'.reset); console.log(`${chalk.yellow('Warning')}: An unexpected error occured when attempting to verify plugin upgradability`);
throw err; throw err;
} }
} }

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const nconf = require('nconf'); const nconf = require('nconf');
const chalk = require('chalk');
const packageInstall = require('./package-install'); const packageInstall = require('./package-install');
const { upgradePlugins } = require('./upgrade-plugins'); const { upgradePlugins } = require('./upgrade-plugins');
@ -11,13 +12,13 @@ const steps = {
handler: function () { handler: function () {
packageInstall.updatePackageFile(); packageInstall.updatePackageFile();
packageInstall.preserveExtraneousPlugins(); packageInstall.preserveExtraneousPlugins();
process.stdout.write(' OK\n'.green); process.stdout.write(chalk.green(' OK\n'));
}, },
}, },
install: { install: {
message: 'Bringing base dependencies up to date...', message: 'Bringing base dependencies up to date...',
handler: function () { handler: function () {
process.stdout.write(' started\n'.green); process.stdout.write(chalk.green(' started\n'));
packageInstall.installAll(); packageInstall.installAll();
}, },
}, },
@ -49,7 +50,7 @@ async function runSteps(tasks) {
for (let i = 0; i < tasks.length; i++) { for (let i = 0; i < tasks.length; i++) {
const step = steps[tasks[i]]; const step = steps[tasks[i]];
if (step && step.message && step.handler) { if (step && step.message && step.handler) {
process.stdout.write(`\n${(`${i + 1}. `).bold}${step.message.yellow}`); process.stdout.write(`\n${chalk.bold(`${i + 1}. `)}${chalk.yellow(step.message)}`);
/* eslint-disable-next-line */ /* eslint-disable-next-line */
await step.handler(); await step.handler();
} }
@ -60,7 +61,7 @@ async function runSteps(tasks) {
const { columns } = process.stdout; const { columns } = process.stdout;
const spaces = columns ? new Array(Math.floor(columns / 2) - (message.length / 2) + 1).join(' ') : ' '; const spaces = columns ? new Array(Math.floor(columns / 2) - (message.length / 2) + 1).join(' ') : ' ';
console.log(`\n\n${spaces}${message.green.bold}${'\n'.reset}`); console.log(`\n\n${spaces}${chalk.green.bold(message)}\n`);
process.exit(); process.exit();
} catch (err) { } catch (err) {
@ -70,7 +71,7 @@ async function runSteps(tasks) {
} }
async function runUpgrade(upgrades, options) { async function runUpgrade(upgrades, options) {
console.log('\nUpdating NodeBB...'.cyan); console.log(chalk.cyan('\nUpdating NodeBB...'));
options = options || {}; options = options || {};
// disable mongo timeouts during upgrade // disable mongo timeouts during upgrade
nconf.set('mongo:options:socketTimeoutMS', 0); nconf.set('mongo:options:socketTimeoutMS', 0);

@ -1,10 +1,10 @@
'use strict'; 'use strict';
const colors = require('colors/safe');
const nconf = require('nconf'); const nconf = require('nconf');
const validator = require('validator'); const validator = require('validator');
const querystring = require('querystring'); const querystring = require('querystring');
const _ = require('lodash'); const _ = require('lodash');
const chalk = require('chalk');
const translator = require('../translator'); const translator = require('../translator');
const user = require('../user'); const user = require('../user');
@ -451,7 +451,7 @@ helpers.formatApiResponse = async (statusCode, res, payload) => {
if (global.env === 'development') { if (global.env === 'development') {
returnPayload.stack = payload.stack; returnPayload.stack = payload.stack;
process.stdout.write(`[${colors.yellow('api')}] Exception caught, error with stack trace follows:\n`); process.stdout.write(`[${chalk.yellow('api')}] Exception caught, error with stack trace follows:\n`);
process.stdout.write(payload.stack); process.stdout.write(payload.stack);
} }
res.status(statusCode).json(returnPayload); res.status(statusCode).json(returnPayload);

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const _ = require('lodash'); const _ = require('lodash');
const chalk = require('chalk');
const aliases = { const aliases = {
'plugin static dirs': ['staticdirs'], 'plugin static dirs': ['staticdirs'],
@ -30,7 +31,7 @@ function buildTargets() {
} }
return [name, arr.join(', ')]; return [name, arr.join(', ')];
}).map(tuple => ` ${_.padEnd(`"${tuple[0]}"`, length + 2).magenta} | ${tuple[1]}`).join('\n'); }).map(tuple => ` ${chalk.magenta(_.padEnd(`"${tuple[0]}"`, length + 2))} | ${tuple[1]}`).join('\n');
console.log( console.log(
`\n\n Build targets:\n${ `\n\n Build targets:\n${
(`\n ${_.padEnd('Target', length + 2)} | Aliases`).green (`\n ${_.padEnd('Target', length + 2)} | Aliases`).green

@ -6,6 +6,7 @@ const nconf = require('nconf');
const _ = require('lodash'); const _ = require('lodash');
const path = require('path'); const path = require('path');
const mkdirp = require('mkdirp'); const mkdirp = require('mkdirp');
const chalk = require('chalk');
const cacheBuster = require('./cacheBuster'); const cacheBuster = require('./cacheBuster');
const { aliases } = require('./aliases'); const { aliases } = require('./aliases');
@ -60,8 +61,7 @@ const aliasMap = Object.keys(aliases).reduce((prev, key) => {
async function beforeBuild(targets) { async function beforeBuild(targets) {
const db = require('../database'); const db = require('../database');
require('colors'); process.stdout.write(`${chalk.green(' started')}\n`);
process.stdout.write(' started'.green + '\n'.reset);
try { try {
await db.init(); await db.init();
meta = require('./index'); meta = require('./index');

@ -5,7 +5,7 @@ const fs = require('fs');
const semver = require('semver'); const semver = require('semver');
const winston = require('winston'); const winston = require('winston');
require('colors'); const chalk = require('chalk');
const pkg = require('../../package.json'); const pkg = require('../../package.json');
const { paths, pluginNamePattern } = require('../constants'); const { paths, pluginNamePattern } = require('../constants');
@ -49,7 +49,7 @@ Dependencies.parseModuleData = function (moduleName, pkgData) {
try { try {
pkgData = JSON.parse(pkgData); pkgData = JSON.parse(pkgData);
} catch (e) { } catch (e) {
winston.warn(`[${'missing'.red}] ${moduleName.bold} is a required dependency but could not be found\n`); winston.warn(`[${chalk.red('missing')}] ${chalk.bold(moduleName)} is a required dependency but could not be found\n`);
depsMissing = true; depsMissing = true;
return null; return null;
} }
@ -64,7 +64,7 @@ Dependencies.doesSatisfy = function (moduleData, packageJSONVersion) {
const githubRepo = moduleData._resolved && moduleData._resolved.includes('//github.com'); const githubRepo = moduleData._resolved && moduleData._resolved.includes('//github.com');
const satisfies = versionOk || githubRepo; const satisfies = versionOk || githubRepo;
if (!satisfies) { if (!satisfies) {
winston.warn(`[${'outdated'.yellow}] ${moduleData.name.bold} installed v${moduleData.version}, package.json requires ${packageJSONVersion}\n`); winston.warn(`[${chalk.yellow('outdated')}] ${chalk.bold(moduleData.name)} installed v${moduleData.version}, package.json requires ${packageJSONVersion}\n`);
depsOutdated = true; depsOutdated = true;
} }
return satisfies; return satisfies;

@ -5,6 +5,7 @@ const path = require('path');
const winston = require('winston'); const winston = require('winston');
const semver = require('semver'); const semver = require('semver');
const nconf = require('nconf'); const nconf = require('nconf');
const chalk = require('chalk');
const request = require('request-promise-native'); const request = require('request-promise-native');
const user = require('../user'); const user = require('../user');
@ -117,7 +118,7 @@ Plugins.reload = async function () {
console.log(''); console.log('');
winston.warn('[plugins/load] The following plugins may not be compatible with your version of NodeBB. This may cause unintended behaviour or crashing. In the event of an unresponsive NodeBB caused by this plugin, run `./nodebb reset -p PLUGINNAME` to disable it.'); winston.warn('[plugins/load] The following plugins may not be compatible with your version of NodeBB. This may cause unintended behaviour or crashing. In the event of an unresponsive NodeBB caused by this plugin, run `./nodebb reset -p PLUGINNAME` to disable it.');
for (let x = 0, numPlugins = Plugins.versionWarning.length; x < numPlugins; x += 1) { for (let x = 0, numPlugins = Plugins.versionWarning.length; x < numPlugins; x += 1) {
console.log(' * '.yellow + Plugins.versionWarning[x]); console.log(`${chalk.yellow(' * ') + Plugins.versionWarning[x]}`);
} }
console.log(''); console.log('');
} }

@ -4,6 +4,7 @@ const nconf = require('nconf');
const url = require('url'); const url = require('url');
const winston = require('winston'); const winston = require('winston');
const path = require('path'); const path = require('path');
const chalk = require('chalk');
const pkg = require('../package.json'); const pkg = require('../package.json');
const { paths } = require('./constants'); const { paths } = require('./constants');
@ -111,7 +112,7 @@ function versionCheck() {
if (!compatible) { if (!compatible) {
winston.warn('Your version of Node.js is too outdated for NodeBB. Please update your version of Node.js.'); winston.warn('Your version of Node.js is too outdated for NodeBB. Please update your version of Node.js.');
winston.warn(`Recommended ${range.green}${', '.reset}${version.yellow}${' provided\n'.reset}`); winston.warn(`Recommended ${chalk.green(range)}, ${chalk.yellow(version)} provided\n`);
} }
} }

@ -6,6 +6,7 @@ const util = require('util');
const semver = require('semver'); const semver = require('semver');
const readline = require('readline'); const readline = require('readline');
const winston = require('winston'); const winston = require('winston');
const chalk = require('chalk');
const db = require('./database'); const db = require('./database');
const file = require('./file'); const file = require('./file');
@ -118,7 +119,7 @@ Upgrade.runParticular = async function (names) {
}; };
Upgrade.process = async function (files, skipCount) { Upgrade.process = async function (files, skipCount) {
console.log('OK'.green + ' | '.reset + String(files.length).cyan + ' script(s) found'.cyan + (skipCount > 0 ? ', '.cyan + String(skipCount).cyan + ' skipped'.cyan : '')); console.log(`${chalk.green('OK')} | ${chalk.cyan(`${files.length} script(s) found`)}${skipCount > 0 ? chalk.cyan(`, ${skipCount} skipped`) : ''}`);
const [schemaDate, schemaLogCount] = await Promise.all([ const [schemaDate, schemaLogCount] = await Promise.all([
db.get('schemaDate'), db.get('schemaDate'),
db.sortedSetCard('schemaLog'), db.sortedSetCard('schemaLog'),
@ -138,11 +139,11 @@ Upgrade.process = async function (files, skipCount) {
date: date, date: date,
}; };
process.stdout.write(`${' → '.white + String(`[${[date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate()].join('/')}] `).gray + String(scriptExport.name).reset}...`); process.stdout.write(`${chalk.white(' → ') + chalk.gray(`[${[date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate()].join('/')}] `) + scriptExport.name}...`);
// For backwards compatibility, cross-reference with schemaDate (if found). If a script's date is older, skip it // For backwards compatibility, cross-reference with schemaDate (if found). If a script's date is older, skip it
if ((!schemaDate && !schemaLogCount) || (scriptExport.timestamp <= schemaDate && semver.lt(version, '1.5.0'))) { if ((!schemaDate && !schemaLogCount) || (scriptExport.timestamp <= schemaDate && semver.lt(version, '1.5.0'))) {
process.stdout.write(' skipped\n'.grey); process.stdout.write(chalk.grey(' skipped\n'));
await db.sortedSetAdd('schemaLog', Date.now(), path.basename(file, '.js')); await db.sortedSetAdd('schemaLog', Date.now(), path.basename(file, '.js'));
// eslint-disable-next-line no-continue // eslint-disable-next-line no-continue
@ -165,13 +166,13 @@ Upgrade.process = async function (files, skipCount) {
throw err; throw err;
} }
const upgradeDuration = ((Date.now() - upgradeStart) / 1000).toFixed(2); const upgradeDuration = ((Date.now() - upgradeStart) / 1000).toFixed(2);
process.stdout.write(` OK (${upgradeDuration} seconds)\n`.green); process.stdout.write(chalk.green(` OK (${upgradeDuration} seconds)\n`));
// Record success in schemaLog // Record success in schemaLog
await db.sortedSetAdd('schemaLog', Date.now(), path.basename(file, '.js')); await db.sortedSetAdd('schemaLog', Date.now(), path.basename(file, '.js'));
} }
console.log('Schema update complete!\n'.green); console.log(chalk.green('Schema update complete!\n'));
}; };
Upgrade.incrementProgress = function (value) { Upgrade.incrementProgress = function (value) {

Loading…
Cancel
Save