aboutsummaryrefslogtreecommitdiff
path: root/lib/diff.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/diff.js')
-rw-r--r--lib/diff.js115
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);
+ });
};
}