mirror of
				https://github.com/JuanCanham/HackMyResume.git
				synced 2025-10-30 20:57:26 +00:00 
			
		
		
		
	Use Commander.js for invocations.
This commit is contained in:
		| @@ -67,8 +67,7 @@ Error-handling routines for HackMyResume. | ||||
|             break; | ||||
|  | ||||
|           case HACKMYSTATUS.invalidCommand: | ||||
|             msg = chalk.yellow('Please ') + chalk.yellow.bold('specify the output resume file') + | ||||
|               chalk.yellow(' that should be created.'); | ||||
|             msg = chalk.yellow('Invalid command: "') + chalk.yellow.bold(ex.attempted) + chalk.yellow('"'); | ||||
|             break; | ||||
|  | ||||
|           case HACKMYSTATUS.resumeNotFoundAlt: | ||||
| @@ -116,7 +115,7 @@ Error-handling routines for HackMyResume. | ||||
|       } | ||||
|  | ||||
|       // Let the error code be the process's return code. | ||||
|       if( shouldExit ) | ||||
|       if( shouldExit || ex.shouldExit ) | ||||
|         process.exit( exitCode ); | ||||
|  | ||||
|     } | ||||
|   | ||||
							
								
								
									
										182
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										182
									
								
								src/index.js
									
									
									
									
									
								
							| @@ -18,8 +18,9 @@ var SPAWNW = require('./core/spawn-watch') | ||||
