mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-05 09:56:22 +00:00
Capture.
This commit is contained in:
parent
a4ee7127ee
commit
656dbe2fc2
@ -52,6 +52,10 @@ Output routines for HackMyResume.
|
||||
chalk.green(' resume: ') + chalk.green.bold(evt.file));
|
||||
break;
|
||||
|
||||
case HME.beforeRead:
|
||||
this.log( chalk.cyan('Reading resume: ' + chalk.bold( evt.file )));
|
||||
break;
|
||||
|
||||
case HME.afterTheme:
|
||||
this.theme = evt.theme;
|
||||
break;
|
||||
@ -148,6 +152,23 @@ Output routines for HackMyResume.
|
||||
chalk.green(' (' + evt.srcFmt + ') to ') + chalk.green.bold(evt.dstFile) +
|
||||
chalk.green(' (' + evt.dstFmt + ').'));
|
||||
break;
|
||||
|
||||
case HME.afterValidate:
|
||||
var style = evt.isValid ? 'green' : 'yellow';
|
||||
this.log( chalk.white('Validating ') + chalk.white.bold(evt.file) + chalk.white(' against ') +
|
||||
chalk.white.bold( evt.fmt ).toUpperCase() +
|
||||
chalk.white(' schema: ') + chalk[style].bold(evt.isValid ? 'VALID!' : 'INVALID'));
|
||||
|
||||
if( evt.errors ) {
|
||||
_.each(evt.errors, function(err,idx) {
|
||||
this.log( chalk.yellow.bold('--> ') +
|
||||
chalk.yellow(err.field.replace('data.','resume.').toUpperCase() + ' ' +
|
||||
err.message) );
|
||||
}, this);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,26 +2,63 @@ Usage:
|
||||
|
||||
hackmyresume <COMMAND> <SOURCES> [TO <TARGETS>] [-t <THEME>] [-f <FORMAT>]
|
||||
|
||||
<COMMAND> should be BUILD, NEW, CONVERT, VALIDATE, ANALYZE or HELP. <SOURCES>
|
||||
should be the path to one or more FRESH or JSON Resume format resumes. <TARGETS>
|
||||
should be the name of the destination resume to be created, if any. The <THEME>
|
||||
<COMMAND> should be BUILD, ANALYZE, NEW, CONVERT, or VALIDATE. <SOURCES> should
|
||||
be the path to one or more FRESH or JSON Resume format resumes. <TARGETS> should
|
||||
be the name of the destination resume to be created, if any. The <THEME>
|
||||
parameter should be the name of a predefined theme (for example: COMPACT,
|
||||
MINIMIST, MODERN, or HELLO-WORLD) or the relative path to a custom theme.
|
||||
<FORMAT> should be either FRESH (for a FRESH-format resume) or JRS (for a JSON
|
||||
Resume-format resume).
|
||||
|
||||
hackmyresume BUILD resume.json TO out/resume.all
|
||||
hackmyresume NEW resume.json
|
||||
hackmyresume CONVERT resume.json TO resume-jrs.json
|
||||
hackmyresume ANALYZE resume.json
|
||||
hackmyresume VALIDATE resume.json
|
||||
hackmyresume BUILD resume.json TO out/resume.all
|
||||
hackmyresume ANALYZE resume.json
|
||||
hackmyresume NEW resume.json
|
||||
hackmyresume CONVERT resume.json TO resume-jrs.json
|
||||
hackmyresume VALIDATE resume.json
|
||||
|
||||
Both SOURCES and TARGETS can accept multiple files:
|
||||
|
||||
hackmyresume BUILD r1.json r2.json TO out/resume.all out2/resume.html
|
||||
hackmyresume NEW r1.json r2.json r3.json
|
||||
hackmyresume ANALYZE r1.json r2.json r3.json
|
||||
hackmyresume VALIDATE resume.json resume2.json resume3.json
|
||||
hackmyresume BUILD r1.json r2.json TO out/resume.all out2/resume.html
|
||||
hackmyresume ANALYZE r1.json r2.json r3.json
|
||||
hackmyresume NEW r1.json r2.json r3.json
|
||||
hackmyresume CONVERT r1.json r2.json TO o1.json o2.json
|
||||
hackmyresume VALIDATE r1.json r2.json r3.json
|
||||
|
||||
Available options:
|
||||
|
||||
--theme <theme> Specify a theme for the BUILD command. Can be the path
|
||||
-t <theme> to any FRESH or JSON Resume theme, or the name of one
|
||||
of HackMyResume's predefined themes.
|
||||
|
||||
|
||||
--pdf <engine> Specify a PDF rendering engine. Can be "wkhtmltopdf",
|
||||
-p <engine> "phantom", or "none". Requires that the corresponding
|
||||
engine be installed and path-accessible.
|
||||
|
||||
|
||||
--opts <path> Load HackMyResume options via an external file.
|
||||
-o <path>
|
||||
|
||||
|
||||
--color Enable/disable terminal colors.
|
||||
--no-color
|
||||
|
||||
|
||||
--tips Enable/disable theme tips and messages.
|
||||
--no-tips
|
||||
|
||||
|
||||
--debug Emit debug info.
|
||||
-d
|
||||
|
||||
|
||||
--help Display help documentation.
|
||||
-h
|
||||
|
||||
|
||||
--version Display the current HackMyResume version.
|
||||
-v
|
||||
|
||||
|
||||
See https://github.com/hacksalot/hackmyresume/blob/master/README.md for more
|
||||
information.
|
||||
|
@ -156,6 +156,21 @@ Error-handling routines for HackMyResume.
|
||||
" is inaccessible. PDF not generated." );
|
||||
break;
|
||||
|
||||
case HACKMYSTATUS.readError:
|
||||
msg = formatError( ex.inner.toString() );
|
||||
break;
|
||||
|
||||
case HACKMYSTATUS.parseError:
|
||||
if( SyntaxErrorEx.is( ex.inner )) {
|
||||
var se = new SyntaxErrorEx( ex, ex.raw );
|
||||
msg = formatError( 'Invalid or corrupt JSON on line ' + se.line +
|
||||
' column ' + se.col );
|
||||
}
|
||||
else {
|
||||
msg = formatError( ex.inner.toString() );
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return {
|
||||
msg: msg,
|
||||
|
@ -40,7 +40,12 @@ Event code definitions.
|
||||
afterAnalyze: 14,
|
||||
|
||||
beforeConvert: 15,
|
||||
afterConvert: 16
|
||||
afterConvert: 16,
|
||||
|
||||
verifyOutputs: 17,
|
||||
|
||||
beforeParse: 18,
|
||||
afterParse: 19
|
||||
|
||||
};
|
||||
|
||||
|
@ -10,11 +10,14 @@ Definition of the ResumeFactory class.
|
||||
|
||||
|
||||
|
||||
require('string.prototype.startswith');
|
||||
var FS = require('fs');
|
||||
var ResumeConverter = require('./convert');
|
||||
var chalk = require('chalk');
|
||||
var SyntaxErrorEx = require('../utils/syntax-error-ex');
|
||||
var FS = require('fs'),
|
||||
HACKMYSTATUS = require('./status-codes'),
|
||||
HME = require('./event-codes'),
|
||||
ResumeConverter = require('./convert'),
|
||||
chalk = require('chalk'),
|
||||
SyntaxErrorEx = require('../utils/syntax-error-ex'),
|
||||
_ = require('underscore');
|
||||
require('string.prototype.startswith');
|
||||
|
||||
|
||||
|
||||
@ -29,14 +32,11 @@ Definition of the ResumeFactory class.
|
||||
/**
|
||||
Load one or more resumes from disk.
|
||||
*/
|
||||
load: function ( sources, opts ) {
|
||||
load: function ( sources, opts, emitter ) {
|
||||
|
||||
// Loop over all inputs, parsing each to JSON and then to a FRESHResume
|
||||
// or JRSResume object.
|
||||
var that = this;
|
||||
return sources.map( function( src ) {
|
||||
return that.loadOne( src, opts );
|
||||
});
|
||||
return this.loadOne( src, opts, emitter );
|
||||
}, this);
|
||||
|
||||
},
|
||||
|
||||
@ -45,9 +45,8 @@ Definition of the ResumeFactory class.
|
||||
/**
|
||||
Load a single resume from disk.
|
||||
*/
|
||||
loadOne: function( src, opts ) {
|
||||
loadOne: function( src, opts, emitter ) {
|
||||
|
||||
var log = opts.log;
|
||||
var toFormat = opts.format;
|
||||
var objectify = opts.objectify;
|
||||
|
||||
@ -55,7 +54,7 @@ Definition of the ResumeFactory class.
|
||||
toFormat && (toFormat = toFormat.toLowerCase().trim());
|
||||
|
||||
// Load and parse the resume JSON
|
||||
var info = _parse( src, opts );
|
||||
var info = _parse( src, opts, emitter );
|
||||
if( info.error ) return info;
|
||||
|
||||
// Determine the resume format: FRESH or JRS
|
||||
@ -88,44 +87,28 @@ Definition of the ResumeFactory class.
|
||||
|
||||
|
||||
|
||||
function _parse( fileName, opts ) {
|
||||
function _parse( fileName, opts, eve ) {
|
||||
|
||||
var rawData;
|
||||
try {
|
||||
|
||||
// TODO: Core should not log
|
||||
opts.log( chalk.cyan('Reading resume: ') + chalk.cyan.bold(fileName) );
|
||||
|
||||
// Read the file
|
||||
eve && eve.stat( HME.beforeRead, { file: fileName });
|
||||
rawData = FS.readFileSync( fileName, 'utf8' );
|
||||
|
||||
// Parse it to JSON
|
||||
return {
|
||||
eve && eve.stat( HME.afterRead, { data: rawData });
|
||||
eve && eve.stat( HME.beforeParse, { data: rawData });
|
||||
var ret = {
|
||||
json: JSON.parse( rawData )
|
||||
};
|
||||
|
||||
eve && eve.stat( HME.afterParse, { data: ret.json } );
|
||||
return ret;
|
||||
}
|
||||
catch( ex ) {
|
||||
|
||||
// JSON.parse failed due to invalid JSON
|
||||
if ( !opts.muffle && ex instanceof SyntaxError) {
|
||||
var info = new SyntaxErrorEx( ex, rawData );
|
||||
opts.log( chalk.red.bold(fileName.toUpperCase() + ' contains invalid JSON on line ' +
|
||||
info.line + ' column ' + info.col + '.' +
|
||||
chalk.red(' Unable to validate.')));
|
||||
opts.log( chalk.red.bold('INTERNAL: ' + ex) );
|
||||
ex.handled = true;
|
||||
}
|
||||
|
||||
// FS.readFileSync failed
|
||||
if( !rawData || opts.throw ) throw ex;
|
||||
|
||||
return {
|
||||
error: ex,
|
||||
raw: rawData,
|
||||
file: fileName
|
||||
throw {
|
||||
fluenterror: rawData ? HACKMYSTATUS.parseError : HACKMYSTATUS.readError,
|
||||
inner: ex, raw: rawData, file: fileName, shouldExit: false
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,7 +20,9 @@ Status codes for HackMyResume.
|
||||
missingPackageJSON: 10,
|
||||
invalid: 11,
|
||||
invalidFormat: 12,
|
||||
notOnPath: 13
|
||||
notOnPath: 13,
|
||||
readError: 14,
|
||||
parseError: 15
|
||||
};
|
||||
|
||||
}());
|
||||
|
@ -31,6 +31,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
, _err, _log, rez;
|
||||
|
||||
|
||||
|
||||
var BuildVerb = module.exports = Verb.extend({
|
||||
|
||||
init: function() {
|
||||
@ -64,7 +65,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
this.stat( HME.afterTheme, { theme: theme });
|
||||
|
||||
// Check for invalid outputs
|
||||
var inv = verifyOutputs( dst, theme );
|
||||
var inv = verifyOutputs.call( this, dst, theme );
|
||||
if( inv && inv.length ) {
|
||||
throw {fluenterror: HACKMYSTATUS.invalidFormat, data: inv, theme: theme};
|
||||
}
|
||||
@ -181,6 +182,8 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
*/
|
||||
function verifyOutputs( targets, theme ) {
|
||||
|
||||
this.stat(HME.verifyOutputs, { targets: targets, theme: theme });
|
||||
|
||||
return _.reject(
|
||||
targets.map( function( t ) {
|
||||
var pathInfo = parsePath( t );
|
||||
|
@ -12,6 +12,8 @@ Implementation of the 'validate' verb for HackMyResume.
|
||||
var chalk = require('chalk');
|
||||
var Verb = require('../core/verb');
|
||||
var HACKMYSTATUS = require('../core/status-codes');
|
||||
var HME = require('../core/event-codes');
|
||||
var _ = require('underscore');
|
||||
|
||||
|
||||
|
||||
@ -45,74 +47,51 @@ Implementation of the 'validate' verb for HackMyResume.
|
||||
|
||||
var resumes = ResumeFactory.load( sources, {
|
||||
format: null,
|
||||
objectify: false,
|
||||
throw: false,
|
||||
muffle: true
|
||||
});
|
||||
objectify: false
|
||||
}, this );
|
||||
|
||||
// Load input resumes...
|
||||
resumes.forEach(function( src ) {
|
||||
// Validate input resumes. Return a { file: <f>, isValid: <v>} object for
|
||||
// each resume (valid, invalid, or broken).
|
||||
return resumes.map( function( src ) {
|
||||
|
||||
var ret = { file: src, isValid: false };
|
||||
|
||||
// If there was an error reading the resume
|
||||
if( src.error ) {
|
||||
// TODO: Core should not log
|
||||
_log( chalk.white('Validating ') + chalk.gray.bold(src.file) +
|
||||
chalk.white(' against ') + chalk.gray.bold('AUTO') +
|
||||
chalk.white(' schema:') + chalk.red.bold(' BROKEN') );
|
||||
|
||||
var ex = src.error; // alias
|
||||
if ( ex instanceof SyntaxError) {
|
||||
var info = new SyntaxErrorEx( ex, src.raw );
|
||||
_log( chalk.red.bold('--> ' + src.file.toUpperCase() + ' contains invalid JSON on line ' +
|
||||
info.line + ' column ' + info.col + '.' +
|
||||
chalk.red(' Unable to validate.') ) );
|
||||
_log( chalk.red.bold(' INTERNAL: ' + ex) );
|
||||
}
|
||||
else {
|
||||
_log(chalk.red.bold('ERROR: ' + ex.toString()));
|
||||
}
|
||||
if( opts.assert ) throw { fluenterror: HACKMYSTATUS.invalid };
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
var json = src.json;
|
||||
var isValid = false;
|
||||
var style = 'green';
|
||||
var errors = [];
|
||||
var fmt = json.basics ? 'jrs' : 'fresh';
|
||||
|
||||
// Successfully read the resume. Now parse it as JSON.
|
||||
var json = src.json, fmt = json.basics ? 'jrs' : 'fresh', errors = [];
|
||||
try {
|
||||
var validate = validator( schemas[ fmt ], { // Note [1]
|
||||
formats: {
|
||||
date: /^\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/
|
||||
date: /^\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/
|
||||
}
|
||||
});
|
||||
|
||||
isValid = validate( json );
|
||||
if( !isValid ) {
|
||||
style = 'yellow';
|
||||
ret.isValid = validate( json );
|
||||
if( !ret.isValid ) {
|
||||
errors = validate.errors;
|
||||
}
|
||||
|
||||
}
|
||||
catch(exc) {
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
_log( chalk.white('Validating ') + chalk.white.bold(src.file) + chalk.white(' against ') +
|
||||
chalk.white.bold(fmt.replace('jars','JSON Resume').toUpperCase()) +
|
||||
chalk.white(' schema: ') + chalk[style].bold(isValid ? 'VALID!' : 'INVALID') );
|
||||
|
||||
errors.forEach(function(err,idx) {
|
||||
_log( chalk.yellow.bold('--> ') +
|
||||
chalk.yellow(err.field.replace('data.','resume.').toUpperCase() + ' ' +
|
||||
err.message) );
|
||||
});
|
||||
this.stat(HME.afterValidate, { file: src.file, isValid: isValid,
|
||||
fmt: fmt.replace('jars', 'JSON Resume'), errors: errors });
|
||||
|
||||
if( opts.assert && !isValid ) {
|
||||
throw { fluenterror: HACKMYSTATUS.invalid, shouldExit: true };
|
||||
}
|
||||
|
||||
});
|
||||
return ret;
|
||||
|
||||
}, this);
|
||||
|
||||
}
|
||||
|
||||
}());
|
||||
|
Loading…
Reference in New Issue
Block a user