diff options
Diffstat (limited to 'lib/diff.js')
-rw-r--r-- | lib/diff.js | 115 |
1 files changed, 79 insertions, 36 deletions
diff --git a/lib/diff.js b/lib/diff.js index dfd0fc81a..c6c31cacb 100644 --- a/lib/diff.js +++ b/lib/diff.js @@ -1,5 +1,8 @@ -var fs = require('fs'); -var child_process = require('child_process'); +var fs = require('fs'), + child_process = require('child_process'), + temp = require('temp'), + path = require('path'), + Promise = require('promise'); function cleanAndGetIndexes(text) { var addRules = { @@ -136,48 +139,88 @@ function cleanAndGetIndexes(text) { return {text: finalText, zones: zones}; } +function newTempDir() { + return new Promise(function (resolve, reject) { + temp.mkdir('gcc-explorer-diff', function (err, dirPath) { + if (err) + reject("Unable to open temp file: " + err); + else + resolve(dirPath); + }); + }); +} + +var writeFile = Promise.denodeify(fs.writeFile); + function buildDiffHandler(config) { + var maxFileSize = config.maxOutput; return function diffHandler(req, res) { var before = req.body.before; var after = req.body.after; + var error; if (before === undefined) { - console.log("Warning : Bad request : wrong \"before\""); - //return next(new Error("Bad request : wrong \"before\"")); + error = 'Warning : Bad request : wrong "before"'; + console.log(error); + return next(new Error(error)); } if (after === undefined) { - console.log("Warning : Bad request : wrong \"after\""); - //return next(new Error("Bad request : wrong \"after\"")); - } - // TODO : make async the two creation of temp files + call to wdiff ? - - var wdiffExe = config.wdiffExe; - - var tempBeforePath = config.wdiffTmpDir + "/gcc-explorer-wdiff-before"; - fs.writeFileSync(tempBeforePath, before); - - var tempAfterPath = config.wdiffTmpDir + "/gcc-explorer-wdiff-after"; - fs.writeFileSync(tempAfterPath, after); - - // TODO : get rid of this buffer or calculate it... - var maxSize = 100000; - var wdiffResult = child_process.spawnSync( - wdiffExe, - [tempBeforePath, tempAfterPath], - {maxBuffer: 100000}); - - res.set('Content-Type', 'application/json'); - var cleaned = cleanAndGetIndexes(wdiffResult.stdout.toString()); - if (cleaned === null) { - res.end(JSON.stringify({ - computedDiff: "Failed to clean the diff", - zones: null - })); - } else { - res.end(JSON.stringify({ - computedDiff: cleaned.text, - zones: cleaned.zones - })); + error = 'Warning : Bad request : wrong "after"'; + console.log(error); + return next(new Error(error)); } + + var tempBeforePath, tempAfterPath; + newTempDir() + .then(function (tmpDir) { + tempBeforePath = path.join(tmpDir, "gcc-explorer-wdiff-before"); + tempAfterPath = path.join(tmpDir, "gcc-explorer-wdiff-after"); + return Promise.all( + writeFile(tempBeforePath, before), + writeFile(tempAfterPath, after) + ); + }) + .then(function () { + var truncated = false; + var stdout = ""; + var child = child_process.spawn(config.wdiffExe, [tempBeforePath, tempAfterPath], + {maxBuffer: maxFileSize, detached: true}); + child.stdout.on('data', function (data) { + if (truncated) return; + if (stdout.length > maxFileSize) { + stdout += "\n[Truncated]"; + truncated = true; + child.kill(); + return; + } + stdout += data; + }); + return new Promise(function (resolve, reject) { + child.on('error', function (e) { + reject(e); + }); + child.on('exit', function (code) { + resolve(stdout); + }); + }); + }) + .then(function (output) { + var cleaned = cleanAndGetIndexes(output); + res.set('Content-Type', 'application/json'); + if (cleaned === null) { + res.end(JSON.stringify({ + computedDiff: "Failed to clean the diff", + zones: null + })); + } else { + res.end(JSON.stringify({ + computedDiff: cleaned.text, + zones: cleaned.zones + })); + } + }) + .catch(function (err) { + res.error(err); + }); }; } |