From 17f2ebb7535f4294975c0bd18e3197493e3a962a Mon Sep 17 00:00:00 2001 From: hacksalot Date: Fri, 15 Jan 2016 23:46:43 -0500 Subject: [PATCH] Modularize messages. ...and move strings out of error.js. --- src/cli/error.js | 54 ++++++++++------------ src/cli/msg.js | 18 ++++++++ src/cli/msg.yml | 118 +++++++++++++++++++++++++++++------------------ src/cli/out.js | 2 +- 4 files changed, 117 insertions(+), 75 deletions(-) create mode 100644 src/cli/msg.js diff --git a/src/cli/error.js b/src/cli/error.js index 4f00a86..68bb810 100644 --- a/src/cli/error.js +++ b/src/cli/error.js @@ -18,6 +18,8 @@ Error-handling routines for HackMyResume. , WRAP = require('word-wrap') , M2C = require('../utils/md2chalk.js') , chalk = require('chalk') + , YAML = require('yamljs') + , printf = require('printf') , SyntaxErrorEx = require('../utils/syntax-error-ex'); require('string.prototype.startswith'); @@ -32,18 +34,23 @@ Error-handling routines for HackMyResume. init: function( debug, assert ) { this.debug = debug; this.assert = assert; + this.msgs = require('./msg.js').errors; return this; }, err: function( ex, shouldExit ) { + if( !this.msgs ) { + this.msgs = require('./msg.js').errors; + } + if( ex.pass ) throw ex; if( ex.fluenterror ) { // Output the error message - var objError = assembleError( ex ); + var objError = assembleError.call( this, ex ); o( this[ 'format' + (objError.warning ? 'Warning' : 'Error')]( objError.msg )); @@ -95,25 +102,20 @@ Error-handling routines for HackMyResume. switch( ex.fluenterror ) { case HACKMYSTATUS.themeNotFound: - msg = - chalk.bold("Couldn't find the '" + ex.data + "' theme."), - " Please specify the name of a preinstalled FRESH theme " + - "or the path to a locally installed FRESH or JSON Resume theme."; + msg = printf( M2C( this.msgs.themeNotFound.msg, 'yellow' ), ex.data); break; case HACKMYSTATUS.copyCSS: - msg = "Couldn't copy CSS file to destination folder."; + msg = M2C( this.msgs.copyCSS.msg, 'red' ); quit = false; break; case HACKMYSTATUS.resumeNotFound: - msg = 'Please ' + chalk.bold('feed me a resume') + - ' in FRESH or JSON Resume format.'; + msg = M2C( this.msgs.resumeNotFound.msg, 'yellow' ); break; case HACKMYSTATUS.missingCommand: - msg = "Please " +chalk.bold("give me a command") + " ("; - + msg = M2C( this.msgs.missingCommand.msg + " (", 'yellow'); msg += Object.keys( FCMD.verbs ).map( function(v, idx, ar) { return (idx === ar.length - 1 ? chalk.yellow('or ') : '') + chalk.yellow.bold(v.toUpperCase()); @@ -124,49 +126,41 @@ Error-handling routines for HackMyResume. break; case HACKMYSTATUS.invalidCommand: - msg = 'Invalid command: "'+chalk.bold(ex.attempted)+'"'; + msg = printf( M2C( this.msgs.invalidCommand.msg, 'yellow'), ex.attempted ); break; case HACKMYSTATUS.resumeNotFoundAlt: - msg = 'Please ' + chalk.bold('feed me a resume') + - ' in either FRESH or JSON Resume format.'; + msg = M2C( this.msgs.resumeNotFoundAlt.msg, 'yellow' ); break; case HACKMYSTATUS.inputOutputParity: - msg = 'Please ' + - chalk.bold('specify an output file name') + - ' for every input file you wish to convert.'; + msg = M2C( this.msgs.inputOutputParity.msg ); break; case HACKMYSTATUS.createNameMissing: - msg = 'Please ' + - chalk.bold('specify the filename of the resume') + ' to create.'; + msg = M2C( this.msgs.createNameMissing.msg ); break; case HACKMYSTATUS.pdfGeneration: - msg = chalk.bold('PDF generation failed. ') + - 'Make sure wkhtmltopdf is installed and accessible from your path.'; + msg = M2C( this.msgs.pdfGeneration.msg, 'bold' ); if( ex.inner ) msg += chalk.red('\n' + ex.inner); withStack = true; quit = false; warn = false; break; case HACKMYSTATUS.invalid: - msg = 'Validation failed and the --assert option was ' + - 'specified.'; + msg = M2C( this.msgs.invalid.msg, 'red' ); warn = false; break; case HACKMYSTATUS.invalidFormat: - ex.data.forEach(function(d){ msg += - 'The ' + chalk.bold(ex.theme.name.toUpperCase()) + - " theme doesn't support the " + chalk.bold(d.format.toUpperCase()) + - " format.\n"; + ex.data.forEach(function(d){ + msg += printf( M2C( this.msgs.invalidFormat.msg, 'bold' ), + ex.theme.name.toUpperCase(), d.format.toUpperCase()); }); break; case HACKMYSTATUS.notOnPath: - msg = ex.engine + " wasn't found on your system path or" + - " is inaccessible. PDF not generated."; + msg = printf( M2C(this.msgs.notOnPath, 'bold'), ex.engine); quit = false; warn = false; break; @@ -179,8 +173,8 @@ Error-handling routines for HackMyResume. case HACKMYSTATUS.parseError: if( SyntaxErrorEx.is( ex.inner )) { var se = new SyntaxErrorEx( ex, ex.raw ); - msg = 'Invalid or corrupt JSON on line ' + se.line + - ' column ' + se.col + '.'; + msg = printf( M2C( this.msgs.parseError.msg, 'red' ), + se.line, se.col); } else { msg = ex; diff --git a/src/cli/msg.js b/src/cli/msg.js new file mode 100644 index 0000000..ce4d2b5 --- /dev/null +++ b/src/cli/msg.js @@ -0,0 +1,18 @@ +/** +Message-handling routines for HackMyResume. +@module msg.js +@license MIT. See LICENSE.md for details. +*/ + + + +(function() { + + var PATH = require('path'); + var YAML = require('yamljs'); + + var cache = module.exports = function() { + return cache ? cache : YAML.load( PATH.join(__dirname, 'msg.yml') ); + }(); + +}()); diff --git a/src/cli/msg.yml b/src/cli/msg.yml index 55ab6f1..70e87ee 100644 --- a/src/cli/msg.yml +++ b/src/cli/msg.yml @@ -1,46 +1,76 @@ -beforeCreate: - msg: Creating new **%s** resume: **%s** -beforeRead: - msg: Reading resume: **%s** -beforeTheme: - msg: Verifying theme: **%s** -afterTheme: - msg: Verifying outputs: ??? -beforeMerge: - msg: - - Merging **%s** - - " onto **%s**" -afterMerge: - msg: Applying **%s** theme (%s format%s) -afterBuild: - msg: - - "The **%s** theme says:" - - | - "For best results view JSON Resume themes over a - local or remote HTTP connection. For example: +events: + beforeCreate: + msg: Creating new **%s** resume: **%s** + beforeRead: + msg: Reading resume: **%s** + beforeTheme: + msg: Verifying theme: **%s** + afterTheme: + msg: Verifying outputs: ??? + beforeMerge: + msg: + - Merging **%s** + - " onto **%s**" + afterMerge: + msg: Applying **%s** theme (%s format%s) + afterBuild: + msg: + - "The **%s** theme says:" + - | + "For best results view JSON Resume themes over a + local or remote HTTP connection. For example: - npm install http-server -g - http-server + npm install http-server -g + http-server - For more information, see the README." -beforeGenerate: - msg: - - " (with %s)" - - "Skipping %s resume: %s" - - "Generating **%s** resume: **%s**" -beforeAnalyze: - msg: "Analyzing **%s** resume: **%s**" -beforeConvert: - msg: "Converting **%s** (**%s**) to **%s** (**%s**)" -afterValidate: - msg: - - "Validating **%s** against the **%s** schema: " - - "VALID!" - - "INVALID" - - "BROKEN" -beforePeek: - msg: - - Peeking at **%s** in **%s** - - Peeking at **%s** -afterPeek: - msg: "The specified key **%s** was not found in **%s**." + For more information, see the README." + beforeGenerate: + msg: + - " (with %s)" + - "Skipping %s resume: %s" + - "Generating **%s** resume: **%s**" + beforeAnalyze: + msg: "Analyzing **%s** resume: **%s**" + beforeConvert: + msg: "Converting **%s** (**%s**) to **%s** (**%s**)" + afterValidate: + msg: + - "Validating **%s** against the **%s** schema: " + - "VALID!" + - "INVALID" + - "BROKEN" + beforePeek: + msg: + - Peeking at **%s** in **%s** + - Peeking at **%s** + afterPeek: + msg: "The specified key **%s** was not found in **%s**." +errors: + themeNotFound: + msg: > + Couldn't find the '%s' theme. Please specify the name of a preinstalled + FRESH theme or the path to a locally installed FRESH or JSON Resume theme. + copyCSS: + msg: Couldn't copy CSS file to destination folder. + resumeNotFound: + msg: Please **feed me a resume** in FRESH or JSON Resume format. + missingCommand: + msg: Please **give me a command** + invalidCommand: + msg: Invalid command: '%s' + resumeNotFoundAlt: + msg: Please **feed me a resume** in either FRESH or JSON Resume format. + inputOutputParity: + msg: Please **specify an output file name** for every input file you wish to convert. + createNameMissing: + msg: Please **specify the filename** of the resume to create. + pdfGeneration: + msg: PDF generation failed. Make sure wkhtmltopdf is installed and accessible from your path. + invalid: + msg: Validation failed and the --assert option was specified. + invalidFormat: + msg: The **%s** theme doesn't support the **%s** format. + notOnPath: + msg: %s wasn't found on your system path or is inaccessible. PDF not generated. + parseError: + msg: Invalid or corrupt JSON on line %s column %s. diff --git a/src/cli/out.js b/src/cli/out.js index 30839e3..129d5a3 100644 --- a/src/cli/out.js +++ b/src/cli/out.js @@ -35,7 +35,7 @@ Output routines for HackMyResume. init: function( opts ) { this.opts = EXTEND( true, this.opts || { }, opts ); - this.msgs = YAML.load(PATH.join( __dirname, 'msg.yml' )); + this.msgs = YAML.load(PATH.join( __dirname, 'msg.yml' )).events; },