1
0
mirror of https://github.com/JuanCanham/HackMyResume.git synced 2024-06-28 23:00:05 +01:00

Improve proc spawn behavior.

Interim until async / promises support is in.
This commit is contained in:
hacksalot 2016-02-01 09:25:22 -05:00
parent 36d641801b
commit 212b01092c
8 changed files with 75 additions and 95 deletions

1
dist/cli/error.js vendored
View File

@ -140,7 +140,6 @@ Error-handling routines for HackMyResume.
if (ex.inner) { if (ex.inner) {
msg += chalk.red('\n' + ex.inner); msg += chalk.red('\n' + ex.inner);
} }
withStack = true;
quit = false; quit = false;
etype = 'error'; etype = 'error';
break; break;

View File

@ -16,7 +16,7 @@ Status codes for HackMyResume.
resumeNotFoundAlt: 6, resumeNotFoundAlt: 6,
inputOutputParity: 7, inputOutputParity: 7,
createNameMissing: 8, createNameMissing: 8,
pdfgeneration: 9, pdfGeneration: 9,
missingPackageJSON: 10, missingPackageJSON: 10,
invalid: 11, invalid: 11,
invalidFormat: 12, invalidFormat: 12,

View File

@ -6,20 +6,20 @@ Definition of the HtmlPdfCLIGenerator class.
*/ */
(function() { (function() {
var FS, HTML, HtmlPdfCLIGenerator, PATH, SLASH, SPAWN, TemplateGenerator, engines; var FS, HMSTATUS, HtmlPdfCLIGenerator, PATH, SLASH, TemplateGenerator, _, engines;
TemplateGenerator = require('./template-generator'); TemplateGenerator = require('./template-generator');
FS = require('fs-extra'); FS = require('fs-extra');
HTML = require('html');
PATH = require('path'); PATH = require('path');
SPAWN = require('../utils/safe-spawn');
SLASH = require('slash'); SLASH = require('slash');
_ = require('underscore');
HMSTATUS = require('../core/status-codes');
/** /**
An HTML-driven PDF resume generator for HackMyResume. Talks to Phantom, An HTML-driven PDF resume generator for HackMyResume. Talks to Phantom,
@ -34,30 +34,20 @@ Definition of the HtmlPdfCLIGenerator class.
/** Generate the binary PDF. */ /** Generate the binary PDF. */
onBeforeSave: function(info) { onBeforeSave: function(info) {
var ex, safe_eng; var safe_eng;
try { safe_eng = info.opts.pdf || 'wkhtmltopdf';
safe_eng = info.opts.pdf || 'wkhtmltopdf'; if (safe_eng === 'phantom') {
if (safe_eng !== 'none') { safe_eng = 'phantomjs';
engines[safe_eng].call(this, info.mk, info.outputFile);
return null;
}
} catch (_error) {
ex = _error;
if (ex.inner && ex.inner.code === 'ENOENT') {
throw {
fluenterror: this.codes.notOnPath,
inner: ex.inner,
engine: ex.cmd,
stack: ex.inner && ex.inner.stack
};
} else {
throw {
fluenterror: this.codes.pdfGeneration,
inner: ex,
stack: ex.stack
};
}
} }
if (_.has(engines, safe_eng)) {
this.SPAWN = require('../utils/safe-spawn');
this.errHandler = info.opts.errHandler;
engines[safe_eng].call(this, info.mk, info.outputFile, this.onError);
return null;
}
},
onError: function(ex, param) {
param.errHandler.err(HMSTATUS.pdfGeneration, ex);
} }
}); });
@ -70,11 +60,11 @@ Definition of the HtmlPdfCLIGenerator class.
TODO: If HTML generation has run, reuse that output TODO: If HTML generation has run, reuse that output
TODO: Local web server to ease wkhtmltopdf rendering TODO: Local web server to ease wkhtmltopdf rendering
*/ */
wkhtmltopdf: function(markup, fOut) { wkhtmltopdf: function(markup, fOut, on_error) {
var info, tempFile; var tempFile;
tempFile = fOut.replace(/\.pdf$/i, '.pdf.html'); tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
FS.writeFileSync(tempFile, markup, 'utf8'); FS.writeFileSync(tempFile, markup, 'utf8');
return info = SPAWN('wkhtmltopdf', [tempFile, fOut]); return this.SPAWN('wkhtmltopdf', [tempFile, fOut], false, on_error, this);
}, },
/** /**
@ -84,14 +74,14 @@ Definition of the HtmlPdfCLIGenerator class.
TODO: If HTML generation has run, reuse that output TODO: If HTML generation has run, reuse that output
TODO: Local web server to ease Phantom rendering TODO: Local web server to ease Phantom rendering
*/ */
phantom: function(markup, fOut) { phantomjs: function(markup, fOut, on_error) {
var destPath, info, scriptPath, sourcePath, tempFile; var destPath, scriptPath, sourcePath, tempFile;
tempFile = fOut.replace(/\.pdf$/i, '.pdf.html'); tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
FS.writeFileSync(tempFile, markup, 'utf8'); FS.writeFileSync(tempFile, markup, 'utf8');
scriptPath = SLASH(PATH.relative(process.cwd(), PATH.resolve(__dirname, '../utils/rasterize.js'))); scriptPath = SLASH(PATH.relative(process.cwd(), PATH.resolve(__dirname, '../utils/rasterize.js')));
sourcePath = SLASH(PATH.relative(process.cwd(), tempFile)); sourcePath = SLASH(PATH.relative(process.cwd(), tempFile));
destPath = SLASH(PATH.relative(process.cwd(), fOut)); destPath = SLASH(PATH.relative(process.cwd(), fOut));
return info = SPAWN('phantomjs', [scriptPath, sourcePath, destPath]); return this.SPAWN('phantomjs', [scriptPath, sourcePath, destPath], false, on_error, this);
} }
}; };

