exe: use custom tar+gz extraction method, should fix #175
This commit is contained in:
+137
-42
@@ -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
@@ -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": {
|
||||
|
||||
@@ -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);
|
||||
@@ -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": {}
|
||||
}
|
||||
Reference in New Issue
Block a user