|   , HACKMYSTATUS = require('./core/status-codes') | ||||
|   , opts = { } | ||||
|   , title = chalk.white.bold('\n*** HackMyResume v' + PKG.version + ' ***') | ||||
|   , _ = require('underscore'); | ||||
|  | ||||
|   , StringUtils = require('./utils/string.js') | ||||
|   , _ = require('underscore') | ||||
|   , Command = require('commander').Command; | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -31,46 +32,175 @@ catch( ex ) { | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
| Kick off the HackMyResume application. | ||||
| */ | ||||
| function main() { | ||||
|  | ||||
|   // Setup | ||||
|   var a = ARGS( process.argv.slice(2) ); | ||||
|   if( a._.length === 0 ) { throw { fluenterror: 4 }; } | ||||
|   opts = getOpts( a ); | ||||
|   logMsg( title ); | ||||
|   var args = initialize(); | ||||
|  | ||||
|   // Get the action to be performed | ||||
|   var params = a._.map( function(p){ return p.toLowerCase().trim(); }); | ||||
|   var verb = opts.help ? 'help' : params[0]; | ||||
|   if( !FCMD.verbs[ verb ] && !FCMD.alias[ verb ] ) { | ||||
|     logMsg(chalk.yellow('Invalid command: "') + chalk.yellow.bold(verb) + chalk.yellow('"')); | ||||
|     return; | ||||
|   function execCommand() { | ||||
|     var argsArray = Array.prototype.slice.call(arguments); | ||||
|     //console.log(argsArray); | ||||
|     return FCMD.verbs[ this.name() ].apply( null, argsArray ); | ||||
|   } | ||||
|  | ||||
|   // Create the top-level (application) command... | ||||
|   var program = new Command('hackmyresume') | ||||
|     .version(PKG.version) | ||||
|     .description(chalk.yellow.bold('*** HackMyResume ***')) | ||||
|     .option('-s, --silent', 'Run in silent mode.') | ||||
|     .usage('COMMAND <sources> [TO <targets>]'); | ||||
|  | ||||
|   // Create the NEW command | ||||
|   program | ||||
|     .command('new') | ||||
|     .arguments('<sources...>') | ||||
|     .option('-f --format <fmt>', 'FRESH or JRS format', 'FRESH') | ||||
|     .alias('create') | ||||
|     .description('Create resume(s) in FRESH or JSON RESUME format.') | ||||
|     .action(function( sources ) { | ||||
|       execCommand.call( this, sources, [], this.opts(), logMsg ); | ||||
|     }); | ||||
|  | ||||
|   // Create the VALIDATE command | ||||
|   program | ||||
|     .command('validate') | ||||
|     .arguments('<sources...>') | ||||
|     .description('Validate a resume in FRESH or JSON RESUME format.') | ||||
|     .action(function(sources) { | ||||
|       execCommand.call(this, sources, [], this.opts(), logMsg); | ||||
|     }); | ||||
|  | ||||
|   // Create the CONVERT command | ||||
|   program | ||||
|     .command('convert') | ||||
|     //.arguments('<sources...>') | ||||
|     .description('Convert a resume to/from FRESH or JSON RESUME format.') | ||||
|     .action(function() { | ||||
|       var x = splitSrcDest.call( this ); | ||||
|       execCommand.call( this, x.src, x.dst, this.opts(), logMsg ); | ||||
|     }); | ||||
|  | ||||
|   // Create the ANALYZE command | ||||
|   program | ||||
|     .command('analyze') | ||||
|     .arguments('<sources...>') | ||||
|     .description('Analyze one or more resumes.') | ||||
|     .action(function() { | ||||
|       execCommand.call(this, sources, [], this.opts(), logMsg); | ||||
|     }); | ||||
|  | ||||
|   // Create the BUILD command | ||||
|   program | ||||
|     .command('build') | ||||
|     .alias('generate') | ||||
|     //.arguments('<sources> TO [targets]') | ||||
|     //.usage('...') | ||||
|     .option('-t --theme <theme>', 'Theme name or path') | ||||
|     .option('-p --prettify', 'Preffity HTML output.') | ||||
|     .description('Generate resume to multiple formats') | ||||
|     .action(function( sources, targets, options ) { | ||||
|       var x = splitSrcDest.call( this ); | ||||
|       execCommand.call( this, x.src, x.dst, opts, logMsg ); | ||||
|     }); | ||||
|  | ||||
|   // program.on('--help', function(){ | ||||
|   //   console.log('  Examples:'); | ||||
|   //   console.log(''); | ||||
|   //   console.log('    $ custom-help --help'); | ||||
|   //   console.log('    $ custom-help -h'); | ||||
|   //   console.log(''); | ||||
|   // }); | ||||
|  | ||||
|   program.parse( args ); | ||||
|  | ||||
|   if (!program.args.length) { throw { fluenterror: 4 }; } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
| Split multiple command-line filenames by the 'TO' keyword | ||||
| */ | ||||
| function splitSrcDest() { | ||||
|  | ||||
|   var params = this.parent.args.filter(function(j) { return String.is(j); }); | ||||
|   if( params.length === 0 ) | ||||
|     throw { fluenterror: HACKMYSTATUS.resumeNotFound }; | ||||
|  | ||||
|   // Find the TO keyword, if any | ||||
|   var splitAt = _.indexOf( params, 'to' ); | ||||
|   if( splitAt === a._.length - 1 && splitAt !== -1 ) { | ||||
|     // 'TO' cannot be the last argument | ||||
|     logMsg(chalk.yellow('Please ') + chalk.yellow.bold('specify an output file') + | ||||
|       chalk.yellow(' for this operation or ') + chalk.yellow.bold('omit the TO keyword') + | ||||
|   var splitAt = _.findIndex( params, function(p) { | ||||
|     return p.toLowerCase() === 'to'; | ||||
|   }); | ||||
|  | ||||
|   // TO can't be the last keyword | ||||
|   if( splitAt === params.length - 1 && splitAt !== -1 ) { | ||||
|     logMsg(chalk.yellow('Please ') + | ||||
|       chalk.yellow.bold('specify an output file') + | ||||
|       chalk.yellow(' for this operation or ') + | ||||
|       chalk.yellow.bold('omit the TO keyword') + | ||||
|       chalk.yellow('.') ); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Massage inputs and outputs | ||||
|   var src = a._.slice(1, splitAt === -1 ? undefined : splitAt ); | ||||
|   var dst = splitAt === -1 ? [] : a._.slice( splitAt + 1 ); | ||||
|  | ||||
|   // Invoke the action | ||||
|   (FCMD.verbs[verb] || FCMD.alias[verb]).apply(null, [src, dst, opts, logMsg]); | ||||
|  | ||||
|   return { | ||||
|     src: params.slice(0, splitAt === -1 ? undefined : splitAt ), | ||||
|     dst: splitAt === -1 ? [] : params.slice( splitAt + 1 ) | ||||
|   }; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
| Massage command-line args and setup Commander.js. | ||||
| */ | ||||
| function initialize() { | ||||
|  | ||||
|   // Support case-insensitive sub-commands (build, generate, validate, etc.).. | ||||
|   var oVerb, verb = '', args = process.argv.slice(), cleanArgs = args.slice(2); | ||||
|   if( cleanArgs.length ) { | ||||
|     var verbIdx = _.findIndex( cleanArgs, function(v){ return v[0] !== '-'; }); | ||||
|     if( verbIdx !== -1 ) { | ||||
|       oVerb = cleanArgs[ verbIdx ]; | ||||
|       verb = args[ verbIdx + 2 ] = oVerb.trim().toLowerCase(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Handle invalid verbs here (a bit easier here than in commander.js)... | ||||
|   if( !FCMD.verbs[ verb ] && !FCMD.alias[ verb ] ) { | ||||
|     throw { fluenterror: HACKMYSTATUS.invalidCommand, shouldExit: true, | ||||
|             attempted: oVerb }; | ||||
|   } | ||||
|  | ||||
|   // Override the .missingArgument behavior | ||||
|   Command.prototype.missingArgument = function(name) { | ||||
|     throw { fluenterror: HACKMYSTATUS.resumeNotFound }; | ||||
|   }; | ||||
|  | ||||
|   // Override the .helpInformation behavior | ||||
|   Command.prototype.helpInformation = function() { | ||||
|     var manPage = FS.readFileSync( PATH.join(__dirname, 'use.txt'), 'utf8' ); | ||||
|     return chalk.green.bold(manPage); | ||||
|   }; | ||||
|  | ||||
|   return args; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
| Simple logging placeholder. | ||||
| */ | ||||
| function logMsg( msg ) { | ||||
|   opts.silent || console.log( msg ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
| Fetch options from command line arguments. | ||||
| */ | ||||
| function getOpts( args ) { | ||||
|   var noPretty = args.nopretty || args.n; | ||||
|   noPretty = noPretty && (noPretty === true || noPretty === 'true'); | ||||
|   | ||||
| @@ -11,7 +11,8 @@ Implementation of the 'convert' verb for HackMyResume. | ||||
|  | ||||
|  | ||||
|   var ResumeFactory = require('../core/resume-factory') | ||||
|     , chalk = require('chalk'); | ||||
|     , chalk = require('chalk') | ||||
|     , HACKMYSTATUS = require('../core/status-codes'); | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -24,12 +25,19 @@ Implementation of the 'convert' verb for HackMyResume. | ||||
|     var _log = logger || console.log; | ||||
|     if( !srcs || !srcs.length ) { throw { fluenterror: 6 }; } | ||||
|     if( !dst || !dst.length ) { | ||||
|       if( srcs.length === 1 ) { throw { fluenterror: 5 }; } | ||||
|       else if( srcs.length === 2 ) { dst = dst || []; dst.push( srcs.pop() ); } | ||||
|       else { throw { fluenterror: 5 }; } | ||||
|       if( srcs.length === 1 ) { | ||||
|         throw { fluenterror: HACKMYSTATUS.inputOutputParity }; | ||||
|       } | ||||
|       else if( srcs.length === 2 ) { | ||||
|         dst = dst || []; dst.push( srcs.pop() ); | ||||
|       } | ||||
|       else { | ||||
|         throw { fluenterror: HACKMYSTATUS.inputOutputParity }; | ||||
|       } | ||||
|     } | ||||
|     if(srcs && dst && srcs.length && dst.length && srcs.length !== dst.length){ | ||||
|       throw { fluenterror: HACKMYSTATUS.inputOutputParity }; | ||||
|     } | ||||
|     if( srcs && dst && srcs.length && dst.length && | ||||
|         srcs.length !== dst.length ) { throw { fluenterror: 7 }; } | ||||
|  | ||||
|     // Load source resumes | ||||
|     srcs.forEach( function( src, idx ) { | ||||
| @@ -46,7 +54,7 @@ Implementation of the 'convert' verb for HackMyResume. | ||||
|  | ||||
|       // TODO: Core should not log | ||||
|       _log( chalk.green('Converting ') + chalk.green.bold(rinfo.file) + | ||||
|         chalk.green(' (' + srcFmt + ') to ') + chalk.green.bold(dst[0]) + | ||||
|         chalk.green(' (' + srcFmt + ') to ') + chalk.green.bold(dst[idx]) + | ||||
|         chalk.green(' (' + targetFormat + ').')); | ||||
|  | ||||
|       // Save it to the destination format | ||||
|   | ||||
| @@ -15,6 +15,7 @@ Implementation of the 'create' verb for HackMyResume. | ||||
|   Create a new empty resume in either FRESH or JRS format. | ||||
|   */ | ||||
|   module.exports = function create( src, dst, opts, logger ) { | ||||
|     //console.log(src); | ||||
|     var _log = logger || console.log; | ||||
|     if( !src || !src.length ) throw { fluenterror: 8 }; | ||||
|     src.forEach( function( t ) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user