View File

@ -5,41 +5,39 @@ Safe spawn utility for HackMyResume / FluentCV.
@license MIT. See LICENSE.md for details. @license MIT. See LICENSE.md for details.
*/ */
/** Safely spawn a process synchronously or asynchronously without throwing an
exception
*/
(function() { (function() {
module.exports = function(cmd, args, isSync, callback) { module.exports = function(cmd, args, isSync, callback, param) {
var info, spawn; var info, spawn;
try { try {
spawn = require('child_process')[isSync ? 'spawnSync' : 'spawn']; spawn = require('child_process')[isSync ? 'spawnSync' : 'spawn'];
info = spawn(cmd, args); info = spawn(cmd, args);
if (!isSync) { if (!isSync) {
info.on('error', function(err) { info.on('error', function(err) {
if (callback != null) { if (typeof callback === "function") {
callback(err); callback(err, param);
} else {
throw {
cmd: cmd,
inner: err
};
} }
}); });
} else { } else {
if (info.error) { if (info.error) {
if (callback != null) { if (typeof callback === "function") {
callback(err); callback(info.error, param);
} else {
throw {
cmd: cmd,
inner: info.error
};
} }
return {
cmd: cmd,
inner: info.error
};
} }
} }
} catch (_error) { } catch (_error) {
if (callback != null) { if (typeof callback === "function") {
return callback(_error); callback(_error, param);
} else {
throw _error;
} }
return _error;
} }
}; };

View File

@ -139,7 +139,6 @@ assembleError = ( ex ) ->
when HMSTATUS.pdfGeneration when HMSTATUS.pdfGeneration
msg = M2C( this.msgs.pdfGeneration.msg, 'bold' ) msg = M2C( this.msgs.pdfGeneration.msg, 'bold' )
msg += chalk.red('\n' + ex.inner) if ex.inner msg += chalk.red('\n' + ex.inner) if ex.inner
withStack = true
quit = false quit = false
etype = 'error' etype = 'error'

View File

@ -15,7 +15,7 @@ module.exports =
resumeNotFoundAlt: 6 resumeNotFoundAlt: 6
inputOutputParity: 7 inputOutputParity: 7
createNameMissing: 8 createNameMissing: 8
pdfgeneration: 9 pdfGeneration: 9
missingPackageJSON: 10 missingPackageJSON: 10
invalid: 11 invalid: 11
invalidFormat: 12 invalidFormat: 12

View File

@ -6,12 +6,12 @@ Definition of the HtmlPdfCLIGenerator class.
TemplateGenerator = require('./template-generator') TemplateGenerator = require './template-generator'
FS = require('fs-extra') FS = require 'fs-extra'
HTML = require( 'html' ) PATH = require 'path'
PATH = require('path') SLASH = require 'slash'
SPAWN = require('../utils/safe-spawn') _ = require 'underscore'
SLASH = require('slash'); HMSTATUS = require '../core/status-codes'
@ -29,25 +29,18 @@ HtmlPdfCLIGenerator = module.exports = TemplateGenerator.extend
###* Generate the binary PDF. ### ###* Generate the binary PDF. ###
onBeforeSave: ( info ) -> onBeforeSave: ( info ) ->
try safe_eng = info.opts.pdf || 'wkhtmltopdf';
safe_eng = info.opts.pdf || 'wkhtmltopdf'; if safe_eng == 'phantom'
if safe_eng != 'none' safe_eng = 'phantomjs'
engines[ safe_eng ].call this, info.mk, info.outputFile if _.has engines, safe_eng
return null # halt further processing @SPAWN = require '../utils/safe-spawn'
catch ex @errHandler = info.opts.errHandler
# { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', ... } engines[ safe_eng ].call @, info.mk, info.outputFile, @onError
# { [Error: ENOENT] } return null # halt further processing
if ex.inner && ex.inner.code == 'ENOENT'
throw onError: (ex, param) ->
fluenterror: this.codes.notOnPath param.errHandler.err HMSTATUS.pdfGeneration, ex
inner: ex.inner return
engine: ex.cmd,
stack: ex.inner && ex.inner.stack
else
throw
fluenterror: this.codes.pdfGeneration
inner: ex
stack: ex.stack
@ -63,11 +56,11 @@ engines =
TODO: If HTML generation has run, reuse that output TODO: If HTML generation has run, reuse that output
TODO: Local web server to ease wkhtmltopdf rendering TODO: Local web server to ease wkhtmltopdf rendering
### ###
wkhtmltopdf: (markup, fOut) -> wkhtmltopdf: (markup, fOut, on_error) ->
# Save the markup to a temporary file # Save the markup to a temporary file
tempFile = fOut.replace /\.pdf$/i, '.pdf.html' tempFile = fOut.replace /\.pdf$/i, '.pdf.html'
FS.writeFileSync tempFile, markup, 'utf8' FS.writeFileSync tempFile, markup, 'utf8'
info = SPAWN 'wkhtmltopdf', [ tempFile, fOut ] @SPAWN 'wkhtmltopdf', [ tempFile, fOut ], false, on_error, @
@ -78,8 +71,7 @@ engines =
TODO: If HTML generation has run, reuse that output TODO: If HTML generation has run, reuse that output
TODO: Local web server to ease Phantom rendering TODO: Local web server to ease Phantom rendering
### ###
phantomjs: ( markup, fOut, on_error ) ->
phantom: ( markup, fOut ) ->
# Save the markup to a temporary file # Save the markup to a temporary file
tempFile = fOut.replace(/\.pdf$/i, '.pdf.html'); tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
@ -88,4 +80,4 @@ engines =
PATH.resolve( __dirname, '../utils/rasterize.js' ) ) ); PATH.resolve( __dirname, '../utils/rasterize.js' ) ) );
sourcePath = SLASH( PATH.relative( process.cwd(), tempFile) ); sourcePath = SLASH( PATH.relative( process.cwd(), tempFile) );
destPath = SLASH( PATH.relative( process.cwd(), fOut) ); destPath = SLASH( PATH.relative( process.cwd(), fOut) );
info = SPAWN('phantomjs', [ scriptPath, sourcePath, destPath ]); @SPAWN 'phantomjs', [ scriptPath, sourcePath, destPath ], false, on_error, @

View File

@ -4,7 +4,9 @@ Safe spawn utility for HackMyResume / FluentCV.
@license MIT. See LICENSE.md for details. @license MIT. See LICENSE.md for details.
### ###
module.exports = ( cmd, args, isSync, callback ) -> ###* Safely spawn a process synchronously or asynchronously without throwing an
exception ###
module.exports = ( cmd, args, isSync, callback, param ) ->
try try
@ -12,17 +14,17 @@ module.exports = ( cmd, args, isSync, callback ) ->
spawn = require('child_process')[ if isSync then 'spawnSync' else 'spawn']; spawn = require('child_process')[ if isSync then 'spawnSync' else 'spawn'];
info = spawn cmd, args info = spawn cmd, args
# Check for error depending on whether we're sync or async # Check for error depending on whether we're sync or async TODO: Promises
if !isSync if !isSync
info.on 'error', (err) -> info.on 'error', (err) ->
if callback? then callback err; return callback?(err, param)
else throw cmd: cmd, inner: err return
return return
else else
if info.error if info.error
if callback? then callback err; return callback?(info.error, param)
else throw cmd: cmd, inner: info.error return cmd: cmd, inner: info.error
catch catch
if callback? then callback _error callback?(_error, param)
else throw _error _error