mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-22 16:30:11 +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));
|
chalk.green(' resume: ') + chalk.green.bold(evt.file));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HME.beforeRead:
|
||||||
|
this.log( chalk.cyan('Reading resume: ' + chalk.bold( evt.file )));
|
||||||
|
break;
|
||||||
|
|
||||||
case HME.afterTheme:
|
case HME.afterTheme:
|
||||||
this.theme = evt.theme;
|
this.theme = evt.theme;
|
||||||
break;
|
break;
|
||||||
@ -148,6 +152,23 @@ Output routines for HackMyResume.
|
|||||||
chalk.green(' (' + evt.srcFmt + ') to ') + chalk.green.bold(evt.dstFile) +
|
chalk.green(' (' + evt.srcFmt + ') to ') + chalk.green.bold(evt.dstFile) +
|
||||||
chalk.green(' (' + evt.dstFmt + ').'));
|
chalk.green(' (' + evt.dstFmt + ').'));
|
||||||
break;
|
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>]
|
hackmyresume <COMMAND> <SOURCES> [TO <TARGETS>] [-t <THEME>] [-f <FORMAT>]
|
||||||
|
|
||||||
<COMMAND> should be BUILD, NEW, CONVERT, VALIDATE, ANALYZE or HELP. <SOURCES>
|
<COMMAND> should be BUILD, ANALYZE, NEW, CONVERT, or VALIDATE. <SOURCES> should
|
||||||
should be the path to one or more FRESH or JSON Resume format resumes. <TARGETS>
|
be the path to one or more FRESH or JSON Resume format resumes. <TARGETS> should
|
||||||
should be the name of the destination resume to be created, if any. The <THEME>
|
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,
|
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.
|
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
|
<FORMAT> should be either FRESH (for a FRESH-format resume) or JRS (for a JSON
|
||||||
Resume-format resume).
|
Resume-format resume).
|
||||||
|
|
||||||
hackmyresume BUILD resume.json TO out/resume.all
|
hackmyresume BUILD resume.json TO out/resume.all
|
||||||
|
hackmyresume ANALYZE resume.json
|
||||||
hackmyresume NEW resume.json
|
hackmyresume NEW resume.json
|
||||||
hackmyresume CONVERT resume.json TO resume-jrs.json
|
hackmyresume CONVERT resume.json TO resume-jrs.json
|
||||||
hackmyresume ANALYZE resume.json
|
|
||||||
hackmyresume VALIDATE resume.json
|
hackmyresume VALIDATE resume.json
|
||||||
|
|
||||||
Both SOURCES and TARGETS can accept multiple files:
|
Both SOURCES and TARGETS can accept multiple files:
|
||||||
|
|
||||||
hackmyresume BUILD r1.json r2.json TO out/resume.all out2/resume.html
|
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 ANALYZE r1.json r2.json r3.json
|
||||||
hackmyresume VALIDATE resume.json resume2.json resume3.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
|
See https://github.com/hacksalot/hackmyresume/blob/master/README.md for more
|
||||||
information.
|
information.
|
||||||
|
@ -156,6 +156,21 @@ Error-handling routines for HackMyResume.
|
|||||||
" is inaccessible. PDF not generated." );
|
" is inaccessible. PDF not generated." );
|
||||||
break;
|
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 {
|
return {
|
||||||
msg: msg,
|
msg: msg,
|
||||||
|
@ -40,7 +40,12 @@ Event code definitions.
|
|||||||
afterAnalyze: 14,
|
afterAnalyze: 14,
|
||||||
|
|
||||||
beforeConvert: 15,
|
beforeConvert: 15,
|
||||||
afterConvert: 16
|
afterConvert: 16,
|
||||||
|
|
||||||
|
verifyOutputs: 17,
|
||||||
|
|
||||||
|
beforeParse: 18,
|
||||||
|
afterParse: 19
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,11 +10,14 @@ Definition of the ResumeFactory class.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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');
|
require('string.prototype.startswith');
|
||||||
var FS = require('fs');
|
|
||||||
var ResumeConverter = require('./convert');
|
|
||||||
var chalk = require('chalk');
|
|
||||||
var SyntaxErrorEx = require('../utils/syntax-error-ex');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -29,14 +32,11 @@ Definition of the ResumeFactory class.
|
|||||||
/**
|
/**
|
||||||
Load one or more resumes from disk.
|
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 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.
|
Load a single resume from disk.
|
||||||
*/
|
*/
|
||||||
loadOne: function( src, opts ) {
|
loadOne: function( src, opts, emitter ) {
|
||||||
|
|
||||||
var log = opts.log;
|
|
||||||
var toFormat = opts.format;
|
var toFormat = opts.format;
|
||||||
var objectify = opts.objectify;
|
var objectify = opts.objectify;
|
||||||
|
|
||||||
@ -55,7 +54,7 @@ Definition of the ResumeFactory class.
|
|||||||
toFormat && (toFormat = toFormat.toLowerCase().trim());
|
toFormat && (toFormat = toFormat.toLowerCase().trim());
|
||||||
|
|
||||||
// Load and parse the resume JSON
|
// Load and parse the resume JSON
|
||||||
var info = _parse( src, opts );
|
var info = _parse( src, opts, emitter );
|
||||||
if( info.error ) return info;
|
if( info.error ) return info;
|
||||||
|
|
||||||
// Determine the resume format: FRESH or JRS
|
// 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;
|
var rawData;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// TODO: Core should not log
|
eve && eve.stat( HME.beforeRead, { file: fileName });
|
||||||
opts.log( chalk.cyan('Reading resume: ') + chalk.cyan.bold(fileName) );
|
|
||||||
|
|
||||||
// Read the file
|
|
||||||
rawData = FS.readFileSync( fileName, 'utf8' );
|
rawData = FS.readFileSync( fileName, 'utf8' );
|
||||||
|
eve && eve.stat( HME.afterRead, { data: rawData });
|
||||||
// Parse it to JSON
|
eve && eve.stat( HME.beforeParse, { data: rawData });
|
||||||
return {
|
var ret = {
|
||||||
json: JSON.parse( rawData )
|
json: JSON.parse( rawData )
|
||||||
};
|
};
|
||||||
|
eve && eve.stat( HME.afterParse, { data: ret.json } );
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
catch( ex ) {
|
catch( ex ) {
|
||||||
|
throw {
|
||||||
// JSON.parse failed due to invalid JSON
|
fluenterror: rawData ? HACKMYSTATUS.parseError : HACKMYSTATUS.readError,
|
||||||
if ( !opts.muffle && ex instanceof SyntaxError) {
|
inner: ex, raw: rawData, file: fileName, shouldExit: false
|
||||||
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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,9 @@ Status codes for HackMyResume.
|
|||||||
missingPackageJSON: 10,
|
missingPackageJSON: 10,
|
||||||
invalid: 11,
|
invalid: 11,
|
||||||
invalidFormat: 12,
|
invalidFormat: 12,
|
||||||
notOnPath: 13
|
notOnPath: 13,
|
||||||
|
readError: 14,
|
||||||
|
parseError: 15
|
||||||
};
|
};
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -31,6 +31,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
|||||||
, _err, _log, rez;
|
, _err, _log, rez;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var BuildVerb = module.exports = Verb.extend({
|
var BuildVerb = module.exports = Verb.extend({
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
@ -64,7 +65,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
|||||||
this.stat( HME.afterTheme, { theme: theme });
|
this.stat( HME.afterTheme, { theme: theme });
|
||||||
|
|
||||||
// Check for invalid outputs
|
// Check for invalid outputs
|
||||||
var inv = verifyOutputs( dst, theme );
|
var inv = verifyOutputs.call( this, dst, theme );
|
||||||
if( inv && inv.length ) {
|
if( inv && inv.length ) {
|
||||||
throw {fluenterror: HACKMYSTATUS.invalidFormat, data: inv, theme: theme};
|
throw {fluenterror: HACKMYSTATUS.invalidFormat, data: inv, theme: theme};
|
||||||
}
|
}
|
||||||
@ -181,6 +182,8 @@ Implementation of the 'generate' verb for HackMyResume.
|
|||||||
*/
|
*/
|
||||||
function verifyOutputs( targets, theme ) {
|
function verifyOutputs( targets, theme ) {
|
||||||
|
|
||||||
|
this.stat(HME.verifyOutputs, { targets: targets, theme: theme });
|
||||||
|
|
||||||
return _.reject(
|
return _.reject(
|
||||||
targets.map( function( t ) {
|
targets.map( function( t ) {
|
||||||
var pathInfo = parsePath( t );
|
var pathInfo = parsePath( t );
|
||||||
|
@ -12,6 +12,8 @@ Implementation of the 'validate' verb for HackMyResume.
|
|||||||
var chalk = require('chalk');
|
var chalk = require('chalk');
|
||||||
var Verb = require('../core/verb');
|
var Verb = require('../core/verb');
|
||||||
var HACKMYSTATUS = require('../core/status-codes');
|
var HACKMYSTATUS = require('../core/status-codes');
|
||||||
|
var HME = require('../core/event-codes');
|
||||||
|
var _ = require('underscore');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -45,41 +47,23 @@ Implementation of the 'validate' verb for HackMyResume.
|
|||||||
|
|
||||||
var resumes = ResumeFactory.load( sources, {
|
var resumes = ResumeFactory.load( sources, {
|
||||||
format: null,
|
format: null,
|
||||||
objectify: false,
|
objectify: false
|
||||||
throw: false,
|
}, this );
|
||||||
muffle: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load input resumes...
|
// Validate input resumes. Return a { file: <f>, isValid: <v>} object for
|
||||||
resumes.forEach(function( src ) {
|
// 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 ) {
|
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 };
|
if( opts.assert ) throw { fluenterror: HACKMYSTATUS.invalid };
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
var json = src.json;
|
// Successfully read the resume. Now parse it as JSON.
|
||||||
var isValid = false;
|
var json = src.json, fmt = json.basics ? 'jrs' : 'fresh', errors = [];
|
||||||
var style = 'green';
|
|
||||||
var errors = [];
|
|
||||||
var fmt = json.basics ? 'jrs' : 'fresh';
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var validate = validator( schemas[ fmt ], { // Note [1]
|
var validate = validator( schemas[ fmt ], { // Note [1]
|
||||||
formats: {
|
formats: {
|
||||||
@ -87,32 +71,27 @@ Implementation of the 'validate' verb for HackMyResume.
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
isValid = validate( json );
|
ret.isValid = validate( json );
|
||||||
if( !isValid ) {
|
if( !ret.isValid ) {
|
||||||
style = 'yellow';
|
|
||||||
errors = validate.errors;
|
errors = validate.errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(exc) {
|
catch(exc) {
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_log( chalk.white('Validating ') + chalk.white.bold(src.file) + chalk.white(' against ') +
|
this.stat(HME.afterValidate, { file: src.file, isValid: isValid,
|
||||||
chalk.white.bold(fmt.replace('jars','JSON Resume').toUpperCase()) +
|
fmt: fmt.replace('jars', 'JSON Resume'), errors: errors });
|
||||||
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) );
|
|
||||||
});
|
|
||||||
|
|
||||||
if( opts.assert && !isValid ) {
|
if( opts.assert && !isValid ) {
|
||||||
throw { fluenterror: HACKMYSTATUS.invalid, shouldExit: true };
|
throw { fluenterror: HACKMYSTATUS.invalid, shouldExit: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
return ret;
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
Loading…
Reference in New Issue
Block a user