exe: use custom tar+gz extraction method, should fix #175

This commit is contained in:
Jared Allard
2016-02-01 12:56:48 -08:00
parent 36a31b1048
commit f75948b7e8
4 changed files with 173 additions and 43 deletions
+137 -42
View File
@@ -26,8 +26,10 @@ var async = require("async"),
outcome = require("outcome"),
mkdirp = require("mkdirp"),
request = require("request"),
gunzip = require("gunzip-maybe"),
path = require("path"),
fs = require("fs"),
tarstream = require('tar-stream'),
colors = require('colors'),
ncp = require("ncp").ncp,
ProgressBar = require("progress"),
@@ -36,7 +38,6 @@ var async = require("async"),
bundle = require("./bundle"),
embed = require("./embed"),
os = require("os"),
targz = require('tar.gz'),
_log = require("./log"),
_monkeypatch = require("./monkeypatch"),
spawn = child_process.spawn;
@@ -355,10 +356,72 @@ function _downloadNode(version, directory, nodeConfigureArgs, nodeMakeArgs, comp
*/
function unzipNodeTarball (next) {
var onError = function(err) {
console.log(err.stack);
_log("error", "failed to extract the node source");
process.exit(1);
}
if(isWin) {
_log("Extracting the .tar.gz.");
new targz().extract(nodeFilePath, nodeFileDir, next);
_log("extracting the node source [node-tar.gz]");
// tar-stream method w/ gunzip-maybe
var read = fs.createReadStream(nodeFilePath);
var extract = tarstream.extract()
var basedir = nodeFileDir;
if(!fs.existsSync(nodeFileDir)) {
fs.mkdirSync(nodeFileDir);
}
extract.on('entry', function(header, stream, callback) {
// header is the tar header
// stream is the content body (might be an empty stream)
// call next when you are done with this entry
var absolutepath = path.join(basedir, header.name);
if(header.type === 'directory') {
// handle directories.
// console.log('dir:', header.name);
fs.mkdirSync(absolutepath);
return callback();
} else if(header.type === 'file') {
// handle files
// console.log('file:', header.name);
} else {
console.log(header.type+':', header.name);
_log('warn', 'unhandled type in tar extraction, skipping');
return callback();
}
var write = fs.createWriteStream(absolutepath);
stream.pipe(write);
write.on('close', function() {
return callback();
});
stream.on('error', function(err) {
return onError(err);
})
write.on('error', function(err) {
return onError(err);
});
stream.resume() // just auto drain the stream
})
extract.on('finish', function() {
_log('extraction finished');
return next();
})
read.pipe(gunzip()).pipe(extract);
} else {
_log("extracting the node source [native tar]");
var cmd = ["tar", "-xf", nodeFilePath, "-C", nodeFileDir];
_log(cmd.join(" "));
@@ -366,12 +429,10 @@ function _downloadNode(version, directory, nodeConfigureArgs, nodeMakeArgs, comp
tar.stdout.pipe(process.stdout);
tar.stderr.pipe(process.stderr);
tar.on("close", function () { next(); })
tar.on("error", function (err) {
console.log(err);
_log("error", "failed to extract the node tar file.");
process.exit(1);
tar.on("close", function () {
return next();
});
tar.on("error", onError);
}
},
@@ -638,43 +699,77 @@ function _monkeyPatchChildProcess(compiler, complete) {
function _monkeyPatchMainCc(compiler, complete) {
var mainPath = path.join(compiler.dir, "src", "node.cc");
_monkeypatch(
mainPath,
function (content) {
return ~content.indexOf('// // TODO use parse opts');
},
function (content, next) { // TODO: failsafe this
var lines = content.split('\n');
var endLine = lines.indexOf(' option_end_index = i;'); // pre node 0.11.6 compat
var mainC = fs.readFileSync(mainPath, {encoding: 'utf8'});
if(endLine !== -1) { // check if it succedded or not.
lines[endLine] = ' option_end_index = 1;';
_log("patched node.cc")
}
// content split, and original start/end
var constant_loc = 1;
var lines = mainC.split('\n');
var startLine = lines.indexOf(' // TODO use parse opts');
var endLine = lines.indexOf(' option_end_index = i;'); // pre node 0.11.6 compat
var isPatched = lines.indexOf('// NEXE_PATCH_IGNOREFLAGS');
/**
* This is the new method of passing the args. Tested on node.js 0.12.5
* and iojs 2.3.1
**/
if(endLine === -1) { // only if the pre-0.12.5 failed.
var startLine = lines.indexOf(' while (index < nargs && argv[index][0] == \'-\') {'); // beginning of the function
endLine = lines.indexOf(' // Copy remaining arguments.');
endLine = endLine-1; // space, then it's at the }
if(isPatched !== -1) {
_log('already patched node.cc');
return complete();
}
// remove the offending lines
if(startLine !== -1) {
for (var i = startLine; i < endLine; i++) {
lines[i] = undefined; // set the value to undefined so it's skipped by the join
}
_log('patched node.cc');
}
}
/**
* This is the new method of passing the args. Tested on node.js 0.12.5
* and iojs 2.3.1
**/
if(endLine === -1 && startLine === -1) { // only if the pre-0.12.5 failed.
_log("using the after 0.12.5 method of ignoring flags.");
lines = lines.join('\n');
next(null, lines);
},
complete
);
startLine = lines.indexOf(" while (index < nargs && argv[index][0] == '-') {"); // beginning of the function
endLine = lines.indexOf(' // Copy remaining arguments.');
endLine--; // space, then it's at the }
constant_loc = lines.length+1;
} else {
_log('using 0.10.x > method of ignoring flags');
lines[endLine] = ' option_end_index = 1;';
}
/**
* This is the method for 5.5.0
**/
if(endLine === -1 || startLine === -1) {
_log("using the after 5.5.0 method of ignoring flags.");
startLine = lines.indexOf(" while (index < nargs && argv[index][0] == '-' && !short_circuit) {"); // beginning of the function
endLine = lines.indexOf(' // Copy remaining arguments.');
endLine--; // space, then it's at the }
constant_loc = lines.length+1;
}
// other versions here.
if(endLine === -1 || startLine === -1) { // failsafe.
_log("error", "Failed to find a way to patch node.cc to ignoreFlags");
_log("startLine =", startLine, '| endLine =', endLine);
process.exit(1);
}
// check if it's been done
lines[constant_loc] = '// NEXE_PATCH_IGNOREFLAGS';
for (var i = startLine; i < endLine; i++) {
lines[i] = undefined; // set the value to undefined so it's skipped by the join
}
_log('patched node.cc');
finalContents = lines.join('\n');
// write the file contents
fs.writeFile(mainPath, finalContents, {encoding: 'utf8'}, function(err) {
if(err) {
_log('error', 'failed to write to', mainPath);
return process.exit(1);
}
return complete();
});
}
/**
@@ -729,7 +824,7 @@ SetFlagsFromString(nexevargs, nexevargslen);\n\
dontCombine;
if(lineToInjectAfter !== -1 && haveWeInjectedBefore === -1) {
_log('injecting v8 args c++');
_log('injecting v8/flags.cc');
// super debug
// _log('v8 injection determined by', lastInjectionLine);
+2 -1
View File
@@ -22,6 +22,7 @@
"builtins": "1.0.3",
"colors": "^1.1.2",
"glob": "^6.0.4",
"gunzip-maybe": "^1.3.1",
"insert-module-globals": "^7.0.1",
"mkdirp": "^0.5.1",
"module-deps": "^4.0.5",
@@ -31,7 +32,7 @@
"request": "^2.67.0",
"sprintf": "~0.1.5",
"step": "0.0.x",
"tar.gz": "1.0.2",
"tar-stream": "^1.3.1",
"yargs": "^3.32.0"
},
"nexe": {
+19
View File
@@ -0,0 +1,19 @@
/**
* Test to verify if we support strict mode (flags)
*
* @author Jared Allard <jaredallard@outlook.com>
* @version 0.0.1
* @license MIT
**/
// test.nex --help
var status = false;
// console.log(process.argv);
if(process.argv[2]) {
status = true;
}
console.log('test:ignoreFlags:status =', status);
+15
View File
@@ -0,0 +1,15 @@
{
"name": "flags-test",
"nexe": {
"input": "./index.js",
"output": "test.nex",
"temp": "src",
"runtime": {
"framework": "node",
"version": "5.5.0",
"ignoreFlags": true,
"node-args": ""
}
},
"dependencies": {}
}