feat: next
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
root = true
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace=true
|
||||
insert_final_newline = true
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"rules": {
|
||||
"comma-dangle": [2,"never"],
|
||||
"no-cond-assign": [2,"except-parens"],
|
||||
"no-console": 2,
|
||||
"no-constant-condition": 2,
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-dupe-class-members": 2,
|
||||
"no-duplicate-imports": 2,
|
||||
"no-empty": 2,
|
||||
"no-empty-character-class": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-extra-parens": 2,
|
||||
"no-extra-semi": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-inner-declarations": 2,
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-reserved-keys": 0,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-unreachable": 2,
|
||||
"use-isnan": 2,
|
||||
"valid-jsdoc": 0,
|
||||
"valid-typeof": 2,
|
||||
"prefer-const": 2,
|
||||
"block-scoped-var": 0,
|
||||
"complexity": 0,
|
||||
"consistent-return": 2,
|
||||
"curly": [2,"multi-line"],
|
||||
"default-case": 0,
|
||||
"dot-notation": 2,
|
||||
"eqeqeq": 2,
|
||||
"guard-for-in": 0,
|
||||
"no-alert": 2,
|
||||
"no-caller": 2,
|
||||
"no-div-regex": 2,
|
||||
"no-else-return": 2,
|
||||
"no-eq-null": 2,
|
||||
"no-eval": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-fallthrough": 2,
|
||||
"no-floating-decimal": 2,
|
||||
"no-implied-eval": 2,
|
||||
"no-iterator": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 2,
|
||||
"no-loop-func": 2,
|
||||
"no-multi-spaces": 2,
|
||||
"no-multi-str": 0,
|
||||
"no-native-reassign": 0,
|
||||
"no-new": 0,
|
||||
"no-new-func": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-octal": 0,
|
||||
"no-octal-escape": 0,
|
||||
"no-process-env": 0,
|
||||
"no-proto": 0,
|
||||
"no-redeclare": 2,
|
||||
"no-return-assign": 0,
|
||||
"no-script-url": 2,
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2,
|
||||
"no-throw-literal": 2,
|
||||
"no-unused-expressions": 0,
|
||||
"no-void": 0,
|
||||
"no-warning-comments": [2, { "terms": ["FIXME"]}],
|
||||
"no-with": 2,
|
||||
"radix": 2,
|
||||
"vars-on-top": 0,
|
||||
"wrap-iife": 2,
|
||||
"yoda": 0,
|
||||
"no-catch-shadow": 2,
|
||||
"no-delete-var": 2,
|
||||
"no-label-var": 2,
|
||||
"no-shadow": 2,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-undef": 2,
|
||||
"no-undef-init": 2,
|
||||
"no-undefined": 2,
|
||||
"no-unused-vars": 2,
|
||||
"no-use-before-define": 2,
|
||||
"strict": [2, "never"],
|
||||
"handle-callback-err": 2,
|
||||
"no-new-require": 2,
|
||||
"no-path-concat": 2,
|
||||
"no-process-exit": 0,
|
||||
"no-restricted-modules": 0,
|
||||
"no-sync": 2,
|
||||
"indent": [2, 2],
|
||||
"brace-style": [2,"1tbs"],
|
||||
"camelcase": 0,
|
||||
"comma-spacing": [2, { "before": false, "after": true }],
|
||||
"comma-style": 2,
|
||||
"consistent-this": 0,
|
||||
"eol-last": 2,
|
||||
"func-names": 0,
|
||||
"func-style": 0,
|
||||
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
|
||||
"linebreak-style": [2, "unix"],
|
||||
"max-nested-callbacks": [2, 3],
|
||||
"new-parens": 2,
|
||||
"no-array-constructor": 2,
|
||||
"no-inline-comments": 0,
|
||||
"no-lonely-if": 2,
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"no-multiple-empty-lines": [2, {"max": 1}],
|
||||
"no-nested-ternary": 2,
|
||||
"no-new-object": 2,
|
||||
"semi-spacing": [2, {"before": false, "after": true}],
|
||||
"no-spaced-func": 2,
|
||||
"no-ternary": 0,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-underscore-dangle": 0,
|
||||
"operator-assignment": [2, "always"],
|
||||
"padded-blocks": 0,
|
||||
"quote-props": 0,
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"semi": [2, "never"],
|
||||
"sort-vars": 0,
|
||||
"keyword-spacing": [2, { "before": true, "after": true}],
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, "always"],
|
||||
"object-curly-spacing": [2, "always"],
|
||||
"array-bracket-spacing": [2, "never"],
|
||||
"computed-property-spacing": [2, "never"],
|
||||
"space-in-parens": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-unary-ops": [2, { "words": false, "nonwords": false }],
|
||||
"spaced-line-comment": 0,
|
||||
"wrap-regex": 0,
|
||||
"require-await": 2,
|
||||
"no-var": 0,
|
||||
"generator-star": 0
|
||||
}
|
||||
}
|
||||
+4
-11
@@ -1,15 +1,8 @@
|
||||
.DS_Store
|
||||
temp/
|
||||
node_modules
|
||||
npm-debug.log
|
||||
test/**/src
|
||||
test/**/out.nex
|
||||
test/**/test.nex
|
||||
test/**/tmp
|
||||
test/**/node_modules
|
||||
test/**/*.map
|
||||
test/src
|
||||
test/test.log
|
||||
test-results.xml
|
||||
src
|
||||
*.log
|
||||
*.exe
|
||||
.idea
|
||||
.nexe
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
test
|
||||
src
|
||||
+1
-2
@@ -12,7 +12,7 @@
|
||||
* Gave win32 a 100 length progress bar.
|
||||
|
||||
### Commits
|
||||
|
||||
|
||||
* [**2cacd83**] Update README.md (@crcn)
|
||||
* [**0e90ac9**] Update README.md (@crcn)
|
||||
* [**54967d1**] Added Gitter badge (@jaredallard)
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
## 2015-02-14, Version v0.3.5, @jaredallard
|
||||
|
||||
|
||||
### Noteable Changes
|
||||
|
||||
* Added new flag: `--python </path/to/python>`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013 Craig Condon
|
||||
Copyright (c) 2013-2017 Nexe Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs'),
|
||||
nexe = require('../lib'),
|
||||
_log = require("../lib/log"),
|
||||
cli = require('yargs').
|
||||
usage('Usage: $0 -i [sources] -o [binary]').
|
||||
options('i', {
|
||||
demand: true,
|
||||
alias: 'input',
|
||||
desc: 'The entry javascript files',
|
||||
default: process.cwd()
|
||||
}).
|
||||
options('o', {
|
||||
demand: true,
|
||||
alias: 'output',
|
||||
desc: 'The output binary',
|
||||
default: "out.nex"
|
||||
}).
|
||||
options('r', {
|
||||
alias: 'runtime',
|
||||
default: 'latest',
|
||||
description: 'The node.js runtime to use'
|
||||
}).
|
||||
options('t', {
|
||||
alias: 'temp',
|
||||
default: './tmp/nexe',
|
||||
description: 'The path to store node.js sources'
|
||||
}).
|
||||
options('f', {
|
||||
alias: 'flags',
|
||||
description: 'Don\'t parse node and v8 flags, pass through app flags',
|
||||
default: false
|
||||
}).
|
||||
options('d', {
|
||||
alias: 'debug',
|
||||
default: false,
|
||||
description: 'generate and use source maps, large file size'
|
||||
}).
|
||||
options('j', {
|
||||
alias: 'jsFlags',
|
||||
default: false,
|
||||
description: 'v8 flags for runtime'
|
||||
}).
|
||||
options('v', {
|
||||
alias: 'version',
|
||||
description: 'Display version number'
|
||||
}).
|
||||
options('p', {
|
||||
alias: 'python',
|
||||
description: 'Set path of python to use.',
|
||||
default: 'python'
|
||||
}).
|
||||
options('F', {
|
||||
alias: 'framework',
|
||||
description: 'Set the framework to use',
|
||||
default: 'nodejs'
|
||||
});
|
||||
|
||||
var argv = cli.argv;
|
||||
if (argv.h || argv.help) {
|
||||
cli.showHelp();
|
||||
process.exit();
|
||||
} else if (argv.v || argv.version) {
|
||||
var pkginfo = require('../package.json');
|
||||
console.log(pkginfo.version);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Support network shares?
|
||||
**/
|
||||
function toAbsolute(pt) {
|
||||
//already resolved?
|
||||
try{
|
||||
fs.accessSync(pt,fs.F_OK);
|
||||
return pt;
|
||||
}catch(e){}
|
||||
|
||||
if (pt.substr(0, 1) == "/") return pt; // for *nix "/"
|
||||
if (pt.substr(0, 2) == "\\\\") return pt; // for windows "\\"
|
||||
if (pt.substr(1, 3) == ":/") return pt; // for windows "c:/"
|
||||
|
||||
// otherwise...
|
||||
return path.join(process.cwd(), pt);
|
||||
}
|
||||
|
||||
if (fs.lstatSync(argv.i).isDirectory()) {
|
||||
opts = nexe.package(path.join(argv.i, "package.json"), argv);
|
||||
nexe.compile(opts, function(error) {
|
||||
if (error) {
|
||||
return console.log(error.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
/**
|
||||
* Call the core
|
||||
**/
|
||||
nexe.compile({
|
||||
input: require.resolve(toAbsolute(argv.i)),
|
||||
output: toAbsolute(argv.o),
|
||||
flags: argv.f,
|
||||
nodeVersion: argv.r,
|
||||
python: argv.python,
|
||||
nodeTempDir: toAbsolute(argv.t),
|
||||
framework: argv.F
|
||||
},
|
||||
function(error) {
|
||||
if (error) {
|
||||
return console.log(error.message);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
machine:
|
||||
node:
|
||||
version: 5.7.0
|
||||
|
||||
test:
|
||||
override:
|
||||
- npm test:
|
||||
timeout: 5400
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
const nexe = require('.'),
|
||||
logger = require('./src/logger').logger
|
||||
|
||||
module.exports = nexe
|
||||
|
||||
if (require.main === module) {
|
||||
nexe.compile(nexe.options).catch((e) => {
|
||||
logger.error(e.stack, () => process.exit(1))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _fs = require('fs');
|
||||
|
||||
var _util = require('./util');
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
var _mkdirp = require('mkdirp');
|
||||
|
||||
var _mkdirp2 = _interopRequireDefault(_mkdirp);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
const mkdirpAsync = (0, _bluebird.promisify)(_mkdirp2.default);
|
||||
const statAsync = (0, _bluebird.promisify)(_fs.stat);
|
||||
const unlinkAsync = (0, _bluebird.promisify)(_fs.unlink);
|
||||
const readdirAsync = (0, _bluebird.promisify)(_fs.readdir);
|
||||
|
||||
function readDirAsync(dir) {
|
||||
return readdirAsync(dir).map(file => {
|
||||
const path = (0, _path.join)(dir, file);
|
||||
return statAsync(path).then(s => s.isDirectory() ? readDirAsync(path) : path);
|
||||
}).reduce((a, b) => a.concat(b), []);
|
||||
}
|
||||
|
||||
function maybeReadFileContents(file) {
|
||||
return (0, _util.readFileAsync)(file, 'utf-8').catch(e => {
|
||||
if (e.code === 'ENOENT') {
|
||||
return '';
|
||||
}
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The artifacts step is where source patches are committed, or written as "artifacts"
|
||||
* Steps:
|
||||
* - A temporary directory is created in the downloaded source
|
||||
* - On start, any files in that directory are restored into the source tree
|
||||
* - After the patch functions have run, the temporary directory is emptied
|
||||
* - Original versions of sources to be patched are written to the temporary directory
|
||||
* - Finally, The patched files are written into source.
|
||||
*
|
||||
*/
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const { src } = compiler;
|
||||
const temp = (0, _path.join)(src, 'nexe');
|
||||
yield mkdirpAsync(temp);
|
||||
const tmpFiles = yield readDirAsync(temp);
|
||||
|
||||
yield (0, _bluebird.map)(tmpFiles, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (path) {
|
||||
return compiler.writeFileAsync(path.replace(temp, ''), (yield (0, _util.readFileAsync)(path)));
|
||||
});
|
||||
|
||||
return function (_x3) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
yield next();
|
||||
|
||||
yield (0, _bluebird.map)(tmpFiles, function (x) {
|
||||
return unlinkAsync(x);
|
||||
});
|
||||
return (0, _bluebird.map)(compiler.files, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (file) {
|
||||
const sourceFile = (0, _path.join)(src, file.filename);
|
||||
const tempFile = (0, _path.join)(temp, file.filename);
|
||||
const fileContents = yield maybeReadFileContents(sourceFile);
|
||||
|
||||
yield mkdirpAsync((0, _path.dirname)(tempFile));
|
||||
yield (0, _util.writeFileAsync)(tempFile, fileContents);
|
||||
yield compiler.writeFileAsync(file.filename, file.contents);
|
||||
});
|
||||
|
||||
return function (_x4) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
||||
|
||||
function artifacts(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return artifacts;
|
||||
})();
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Craig Condon
|
||||
* Copyright (c) 2015-2016 Jared Allard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
let browserify = require('browserify'),
|
||||
path = require("path"),
|
||||
spawn = require('child_process').spawn,
|
||||
insertGlobals = require('insert-module-globals'),
|
||||
fs = require("fs"),
|
||||
async = require("async"),
|
||||
_log = require("./log");
|
||||
|
||||
/**
|
||||
* User browserify to create a "packed" file.
|
||||
*
|
||||
* @param {string} input - input file
|
||||
* @param {string} nc - node compiler dir
|
||||
* @param {array} options - nexe options
|
||||
* @param {function} complete - next function to call (async)
|
||||
**/
|
||||
function bundle(input, nc, options, complete) {
|
||||
const bundlePath = path.join(nc, "lib", "nexe.js");
|
||||
const mapfile = options.output+'.map';
|
||||
let ws = fs.createWriteStream(bundlePath);
|
||||
|
||||
const igv = '__filename,__dirname,_process';
|
||||
let insertGlobalVars = { isNexe: true },
|
||||
wantedGlobalVars = igv.split(',');
|
||||
|
||||
// parse insertGlobalVars.
|
||||
Object.keys(insertGlobals.vars).forEach(function (x) {
|
||||
if (wantedGlobalVars.indexOf(x) === -1) {
|
||||
insertGlobalVars[x] = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
let paths = [path.join(nc, 'lib')];
|
||||
|
||||
if(options.browserifyPaths) {
|
||||
paths = paths.concat(options.browserifyPaths);
|
||||
}
|
||||
|
||||
|
||||
_log('executing browserify via API');
|
||||
let bproc = browserify([input], {
|
||||
debug: options.debug,
|
||||
commondir: false,
|
||||
paths: paths,
|
||||
builtins: false,
|
||||
insertGlobalVars: insertGlobalVars,
|
||||
detectGlobals: true,
|
||||
browserField: false
|
||||
});
|
||||
|
||||
if (options.browserifyExcludes && Array.isArray(options.browserifyExcludes)) {
|
||||
for (let i = 0; i < options.browserifyExcludes.length; i++) {
|
||||
let lib = options.browserifyExcludes[i];
|
||||
_log('Excluding \'%s\' from browserify bundle', lib);
|
||||
bproc.exclude(lib);
|
||||
}
|
||||
}
|
||||
|
||||
// copy the excludes code for requires for now.
|
||||
if (options.browserifyRequires && Array.isArray(options.browserifyRequires)) {
|
||||
for (let i = 0; i < options.browserifyRequires.length; i++) {
|
||||
let lib = options.browserifyRequires[i];
|
||||
let name = lib.file || lib; // for object format.
|
||||
// if `lib` is object then fetch all params without `file`
|
||||
// otherwise returns empty object
|
||||
let opts = (lib instanceof Object) && Object.keys(lib)
|
||||
.filter((key) => key !== 'file')
|
||||
.reduce((acc, key) => { return acc[key] = lib[key], acc }, {})
|
||||
|| {};
|
||||
|
||||
_log('Force including \'%s\' in browserify bundle', name);
|
||||
bproc.require(lib, opts);
|
||||
}
|
||||
}
|
||||
|
||||
if(options.debug) {
|
||||
bproc.require(require.resolve('source-map-support'))
|
||||
}
|
||||
|
||||
let bprocbun = bproc.bundle() // bundle
|
||||
.pipe(ws) // pipe to file
|
||||
|
||||
// error on require errors, still can't contionue. ffs browserify
|
||||
bprocbun.on('error', function(err) {
|
||||
_log('error', '[browserify] '+err);
|
||||
});
|
||||
|
||||
ws.on('error', function(err) {
|
||||
console.log(err);
|
||||
_log('error', 'Failed to save stdout to disk');
|
||||
process.exit(1);
|
||||
})
|
||||
|
||||
ws.on('close', function() {
|
||||
var source = fs.readFileSync(bundlePath, 'utf8');
|
||||
source = source.replace(/[^\x00-\x7F]/g, "");
|
||||
|
||||
// write the source modified to nexe.js
|
||||
fs.writeFile(bundlePath, source, 'utf8', function(err) {
|
||||
if (err) {
|
||||
_log('error', 'failed to save source');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = bundle;
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
var _fs = require('fs');
|
||||
|
||||
var _util = require('./util');
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird.Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird.Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
function getStdIn() {
|
||||
return new _bluebird.Promise(resolve => {
|
||||
const bundle = [];
|
||||
process.stdin.setEncoding('utf-8');
|
||||
process.stdin.on('data', x => bundle.push(x));
|
||||
process.stdin.once('end', () => resolve((0, _util.dequote)(Buffer.concat(bundle).toString())));
|
||||
process.stdin.resume();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The "cli" step detects whether the process is in a tty. If it is then the input is read into memory.
|
||||
* Otherwise, it is buffered from stdin. If no input options are passed in the tty, the package.json#main file is used.
|
||||
* After all the build steps have run, the output (the executable) is written to a file or piped to stdout.
|
||||
*
|
||||
* Configuration:
|
||||
* - compiler.options.input - file path to the input bundle.
|
||||
* - fallbacks: stdin, package.json#main
|
||||
* - compiler.options.output - file path to the output executable.
|
||||
* - fallbacks: stdout, nexe_ + epoch + ext
|
||||
*
|
||||
* @param {*} compiler
|
||||
* @param {*} next
|
||||
*/
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const input = compiler.options.input;
|
||||
const bundled = Boolean(compiler.input);
|
||||
|
||||
if (bundled) {
|
||||
yield next();
|
||||
} else if (!input && !process.stdin.isTTY) {
|
||||
compiler.log.verbose('Buffering stdin as main module...');
|
||||
compiler.input = yield getStdIn();
|
||||
} else if (input) {
|
||||
compiler.log.verbose('Reading input as main module: ' + input);
|
||||
compiler.input = yield (0, _util.readFileAsync)((0, _path.normalize)(input));
|
||||
} else if (!compiler.options.empty) {
|
||||
compiler.log.verbose('Resolving cwd as main module...');
|
||||
compiler.input = yield (0, _util.readFileAsync)(require.resolve(process.cwd()));
|
||||
}
|
||||
|
||||
if (!bundled) {
|
||||
yield next();
|
||||
}
|
||||
|
||||
const deliverable = yield compiler.getDeliverableAsync();
|
||||
|
||||
return new _bluebird.Promise(function (resolve, reject) {
|
||||
deliverable.once('error', reject);
|
||||
|
||||
if (!compiler.options.output && !process.stdout.isTTY) {
|
||||
compiler.log.verbose('Writing result to stdout...');
|
||||
deliverable.pipe(process.stdout).once('error', reject);
|
||||
resolve();
|
||||
} else {
|
||||
compiler.log.verbose('Writing result to file...');
|
||||
const output = compiler.options.output || `${compiler.options.name}${isWindows ? '.exe' : ''}`;
|
||||
deliverable.pipe((0, _fs.createWriteStream)((0, _path.normalize)(output))).once('error', reject).once('close', function (e) {
|
||||
if (e) {
|
||||
reject(e);
|
||||
} else {
|
||||
resolve(compiler.log.info('Executable written: ' + output));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function cli(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return cli;
|
||||
})();
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.NexeCompiler = undefined;
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
var _fs = require('fs');
|
||||
|
||||
var _child_process = require('child_process');
|
||||
|
||||
var _logger = require('./logger');
|
||||
|
||||
var logger = _interopRequireWildcard(_logger);
|
||||
|
||||
var _util = require('./util');
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird.Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird.Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
const isBsd = Boolean(~process.platform.indexOf('bsd'));
|
||||
const make = isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make';
|
||||
const configure = isWindows ? 'configure' : './configure';
|
||||
|
||||
class NexeCompiler {
|
||||
constructor(options) {
|
||||
var _this = this;
|
||||
|
||||
this.options = options;
|
||||
logger.setLevel(options.loglevel);
|
||||
this.log = logger;
|
||||
this.python = options.python;
|
||||
this.configure = options.configure;
|
||||
this.make = isWindows ? options.vcBuild : options.make;
|
||||
this.src = (0, _path.join)(options.temp, options.version);
|
||||
this.env = Object.assign({}, process.env);
|
||||
this.files = [];
|
||||
|
||||
this.readFileAsync = (() => {
|
||||
var _ref = _asyncToGenerator(function* (file) {
|
||||
let cachedFile = _this.files.find(function (x) {
|
||||
return (0, _path.normalize)(x.filename) === (0, _path.normalize)(file);
|
||||
});
|
||||
if (!cachedFile) {
|
||||
cachedFile = {
|
||||
filename: file,
|
||||
contents: yield (0, _util.readFileAsync)((0, _path.join)(_this.src, file), 'utf-8').catch({ code: 'ENOENT' }, function () {
|
||||
return '';
|
||||
})
|
||||
};
|
||||
_this.files.push(cachedFile);
|
||||
}
|
||||
return cachedFile;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
this.writeFileAsync = (file, contents) => (0, _util.writeFileAsync)((0, _path.join)(this.src, file), contents);
|
||||
}
|
||||
|
||||
set python(pythonPath) {
|
||||
if (!pythonPath) {
|
||||
return;
|
||||
}
|
||||
if (isWindows) {
|
||||
this.env.PATH = this.env.PATH + ';"' + (0, _util.dequote)((0, _path.normalize)(pythonPath)) + '"';
|
||||
} else {
|
||||
this.env.PYTHON = pythonPath;
|
||||
}
|
||||
}
|
||||
|
||||
get _deliverableLocation() {
|
||||
return isWindows ? (0, _path.join)(this.src, 'Release', 'node.exe') : (0, _path.join)(this.src, 'out', 'Release', 'node');
|
||||
}
|
||||
|
||||
_runBuildCommandAsync(command, args) {
|
||||
return new _bluebird.Promise((resolve, reject) => {
|
||||
(0, _child_process.spawn)(command, args, {
|
||||
cwd: this.src,
|
||||
env: this.env,
|
||||
stdio: 'ignore'
|
||||
}).once('error', reject).once('close', resolve);
|
||||
});
|
||||
}
|
||||
|
||||
_configureAsync() {
|
||||
return this._runBuildCommandAsync(this.env.PYTHON || 'python', [configure, ...this.configure]);
|
||||
}
|
||||
|
||||
buildAsync() {
|
||||
var _this2 = this;
|
||||
|
||||
return _asyncToGenerator(function* () {
|
||||
yield _this2._configureAsync();
|
||||
return _this2._runBuildCommandAsync(make, _this2.make);
|
||||
})();
|
||||
}
|
||||
|
||||
getDeliverableAsync() {
|
||||
return _bluebird.Promise.resolve((0, _fs.createReadStream)(this._deliverableLocation));
|
||||
}
|
||||
}
|
||||
exports.NexeCompiler = NexeCompiler;
|
||||
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = download;
|
||||
|
||||
var _zlib = require('zlib');
|
||||
|
||||
var _tar = require('tar');
|
||||
|
||||
var _request = require('request');
|
||||
|
||||
var _request2 = _interopRequireDefault(_request);
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
var _fs = require('fs');
|
||||
|
||||
var _rimraf = require('rimraf');
|
||||
|
||||
var _rimraf2 = _interopRequireDefault(_rimraf);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const statAsync = (0, _bluebird.promisify)(_fs.stat);
|
||||
const rimrafAsync = (0, _bluebird.promisify)(_rimraf2.default);
|
||||
|
||||
function progress(req, log, precision = 10) {
|
||||
const logged = {};
|
||||
let length = 0;
|
||||
let total = 1;
|
||||
|
||||
return req.on('response', res => {
|
||||
total = res.headers['content-length'];
|
||||
}).on('data', chunk => {
|
||||
length += chunk.length;
|
||||
const percentComplete = +(length / total * 100).toFixed();
|
||||
if (percentComplete % precision === 0 && !logged[percentComplete]) {
|
||||
logged[percentComplete] = true;
|
||||
log(percentComplete);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchNodeSource(path, url, log) {
|
||||
log.info('Downloading Node: ' + url);
|
||||
return new _bluebird.Promise((resolve, reject) => {
|
||||
progress(_request2.default.get(url), pc => {
|
||||
log.verbose(`Downloading Node: ${pc}%...`);
|
||||
if (pc === 100) {
|
||||
log.info('Extracting Node...');
|
||||
}
|
||||
}).on('error', reject).pipe((0, _zlib.createGunzip)().on('error', reject)).pipe((0, _tar.Extract)({ path, strip: 1 })).on('error', reject).on('end', () => resolve(log.info('Extracted to: ' + path)));
|
||||
});
|
||||
}
|
||||
|
||||
function cleanSrc(clean, src, log) {
|
||||
if (clean === true) {
|
||||
log.info('Removing source: ' + src);
|
||||
return rimrafAsync(src).then(() => {
|
||||
log.info('Source deleted.' + src);
|
||||
});
|
||||
}
|
||||
return _bluebird.Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes (maybe) and downloads the node source to the configured temporary directory
|
||||
* @param {*} compiler
|
||||
* @param {*} next
|
||||
*/
|
||||
function download(compiler, next) {
|
||||
const { src, log } = compiler;
|
||||
const { version, sourceUrl, clean } = compiler.options;
|
||||
const url = sourceUrl || `https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`;
|
||||
|
||||
return cleanSrc(clean, src, log).then(() => statAsync(src).then(x => !x.isDirectory() && fetchNodeSource(src, url, log), e => {
|
||||
if (e.code !== 'ENOENT') {
|
||||
throw e;
|
||||
}
|
||||
return fetchNodeSource(src, url, log);
|
||||
})).then(next);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Craig Condon
|
||||
* Copyright (c) 2015-2016 Jared Allard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
let path = require("path"),
|
||||
fs = require("fs");
|
||||
|
||||
/**
|
||||
* Accessort for embed
|
||||
**/
|
||||
const accessor = function(key) {
|
||||
if (embeddedFiles.hasOwnProperty(key)) {
|
||||
return new Buffer(embeddedFiles[key], 'base64');
|
||||
} else {
|
||||
//file was not embedded, throw err.
|
||||
throw new Error('Embedded file not found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Embed files.
|
||||
*
|
||||
* @param {array} resourceFiles - array of files to embed.
|
||||
* @param {string} resourceRoot - root of resources.
|
||||
* @param {function} compelte - callback
|
||||
**/
|
||||
function embed(resourceFiles, resourceRoot, options, complete) {
|
||||
const encode = function(filePath) {
|
||||
return fs.readFileSync(filePath).toString('base64');
|
||||
}
|
||||
|
||||
resourceFiles = resourceFiles || [];
|
||||
resourceRoot = resourceRoot || "";
|
||||
|
||||
if (!Array.isArray(resourceFiles)) {
|
||||
throw new Error("Bad Argument: resourceFiles is not an array");
|
||||
}
|
||||
|
||||
let buffer = "var embeddedFiles = {\n";
|
||||
for (let i = 0; i < resourceFiles.length; ++i) {
|
||||
buffer += JSON.stringify(path.relative(resourceRoot, resourceFiles[i])) + ': "';
|
||||
buffer += encode(resourceFiles[i]) + '",\n';
|
||||
}
|
||||
|
||||
buffer += "\n};\n\nmodule.exports.keys = function () { return Object.keys(embeddedFiles); }\n\nmodule.exports.get = ";
|
||||
buffer += accessor.toString();
|
||||
complete(null, buffer);
|
||||
}
|
||||
|
||||
module.exports = embed;
|
||||
-1052
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
module.exports = require("./exe");
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Craig Condon
|
||||
* Copyright (c) 2015-2016 Jared Allard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**/
|
||||
|
||||
var colors = require('colors');
|
||||
|
||||
/**
|
||||
* standard output, takes 3 different types.
|
||||
* log, error, and warn
|
||||
*
|
||||
* @param {any} arguments - Text to output.
|
||||
* @return undefined
|
||||
**/
|
||||
function _log () {
|
||||
|
||||
var args = Array.prototype.slice.call(arguments, 0),
|
||||
level = args.shift();
|
||||
|
||||
if (!~["log", "error", "warn"].indexOf(level)) {
|
||||
args.unshift(level);
|
||||
level = "log";
|
||||
}
|
||||
|
||||
if(level == "log") {
|
||||
args[0] = "----> " + args[0];
|
||||
} else if(level == "error") {
|
||||
args[0] = "....> " + colors.red("ERROR: ") + args[0]
|
||||
} else if(level == "warn") {
|
||||
args[0] = "....> " + colors.yellow("WARNING: ") + args[0]
|
||||
}
|
||||
|
||||
console[level].apply(console, args);
|
||||
}
|
||||
|
||||
// export the log function, for require()
|
||||
module.exports = _log;
|
||||
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.verbose = exports.error = exports.info = exports.setLevel = undefined;
|
||||
|
||||
var _os = require('os');
|
||||
|
||||
var _chalk = require('chalk');
|
||||
|
||||
var _chalk2 = _interopRequireDefault(_chalk);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function isFn(f) {
|
||||
return typeof f === 'function';
|
||||
}
|
||||
|
||||
function logNoop(x, cb) {
|
||||
return isFn(cb) && process.nextTick(cb);
|
||||
}
|
||||
|
||||
function safeCb(f) {
|
||||
return isFn(f) ? f : logNoop;
|
||||
}
|
||||
|
||||
const logLevels = [['verbose', 'green'], ['info', 'blue'], ['error', 'red']];
|
||||
|
||||
const logger = logLevels.reduce((logMethods, info) => {
|
||||
const [level, color] = info;
|
||||
logMethods[level] = function (output, cb) {
|
||||
process.stderr.write(_chalk2.default[color](`${_os.EOL}[${level}]: ${output}`), safeCb(cb));
|
||||
};
|
||||
return logMethods;
|
||||
}, {
|
||||
setLevel(level) {
|
||||
if (level === 'silent') {
|
||||
logLevels.forEach(([x]) => {
|
||||
logger[x] = logNoop;
|
||||
});
|
||||
return;
|
||||
}
|
||||
process.on('beforeExit', () => {
|
||||
process.stderr.write(_os.EOL);
|
||||
});
|
||||
if (level === 'info') {
|
||||
logger.verbose = logNoop;
|
||||
}
|
||||
return logger;
|
||||
}
|
||||
});
|
||||
|
||||
const { info, error, verbose, setLevel } = logger;
|
||||
|
||||
exports.setLevel = setLevel;
|
||||
exports.info = info;
|
||||
exports.error = error;
|
||||
exports.verbose = verbose;
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Craig Condon
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**/
|
||||
|
||||
var async = require("async"),
|
||||
fs = require("fs"),
|
||||
_log = require("./log");
|
||||
|
||||
/**
|
||||
* Monkey patch a file.
|
||||
*
|
||||
* @param {string} filePath - path to file.
|
||||
* @param {function} monkeyPatched - function to process contents
|
||||
* @param {function} processor - TODO: detail what this is
|
||||
* @param {function} complete - callback
|
||||
*
|
||||
* @return undefined
|
||||
*/
|
||||
function _monkeypatch (filePath, monkeyPatched, processor, complete) {
|
||||
|
||||
async.waterfall([
|
||||
|
||||
function read (next) {
|
||||
fs.readFile(filePath, "utf8", next);
|
||||
},
|
||||
|
||||
// TODO - need to parse gyp file - this is a bit hacker
|
||||
function monkeypatch (content, next) {
|
||||
|
||||
if (monkeyPatched(content)) return complete();
|
||||
|
||||
_log("monkey patch %s", filePath);
|
||||
processor(content, next);
|
||||
},
|
||||
|
||||
function write (content, next) {
|
||||
fs.writeFile(filePath, content, "utf8", next);
|
||||
}
|
||||
], complete);
|
||||
}
|
||||
|
||||
// export the function for require()
|
||||
module.exports = _monkeypatch;
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.compile = exports.isNexe = exports.argv = undefined;
|
||||
|
||||
let compile = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compilerOptions, callback) {
|
||||
const options = yield (0, _options.normalizeOptionsAsync)(compilerOptions);
|
||||
const compiler = new _compiler.NexeCompiler(options);
|
||||
|
||||
compiler.log.verbose('Compiler options:' + _os.EOL + JSON.stringify(compiler.options, null, 4));
|
||||
|
||||
const nexe = (0, _appBuilder.compose)(_bundle2.default, _cli2.default, _download2.default, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_, next) {
|
||||
yield next();
|
||||
return compiler.buildAsync();
|
||||
});
|
||||
|
||||
return function (_x3, _x4) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})(), _artifacts2.default, _patches2.default, compiler.options.patches);
|
||||
return nexe(compiler).asCallback(callback);
|
||||
});
|
||||
|
||||
return function compile(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
var _appBuilder = require('app-builder');
|
||||
|
||||
var _bundle = require('./bundle');
|
||||
|
||||
var _bundle2 = _interopRequireDefault(_bundle);
|
||||
|
||||
var _compiler = require('./compiler');
|
||||
|
||||
var _options = require('./options');
|
||||
|
||||
var _cli = require('./cli');
|
||||
|
||||
var _cli2 = _interopRequireDefault(_cli);
|
||||
|
||||
var _download = require('./download');
|
||||
|
||||
var _download2 = _interopRequireDefault(_download);
|
||||
|
||||
var _artifacts = require('./artifacts');
|
||||
|
||||
var _artifacts2 = _interopRequireDefault(_artifacts);
|
||||
|
||||
var _patches = require('./patches');
|
||||
|
||||
var _patches2 = _interopRequireDefault(_patches);
|
||||
|
||||
var _os = require('os');
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
var _logger = require('./logger');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird.Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird.Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
_appBuilder.PromiseConfig.constructor = _bluebird.Promise;
|
||||
(0, _bluebird.longStackTraces)();
|
||||
|
||||
function isNexe(callback) {
|
||||
return _bluebird.Promise.resolve(Boolean(process.__nexe)).asCallback(callback);
|
||||
}
|
||||
|
||||
exports.argv = _options.argv;
|
||||
exports.isNexe = isNexe;
|
||||
exports.compile = compile;
|
||||
|
||||
|
||||
if (require.main === module || process.__nexe) {
|
||||
compile(_options.argv).catch(e => {
|
||||
(0, _logger.error)(e.stack, () => process.exit(e.exitCode || 1));
|
||||
});
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.normalizeOptionsAsync = exports.argv = undefined;
|
||||
|
||||
var _minimist = require('minimist');
|
||||
|
||||
var _minimist2 = _interopRequireDefault(_minimist);
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
var _os = require('os');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function padRight(str, l) {
|
||||
return (str + ' '.repeat(l)).substr(0, l);
|
||||
}
|
||||
const defaults = {
|
||||
temp: process.env.NEXE_TEMP || (0, _path.join)(process.cwd(), '.nexe'),
|
||||
version: process.version.slice(1),
|
||||
flags: [],
|
||||
configure: [],
|
||||
make: [],
|
||||
vcBuild: ['nosign', 'release'],
|
||||
quick: false,
|
||||
bundle: true,
|
||||
enableNodeCli: false,
|
||||
verbose: false,
|
||||
silent: false,
|
||||
padding: 2,
|
||||
patches: []
|
||||
};
|
||||
const alias = {
|
||||
i: 'input',
|
||||
o: 'output',
|
||||
t: 'temp',
|
||||
n: 'name',
|
||||
v: 'version',
|
||||
p: 'python',
|
||||
f: 'flag',
|
||||
c: 'configure',
|
||||
m: 'make',
|
||||
vc: 'vcBuild',
|
||||
q: 'quick',
|
||||
s: 'snapshot',
|
||||
b: 'bundle',
|
||||
cli: 'enableNodeCli',
|
||||
h: 'help',
|
||||
l: 'loglevel'
|
||||
};
|
||||
const argv = (0, _minimist2.default)(process.argv, { alias, default: defaults });
|
||||
const help = `
|
||||
nexe --help CLI OPTIONS
|
||||
|
||||
-i --input =./index.js -- application entry point
|
||||
-o --output =./nexe.exe -- path to output file
|
||||
-t --temp =./.nexe -- nexe temp directory (3Gb+) ~ NEXE_TEMP
|
||||
-n --name =nexe.js -- file name for error reporting at run time
|
||||
-v --version =${padRight(process.version.slice(1), 23)}-- node version
|
||||
-p --python =/path/to/python2 -- python executable
|
||||
-f --flag ="--expose-gc" -- *v8 flags to include during compilation
|
||||
-c --configure ="--with-dtrace" -- *pass arguments to the configure command
|
||||
-m --make ="--loglevel" -- *pass arguments to the make command
|
||||
-vc --vcBuild =x64 -- *pass arguments to vcbuild.bat
|
||||
-s --snapshot =/path/to/snapshot -- build with warmup snapshot
|
||||
-b --bundle -- attempt bundling application
|
||||
--ico -- file name for alternate icon file (windows)
|
||||
--rc-* -- populate rc file options (windows)
|
||||
--clean -- force download of sources
|
||||
--enableNodeCli -- enable node cli enforcement (blocks app cli)
|
||||
--sourceUrl -- pass an alternate source (node.tar.gz) url
|
||||
--silent -- disable logging
|
||||
--verbose -- set logging to verbose
|
||||
|
||||
|
||||
-* variable key name * option can be used more than once
|
||||
|
||||
TODO -q --quick =win32-x64-X.X.X -- use prebuilt binary (url, key or path)
|
||||
TODO --resource-* =/path/to/resource -- *embed file bytes within the binary
|
||||
`.trim();
|
||||
|
||||
function flattenFilter(...args) {
|
||||
return [].concat(...args).filter(x => x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract keys such as { "rc-CompanyName": "Node.js" } to
|
||||
* { CompanyName: "Node.js" }
|
||||
* @param {*} match
|
||||
* @param {*} options
|
||||
*/
|
||||
function extractCliMap(match, options) {
|
||||
Object.keys(options).filter(x => match.test(x)).reduce((map, option) => {
|
||||
const key = option.split('-')[1];
|
||||
map = map || {};
|
||||
map[key] = options[option];
|
||||
delete options[option];
|
||||
return map;
|
||||
}, null);
|
||||
}
|
||||
|
||||
function tryResolveMainFileName() {
|
||||
let filename = 'nexe';
|
||||
try {
|
||||
const file = require.resolve(process.cwd());
|
||||
filename = (0, _path.basename)(file).replace((0, _path.extname)(file), '');
|
||||
} catch (_) {}
|
||||
|
||||
return filename === 'index' ? 'nexe_' + Date.now() : filename;
|
||||
}
|
||||
|
||||
function extractLogLevel(options) {
|
||||
if (options.loglevel) return options.loglevel;
|
||||
if (options.silent) return 'silent';
|
||||
if (options.verbose) return 'verbose';
|
||||
if (options.info) return 'info';
|
||||
}
|
||||
|
||||
function extractName(options) {
|
||||
if (typeof options.input === 'string') {
|
||||
return options.name || (0, _path.basename)(options.input).replace((0, _path.extname)(options.input), '');
|
||||
}
|
||||
const mainName = tryResolveMainFileName();
|
||||
return options.name || mainName;
|
||||
}
|
||||
|
||||
function normalizeOptionsAsync(input) {
|
||||
if (argv.help || Boolean(argv._.find(x => x === 'version'))) {
|
||||
return (0, _bluebird.fromCallback)(cb => process.stderr.write(argv.help ? help : '2.0.0-beta.1' + _os.EOL, () => cb(null, process.exit(1))));
|
||||
}
|
||||
|
||||
const options = Object.assign({}, defaults, input);
|
||||
delete options._;
|
||||
options.loglevel = extractLogLevel(options);
|
||||
options.name = extractName(options);
|
||||
options.flags = flattenFilter(options.flag, options.flags);
|
||||
options.make = flattenFilter(options.make);
|
||||
options.vcBuild = flattenFilter(options.vcBuild);
|
||||
options.rc = options.rc || extractCliMap(/^rc-.*/, options);
|
||||
options.resources = options.resources || extractCliMap(/^resource-.*/, options);
|
||||
Object.keys(alias).filter(k => k !== 'rc').forEach(x => delete options[x]);
|
||||
|
||||
return _bluebird.Promise.resolve(options);
|
||||
}
|
||||
|
||||
exports.argv = argv;
|
||||
exports.normalizeOptionsAsync = normalizeOptionsAsync;
|
||||
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _buffer = require('buffer');
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
yield next();
|
||||
|
||||
const filename = 'lib/' + compiler.options.name + '.js';
|
||||
const file = yield compiler.readFileAsync(filename);
|
||||
const header = '/' + '*'.repeat(19) + 'nexe_';
|
||||
const end = '_' + '*'.repeat(19) + '/';
|
||||
const padding = Array(compiler.options.padding * 1000000).fill('*').join('');
|
||||
|
||||
if (!padding) {
|
||||
file.contents = compiler.input;
|
||||
return;
|
||||
}
|
||||
|
||||
file.contents = [compiler.input, '/', padding, '/'].join('');
|
||||
|
||||
file.contents = header + _buffer.Buffer.byteLength(file.contents) + end + file.contents;
|
||||
});
|
||||
|
||||
function content(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return content;
|
||||
})();
|
||||
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
if (compiler.options.enableNodeCli) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const nodecc = yield compiler.readFileAsync('src/node.cc');
|
||||
console.log(nodecc);
|
||||
const nodeccMarker = "argv[index][0] == '-'";
|
||||
|
||||
nodecc.contents = nodecc.contents.replace(nodeccMarker, nodeccMarker.replace('-', ']'));
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
function disableNodeCli(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return disableNodeCli;
|
||||
})();
|
||||
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const nodeflags = compiler.options.flags;
|
||||
if (!nodeflags.length) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const nodegyp = yield compiler.readFileAsync('node.gyp');
|
||||
|
||||
nodegyp.contents = nodegyp.contents.replace("'node_v8_options%': ''", `'node_v8_options%': '${nodeflags.join(' ')}'`);
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
function flags(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return flags;
|
||||
})();
|
||||
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* ({ files, readFileAsync }, next) {
|
||||
yield next();
|
||||
|
||||
const nodegyp = yield readFileAsync('node.gyp');
|
||||
const nodeGypMarker = "'lib/fs.js',";
|
||||
|
||||
nodegyp.contents = nodegyp.contents.replace(nodeGypMarker, `
|
||||
${nodeGypMarker}
|
||||
${files.filter(function (x) {
|
||||
return x.filename.startsWith('lib');
|
||||
}).map(function (x) {
|
||||
return `'${x.filename}'`;
|
||||
}).toString()},
|
||||
`.trim());
|
||||
});
|
||||
|
||||
function nodeGyp(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return nodeGyp;
|
||||
})();
|
||||
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _util = require('../util');
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const iconFile = compiler.options.ico;
|
||||
if (!iconFile) {
|
||||
return next();
|
||||
}
|
||||
const file = yield compiler.readFileAsync('src/res/node.ico');
|
||||
file.contents = yield (0, _util.readFileAsync)((0, _path.normalize)(iconFile));
|
||||
return next();
|
||||
});
|
||||
|
||||
function ico(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return ico;
|
||||
})();
|
||||
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _gyp = require('./gyp');
|
||||
|
||||
var _gyp2 = _interopRequireDefault(_gyp);
|
||||
|
||||
var _content = require('./content');
|
||||
|
||||
var _content2 = _interopRequireDefault(_content);
|
||||
|
||||
var _thirdPartyMain = require('./third-party-main');
|
||||
|
||||
var _thirdPartyMain2 = _interopRequireDefault(_thirdPartyMain);
|
||||
|
||||
var _disableNodeCli = require('./disable-node-cli');
|
||||
|
||||
var _disableNodeCli2 = _interopRequireDefault(_disableNodeCli);
|
||||
|
||||
var _flags = require('./flags');
|
||||
|
||||
var _flags2 = _interopRequireDefault(_flags);
|
||||
|
||||
var _ico = require('./ico');
|
||||
|
||||
var _ico2 = _interopRequireDefault(_ico);
|
||||
|
||||
var _nodeRc = require('./node-rc');
|
||||
|
||||
var _nodeRc2 = _interopRequireDefault(_nodeRc);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const patches = [_gyp2.default, _content2.default, _thirdPartyMain2.default, _disableNodeCli2.default, _flags2.default, _ico2.default, _nodeRc2.default];
|
||||
|
||||
exports.default = patches;
|
||||
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const options = compiler.options.rc;
|
||||
if (!options) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const file = yield compiler.readFileAsync('src/res/node.rc');
|
||||
|
||||
Object.keys(options).forEach(function (key) {
|
||||
let value = options[key];
|
||||
const isVar = /^[A-Z_]+$/.test(value);
|
||||
|
||||
value = isVar ? value : `"${value}"`;
|
||||
file.contents.replace(new RegExp(`VALUE "${key}",*`), `VALUE "${key}", ${value}`);
|
||||
});
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
function nodeRc(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return nodeRc;
|
||||
})();
|
||||
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const snapshotFile = compiler.options.snapshot;
|
||||
|
||||
if (!snapshotFile) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const file = yield compiler.readFileAsync('configure');
|
||||
file.contents = file.contents.replace('def configure_v8(o):', `def configure_v8(o):\n o['variables']['embed_script'] = '${snapshotFile}'\n o['variables']['warmup_script'] = '${snapshotFile}'`);
|
||||
return next();
|
||||
});
|
||||
|
||||
function snapshot(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return snapshot;
|
||||
})();
|
||||
@@ -0,0 +1,37 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
exports.default = (() => {
|
||||
var _ref = _asyncToGenerator(function* (compiler, next) {
|
||||
const mainFile = yield compiler.readFileAsync('lib/_third_party_main.js');
|
||||
mainFile.contents = `
|
||||
Object.defineProperty(process, '__nexe', {
|
||||
value: true,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: false
|
||||
});
|
||||
require("${compiler.options.name}");
|
||||
`.trim();
|
||||
|
||||
if (compiler.options.empty === true) {
|
||||
compiler.options.resources.length = 0;
|
||||
//eslint-disable-next-line
|
||||
compiler.input = 'console.log(`nexe-${process.platform}-${process.arch}-${process.version}`)';
|
||||
return next();
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
function main(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
}
|
||||
|
||||
return main;
|
||||
})();
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.dequote = exports.writeFileAsync = exports.readFileAsync = undefined;
|
||||
|
||||
var _fs = require('fs');
|
||||
|
||||
var _bluebird = require('bluebird');
|
||||
|
||||
function dequote(input) {
|
||||
input = input.trim();
|
||||
|
||||
const singleQuote = input.startsWith('\'') && input.endsWith('\'');
|
||||
const doubleQuote = input.startsWith('"') && input.endsWith('"');
|
||||
if (singleQuote || doubleQuote) {
|
||||
return input.slice(1).slice(0, -1);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
const readFileAsync = (0, _bluebird.promisify)(_fs.readFile);
|
||||
const writeFileAsync = (0, _bluebird.promisify)(_fs.writeFile);
|
||||
|
||||
exports.readFileAsync = readFileAsync;
|
||||
exports.writeFileAsync = writeFileAsync;
|
||||
exports.dequote = dequote;
|
||||
+21
-40
@@ -1,55 +1,36 @@
|
||||
{
|
||||
"author": "Jared Allard <jaredallard@outlook.com>",
|
||||
"name": "nexe",
|
||||
"description": "create single executables out of your [node/io].js applications",
|
||||
"description": "Create a single executable out of your Node.js application",
|
||||
"license": "MIT",
|
||||
"version": "1.1.2",
|
||||
"version": "2.0.0-beta.1",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Criag Condon",
|
||||
"email": "craig.j.condon@gmail.com",
|
||||
"url": "http://crcn.io/"
|
||||
}
|
||||
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
|
||||
"Jared Allard <jaredallard@outlook.com>",
|
||||
"Caleb Boyd <caleb.boyd@hotmail.com>"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "echo node: $(node -v) && node_modules/.bin/mocha --reporter mocha-circleci-reporter test/test.js"
|
||||
"lint": "eslint index.js ./src/**/*",
|
||||
"test": "npm run lint"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jaredallard/nexe.git"
|
||||
"url": "git://github.com/nexe/nexe.git"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"dependencies": {
|
||||
"async": "^1.5.2",
|
||||
"browserify": "^13.0.0",
|
||||
"colors": "^1.1.2",
|
||||
"glob": "^7.0.0",
|
||||
"gunzip-maybe": "^1.3.1",
|
||||
"insert-module-globals": "^7.0.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"module-deps": "^4.0.5",
|
||||
"ncp": "^2.0.0",
|
||||
"progress": "^1.1.8",
|
||||
"request": "^2.67.0",
|
||||
"tar-stream": "^1.3.1",
|
||||
"yargs": "^4.2.0"
|
||||
},
|
||||
"nexe": {
|
||||
"input": "./bin/nexe",
|
||||
"output": "nexe^$",
|
||||
"temp": "src",
|
||||
"runtime": {
|
||||
"framework": "nodejs",
|
||||
"version": "5.5.0",
|
||||
"ignoreFlags": true
|
||||
}
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"main": "src/nexe.js",
|
||||
"bin": {
|
||||
"nexe": "bin/nexe"
|
||||
"nexe": "index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"app-builder": "^5.1.0",
|
||||
"bluebird": "^3.5.0",
|
||||
"chalk": "^1.1.3",
|
||||
"memory-fs": "^0.4.1",
|
||||
"minimist": "^1.2.0",
|
||||
"request": "^2.81.0",
|
||||
"tar": "^2.2.1",
|
||||
"webpack": "^2.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^2.4.5",
|
||||
"mocha-circleci-reporter": "0.0.1"
|
||||
"eslint": "^3.19.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
const
|
||||
{ join, dirname } = require('path'),
|
||||
{ readdir, stat, readFile, unlink, writeFile } = require('fs'),
|
||||
{ promisify, map, coroutine } = require('bluebird'),
|
||||
mkdirpAsync = promisify(require('mkdirp')),
|
||||
statAsync = promisify(stat),
|
||||
unlinkAsync = promisify(unlink),
|
||||
readdirAsync = promisify(readdir),
|
||||
writeAnyFileAsync = promisify(writeFile),
|
||||
readFileAsync = promisify(readFile),
|
||||
readDirAsync = (dir) => {
|
||||
return readdirAsync(dir).map((file) => {
|
||||
const path = join(dir, file)
|
||||
return statAsync(path).then(s => s.isDirectory() ? readDirAsync(path) : path)
|
||||
}).reduce((a, b) => a.concat(b), [])
|
||||
},
|
||||
maybeReadFileContents = (file) => {
|
||||
return readFileAsync(file, 'utf-8')
|
||||
.catch(e => {
|
||||
if (e.code === 'ENOENT') {
|
||||
return ''
|
||||
}
|
||||
throw e
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The artifacts step is where source patches are committed, or written as "artifacts"
|
||||
* Steps:
|
||||
* - A temporary directory is created in the downloaded source
|
||||
* - On start, any files in that directory are restored into the source tree
|
||||
* - After the patch functions have run, the temporary directory is emptied
|
||||
* - Original versions of sources to be patched are written to the temporary directory
|
||||
* - Finally, The patched files are written into source.
|
||||
*
|
||||
*/
|
||||
module.exports.artifacts = function* artifacts ({ files, writeFileAsync, src }, next) {
|
||||
const temp = join(src, 'nexe')
|
||||
yield mkdirpAsync(temp)
|
||||
const tmpFiles = yield readDirAsync(temp)
|
||||
|
||||
yield map(tmpFiles, coroutine(function* (path) {
|
||||
return writeFileAsync(path.replace(temp, ''), yield readFileAsync(path))
|
||||
}))
|
||||
|
||||
yield next()
|
||||
|
||||
yield map(tmpFiles, x => unlinkAsync(x))
|
||||
return map(files, coroutine(function* (file) {
|
||||
const sourceFile = join(src, file.filename),
|
||||
tempFile = join(temp, file.filename),
|
||||
fileContents = yield maybeReadFileContents(sourceFile)
|
||||
|
||||
yield mkdirpAsync(dirname(tempFile))
|
||||
yield writeAnyFileAsync(tempFile, fileContents)
|
||||
yield writeFileAsync(file.filename, file.contents)
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
const Mfs = require('memory-fs'),
|
||||
webpack = require('webpack'),
|
||||
{ fromCallback } = require('bluebird'),
|
||||
{ resolve, join, relative } = require('path'),
|
||||
isObject = (x) => typeof x === 'object',
|
||||
isString = (x) => typeof x === 'string'
|
||||
|
||||
function* bundle (compiler, next) {
|
||||
let bundleConfig = compiler.options.bundle
|
||||
if (!bundleConfig) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const
|
||||
input = compiler.options.input || require.resolve(process.cwd()),
|
||||
fs = new Mfs(),
|
||||
path = resolve('nexe'),
|
||||
filename = 'virtual-bundle.js'
|
||||
|
||||
if (isString(bundleConfig)) {
|
||||
bundleConfig === require(relative(process.cwd(), bundleConfig))
|
||||
} else if (!isObject(bundleConfig)) {
|
||||
bundleConfig = {
|
||||
entry: resolve(input),
|
||||
target: 'node',
|
||||
output: { path, filename }
|
||||
}
|
||||
}
|
||||
|
||||
const bundler = webpack(bundleConfig)
|
||||
bundler.outputFileSystem = fs
|
||||
const stats = yield fromCallback(cb => bundler.run(cb))
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
compiler.log.error(stats.toString())
|
||||
return null
|
||||
}
|
||||
//eslint-disable-next-line no-sync
|
||||
compiler.input = fs.readFileSync(
|
||||
join(bundleConfig.output.path, bundleConfig.output.filename)
|
||||
)
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
module.exports.bundle = bundle
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
const
|
||||
{ normalize } = require('path'),
|
||||
{ Promise, promisify } = require('bluebird'),
|
||||
{ createWriteStream, readFile } = require('fs')
|
||||
|
||||
const readFileAsync = promisify(readFile),
|
||||
isWindows = process.platform === 'win32'
|
||||
|
||||
function dequoteStdIn (input) {
|
||||
input = input.trim()
|
||||
if (input.startsWith('\'') && input.endsWith('\'') ||
|
||||
input.startsWith('"') && input.endsWith('"')) {
|
||||
return input.slice(1).slice(0, -1)
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
function getStdIn () {
|
||||
return new Promise((resolve) => {
|
||||
const bundle = []
|
||||
process.stdin.setEncoding('utf-8')
|
||||
process.stdin.on('data', x => bundle.push(x))
|
||||
process.stdin.once('end', () =>
|
||||
resolve(dequoteStdIn(Buffer.concat(bundle).toString()))
|
||||
)
|
||||
process.stdin.resume()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The "cli" step detects whether the process is in a tty. If it is then the input is read into memory.
|
||||
* Otherwise, it is buffered from stdin. If no input options are passed in the tty, the package.json#main file is used.
|
||||
* After all the build steps have run, the output (the executable) is written to a file or piped to stdout.
|
||||
*
|
||||
* Configuration:
|
||||
* - compiler.options.input - file path to the input bundle.
|
||||
* - fallbacks: stdin, package.json#main
|
||||
* - compiler.options.output - file path to the output executable.
|
||||
* - fallbacks: stdout, nexe_ + epoch + ext
|
||||
*
|
||||
* @param {*} compiler
|
||||
* @param {*} next
|
||||
*/
|
||||
module.exports.cli = function* cli (compiler, next) {
|
||||
const input = compiler.options.input,
|
||||
bundled = Boolean(compiler.input)
|
||||
|
||||
if (bundled) {
|
||||
yield next()
|
||||
} else if (!input && !process.stdin.isTTY) {
|
||||
compiler.log.verbose('Buffering stdin as main module...')
|
||||
compiler.input = yield getStdIn()
|
||||
} else if (input) {
|
||||
compiler.log.verbose('Reading input as main module: ' + input)
|
||||
compiler.input = yield readFileAsync(normalize(input))
|
||||
} else if (!compiler.options.empty) {
|
||||
compiler.log.verbose('Resolving cwd as main module...')
|
||||
compiler.input = yield readFileAsync(require.resolve(process.cwd()))
|
||||
}
|
||||
|
||||
if (!bundled) {
|
||||
yield next()
|
||||
}
|
||||
|
||||
const deliverable = yield compiler.getDeliverableAsync()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
deliverable.once('error', reject)
|
||||
|
||||
if (!compiler.options.output && !process.stdout.isTTY) {
|
||||
compiler.log.verbose('Writing result to stdout...')
|
||||
deliverable.pipe(process.stdout).once('error', reject)
|
||||
resolve()
|
||||
} else {
|
||||
compiler.log.verbose('Writing result to file...')
|
||||
const output = compiler.options.output || `${compiler.options.name}${isWindows ? '.exe' : ''}`
|
||||
deliverable.pipe(createWriteStream(normalize(output)))
|
||||
.once('error', reject)
|
||||
.once('close', e => {
|
||||
if (e) {
|
||||
reject(e)
|
||||
} else {
|
||||
resolve(compiler.log.info('Executable written: ' + output))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
const
|
||||
{ dirname, normalize, join } = require('path'),
|
||||
{ promisify, Promise, coroutine } = require('bluebird'),
|
||||
{ normalizeOptions } = require('./options'),
|
||||
{ readFile, writeFile, createReadStream } = require('fs'),
|
||||
{ spawn } = require('child_process'),
|
||||
{ logger } = require('./logger')
|
||||
|
||||
const
|
||||
isWindows = process.platform === 'win32',
|
||||
isBsd = Boolean(~process.platform.indexOf('bsd')),
|
||||
make = isWindows && 'vcbuild.bat' ||
|
||||
isBsd && 'gmake' ||
|
||||
'make',
|
||||
configure = isWindows ? 'configure' : './configure',
|
||||
readFileAsync = promisify(readFile),
|
||||
writeFileAsync = promisify(writeFile)
|
||||
|
||||
module.exports.NexeCompiler = class NexeCompiler {
|
||||
constructor (options) {
|
||||
options = this.options = normalizeOptions(options)
|
||||
logger.setLevel(options.loglevel)
|
||||
this.log = logger
|
||||
this.python = options.python
|
||||
this.configure = options.configure
|
||||
this.make = isWindows ? options.vcBuild : options.make
|
||||
this.src = join(options.temp, options.version)
|
||||
this.env = Object.assign({}, process.env)
|
||||
this.files = []
|
||||
|
||||
this.readFileAsync = coroutine(function * (file) {
|
||||
const cachedFile = this.files.find(x => normalize(x.filename) === normalize(file))
|
||||
if (cachedFile) {
|
||||
return Promise.resolve(cachedFile)
|
||||
}
|
||||
this.files.push({
|
||||
filename: file,
|
||||
contents: yield readFileAsync(join(this.src, file), 'utf-8').catch(e => {
|
||||
if (e.code !== 'ENOENT') {
|
||||
throw e
|
||||
}
|
||||
return ''
|
||||
})
|
||||
})
|
||||
return this.readFileAsync(file)
|
||||
}.bind(this))
|
||||
this.writeFileAsync = (file, contents) => writeFileAsync(join(this.src, file), contents)
|
||||
}
|
||||
|
||||
set python (pythonPath) {
|
||||
if (!pythonPath) {
|
||||
return
|
||||
}
|
||||
if (isWindows) {
|
||||
this.env.PATH = this.env.PATH + ';' + normalize(dirname(pythonPath))
|
||||
} else {
|
||||
this.env.PYTHON = pythonPath
|
||||
}
|
||||
}
|
||||
|
||||
get _deliverableLocation () {
|
||||
return isWindows
|
||||
? join(this.src, 'Release', 'node.exe')
|
||||
: join(this.src, 'out', 'Release', 'node')
|
||||
}
|
||||
|
||||
_runBuildCommandAsync (command, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
spawn(command, args, {
|
||||
cwd: this.src,
|
||||
env: this.env,
|
||||
stdio: 'ignore'
|
||||
})
|
||||
.once('error', reject)
|
||||
.once('close', resolve)
|
||||
})
|
||||
}
|
||||
|
||||
_configureAsync () {
|
||||
return this._runBuildCommandAsync(
|
||||
this.env.PYTHON || 'python',
|
||||
[configure, ...this.configure]
|
||||
)
|
||||
}
|
||||
|
||||
buildAsync () {
|
||||
return this._configureAsync()
|
||||
.then(() => this._runBuildCommandAsync(make, this.make))
|
||||
}
|
||||
|
||||
getDeliverableAsync () {
|
||||
return Promise.resolve(createReadStream(this._deliverableLocation))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
const
|
||||
unZip = require('zlib').createGunzip,
|
||||
unTar = require('tar').Extract,
|
||||
request = require('request'),
|
||||
{ Promise, promisify } = require('bluebird'),
|
||||
statAsync = promisify(require('fs').stat),
|
||||
rimrafAsync = promisify(require('rimraf'))
|
||||
|
||||
function progress (req, log, precision = 10) {
|
||||
const logged = {}
|
||||
let length = 0,
|
||||
total = 1
|
||||
|
||||
return req.on('response', (res) => {
|
||||
total = res.headers['content-length']
|
||||
}).on('data', (chunk) => {
|
||||
length += chunk.length
|
||||
const percentComplete = +(length / total * 100).toFixed()
|
||||
if (percentComplete % precision === 0 && !logged[percentComplete]) {
|
||||
logged[percentComplete] = true
|
||||
log(percentComplete)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function fetchNodeSource (path, url, log) {
|
||||
log.info('Downloading Node: ' + url)
|
||||
return new Promise((resolve, reject) => {
|
||||
progress(request.get(url), (pc) => {
|
||||
log.verbose(`Downloading Node: ${pc}%...`)
|
||||
if (pc === 100) {
|
||||
log.info('Extracting Node...')
|
||||
}
|
||||
}).on('error', reject)
|
||||
.pipe(unZip().on('error', reject))
|
||||
.pipe(unTar({ path, strip: 1 }))
|
||||
.on('error', reject)
|
||||
.on('end', () => resolve(log.info('Extracted to: ' + path)))
|
||||
})
|
||||
}
|
||||
|
||||
function cleanSrc (clean, src, log) {
|
||||
if (clean === true) {
|
||||
log.info('Removing source: ' + src)
|
||||
return rimrafAsync(src).then(() => {
|
||||
log.info('Source deleted.' + src)
|
||||
})
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes (maybe) and downloads the node source to the configured temporary directory
|
||||
* @param {*} compiler
|
||||
* @param {*} next
|
||||
*/
|
||||
function download (compiler, next) {
|
||||
const
|
||||
{ src, log } = compiler,
|
||||
{ version, sourceUrl, clean } = compiler.options,
|
||||
url = sourceUrl ||
|
||||
`https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`
|
||||
|
||||
return cleanSrc(clean, src, log).then(() => statAsync(src).then(
|
||||
x => !x.isDirectory() && fetchNodeSource(src, url, log),
|
||||
e => {
|
||||
if (e.code !== 'ENOENT') {
|
||||
throw e
|
||||
}
|
||||
return fetchNodeSource(src, url, log)
|
||||
}
|
||||
)).then(next)
|
||||
}
|
||||
|
||||
module.exports.download = download
|
||||
@@ -0,0 +1,35 @@
|
||||
const
|
||||
EOL = require('os').EOL,
|
||||
colors = require('chalk'),
|
||||
isFn = f => typeof f === 'function',
|
||||
logNoop = (x, cb) => {
|
||||
isFn(cb) && process.nextTick(cb)
|
||||
},
|
||||
safeCb = f => isFn(f) ? f : logNoop,
|
||||
logLevels = [
|
||||
['verbose', 'green'],
|
||||
['info', 'blue'],
|
||||
['error', 'red']
|
||||
],
|
||||
logger = logLevels.reduce((logMethods, info) => {
|
||||
const [level, color] = info
|
||||
logMethods[level] = function (output, cb) {
|
||||
process.stderr.write(colors[color](`${EOL}[${level}]: ${output}`), safeCb(cb))
|
||||
}
|
||||
return logMethods
|
||||
}, {
|
||||
setLevel (level) {
|
||||
if (level === 'silent') {
|
||||
return void logLevels.forEach(([x]) => logger[x] = logNoop)
|
||||
}
|
||||
process.on('beforeExit', () => {
|
||||
process.stderr.write(EOL)
|
||||
})
|
||||
if (level === 'info') {
|
||||
logger.verbose = logNoop
|
||||
}
|
||||
return logger
|
||||
}
|
||||
})
|
||||
|
||||
module.exports.logger = logger
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
const
|
||||
{ compose } = require('app-builder'),
|
||||
{ bundle } = require('./bundle'),
|
||||
{ NexeCompiler } = require('./compiler'),
|
||||
{ options } = require('./options'),
|
||||
{ cli } = require('./cli'),
|
||||
{ download } = require('./download'),
|
||||
{ artifacts } = require('./artifacts'),
|
||||
{ patches } = require('./patches'),
|
||||
{ EOL } = require('os'),
|
||||
{ coroutine, Promise } = require('bluebird'),
|
||||
{ logger } = require('./logger')
|
||||
|
||||
function wrap (fns) {
|
||||
return [].concat(...fns).map(fn => {
|
||||
return fn.constructor.name === 'GeneratorFunction'
|
||||
? coroutine(fn) : fn
|
||||
})
|
||||
}
|
||||
|
||||
function compile (compilerOptions, callback) {
|
||||
const compiler = new NexeCompiler(compilerOptions)
|
||||
|
||||
compiler.log.verbose('Compiler options:' +
|
||||
EOL + JSON.stringify(compiler.options, null, 4)
|
||||
)
|
||||
|
||||
const nexe = compose(wrap([
|
||||
bundle,
|
||||
cli,
|
||||
download,
|
||||
(nexeCompiler, next) => {
|
||||
return next().then(() => {
|
||||
return nexeCompiler.buildAsync()
|
||||
})
|
||||
},
|
||||
artifacts,
|
||||
patches,
|
||||
compiler.options.patches
|
||||
]))
|
||||
return Promise.resolve(nexe(compiler)).asCallback(callback)
|
||||
}
|
||||
|
||||
module.exports.options = options
|
||||
module.exports.compile = compile
|
||||
|
||||
if (require.main === module || process.__nexe) {
|
||||
compile(options).catch((e) => {
|
||||
logger.error(e.stack, () => process.exit(1))
|
||||
})
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
const
|
||||
parseArgv = require('minimist'),
|
||||
{ basename, extname, join } = require('path'),
|
||||
EOL = require('os').EOL,
|
||||
padRight = (str, l) => {
|
||||
while (str.length < l) {
|
||||
str += ' '
|
||||
}
|
||||
return str.substr(0, l)
|
||||
},
|
||||
defaults = {
|
||||
temp: process.env.NEXE_TEMP || join(process.cwd(), '.nexe'),
|
||||
version: process.version.slice(1),
|
||||
flags: [],
|
||||
configure: [],
|
||||
make: [],
|
||||
vcBuild: ['nosign', 'release'],
|
||||
quick: false,
|
||||
bundle: true,
|
||||
enableNodeCli: false,
|
||||
verbose: false,
|
||||
silent: false,
|
||||
padding: 2,
|
||||
patches: []
|
||||
},
|
||||
alias = {
|
||||
i: 'input',
|
||||
o: 'output',
|
||||
t: 'temp',
|
||||
n: 'name',
|
||||
v: 'version',
|
||||
p: 'python',
|
||||
f: 'flag',
|
||||
c: 'configure',
|
||||
m: 'make',
|
||||
vc: 'vcBuild',
|
||||
q: 'quick',
|
||||
s: 'snapshot',
|
||||
b: 'bundle',
|
||||
cli: 'enableNodeCli',
|
||||
h: 'help',
|
||||
l: 'loglevel'
|
||||
},
|
||||
argv = parseArgv(process.argv, { alias, default: defaults }),
|
||||
help = `
|
||||
nexe --help CLI OPTIONS
|
||||
|
||||
-i --input =./index.js -- application entry point
|
||||
-o --output =./nexe.exe -- path to output file
|
||||
-t --temp =./.nexe -- nexe temp directory (3Gb+) ~ NEXE_TEMP
|
||||
-n --name =nexe.js -- file name for error reporting at run time
|
||||
-v --version =${padRight(process.version.slice(1), 23)}-- node version
|
||||
-p --python =/path/to/python2 -- python executable
|
||||
-f --flag ="--expose-gc" -- *v8 flags to include during compilation
|
||||
-c --configure ="--with-dtrace" -- *pass arguments to the configure command
|
||||
-m --make ="--loglevel" -- *pass arguments to the make command
|
||||
-vc --vcBuild =x64 -- *pass arguments to vcbuild.bat
|
||||
-s --snapshot =/path/to/snapshot -- build with warmup snapshot
|
||||
-b --bundle -- attempt bundling application
|
||||
--ico -- file name for alternate icon file (windows)
|
||||
--rc-* -- populate rc file options (windows)
|
||||
--clean -- force download of sources
|
||||
--enableNodeCli -- enable node cli enforcement (blocks app cli)
|
||||
--sourceUrl -- pass an alternate source (node.tar.gz) url
|
||||
--silent -- disable logging
|
||||
--verbose -- set logging to verbose
|
||||
|
||||
|
||||
-* variable key name * option can be used more than once
|
||||
|
||||
TODO -q --quick =win32-x64-X.X.X -- use prebuilt binary (url, key or path)
|
||||
TODO --resource-* =/path/to/resource -- *embed file bytes within the binary
|
||||
`.trim()
|
||||
|
||||
function flattenFilter (...args) {
|
||||
return [].concat(...args).filter(x => x)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract keys such as { "rc-CompanyName": "Node.js" } to
|
||||
* { CompanyName: "Node.js" }
|
||||
* @param {*} match
|
||||
* @param {*} options
|
||||
*/
|
||||
function extractCliMap (match, options) {
|
||||
Object.keys(options).filter(x => match.test(x))
|
||||
.reduce((map, option) => {
|
||||
const key = option.split('-')[1]
|
||||
map = map || {}
|
||||
map[key] = options[option]
|
||||
delete options[option]
|
||||
return map
|
||||
}, null)
|
||||
}
|
||||
|
||||
function extractName (options) {
|
||||
if (typeof options.input === 'string') {
|
||||
return options.name
|
||||
|| basename(options.input).replace(extname(options.input), '')
|
||||
}
|
||||
const mainName = basename(require.resolve(process.cwd()))
|
||||
return options.name || mainName.replace(extname(mainName), '')
|
||||
}
|
||||
|
||||
function normalizeOptions (input) {
|
||||
if (input.__normalized) {
|
||||
return input
|
||||
}
|
||||
|
||||
if (argv.help || Boolean(argv._.find(x => x === 'version'))) {
|
||||
process.stderr.write(
|
||||
argv.help ? help : 'next' + EOL,
|
||||
() => process.exit(0)
|
||||
)
|
||||
}
|
||||
|
||||
const options = Object.assign({}, defaults, input)
|
||||
delete options._
|
||||
delete alias.rc
|
||||
options.loglevel = options.loglevel
|
||||
|| options.silent && 'silent'
|
||||
|| options.verbose && 'verbose' || 'info'
|
||||
options.name = extractName(options)
|
||||
options.flags = flattenFilter(options.flag, options.flags)
|
||||
options.make = flattenFilter(options.make)
|
||||
options.vcBuild = flattenFilter(options.vcBuild)
|
||||
options.rc = options.rc || extractCliMap(/^rc-.*/, options)
|
||||
options.resources = options.resources || extractCliMap(/^resource-.*/, options)
|
||||
Object.keys(alias).forEach(x => delete options[x])
|
||||
|
||||
options.__normalized = true
|
||||
return options
|
||||
}
|
||||
|
||||
module.exports.normalizeOptions = normalizeOptions
|
||||
module.exports.options = normalizeOptions(argv)
|
||||
@@ -0,0 +1,27 @@
|
||||
const Buffer = require('buffer').Buffer
|
||||
|
||||
function* content (compiler, next) {
|
||||
yield next()
|
||||
|
||||
const filename = 'lib/' + compiler.options.name + '.js',
|
||||
file = yield compiler.readFileAsync(filename),
|
||||
header = '/' + '*'.repeat(19) + 'nexe_',
|
||||
end = '_' + '*'.repeat(19) + '/',
|
||||
padding = Array(compiler.options.padding * 1000000).fill('*').join('')
|
||||
|
||||
if (!padding) {
|
||||
file.contents = compiler.input
|
||||
return
|
||||
}
|
||||
|
||||
file.contents = [
|
||||
compiler.input,
|
||||
'/',
|
||||
padding,
|
||||
'/'
|
||||
].join('')
|
||||
|
||||
file.contents = header + Buffer.byteLength(file.contents) + end + file.contents
|
||||
}
|
||||
|
||||
module.exports.content = content
|
||||
@@ -0,0 +1,17 @@
|
||||
function * disableNodeCli (compiler, next) {
|
||||
if (compiler.options.enableNodeCli) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const nodecc = yield compiler.readFileAsync('src/node.cc'),
|
||||
nodeccMarker = "argv[index][0] == '-'"
|
||||
|
||||
nodecc.contents = nodecc.contents.replace(
|
||||
nodeccMarker,
|
||||
nodeccMarker.replace('-', ']')
|
||||
)
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
module.exports.disableNodeCli = disableNodeCli
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports.flags = function* flags (compiler, next) {
|
||||
const nodeflags = compiler.options.flags
|
||||
if (!nodeflags.length) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const nodegyp = yield compiler.readFileAsync('node.gyp')
|
||||
|
||||
nodegyp.contents = nodegyp.contents.replace(
|
||||
"'node_v8_options%': ''",
|
||||
`'node_v8_options%': '${nodeflags.join(' ')}'`)
|
||||
|
||||
return next()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
module.exports.nodeGyp = function * nodeGyp ({ files, readFileAsync, download }, next) {
|
||||
yield next()
|
||||
|
||||
const nodegyp = yield readFileAsync('node.gyp'),
|
||||
nodeGypMarker = "'lib/fs.js',"
|
||||
|
||||
nodegyp.contents = nodegyp.contents
|
||||
.replace(nodeGypMarker, `
|
||||
${nodeGypMarker}
|
||||
${files
|
||||
.filter(x => x.filename.startsWith('lib'))
|
||||
.map(x => `'${x.filename}'`)
|
||||
.toString()},
|
||||
`.trim())
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
const
|
||||
{ readFile } = require('fs'),
|
||||
{ normalize } = require('path'),
|
||||
{ promisify } = require('bluebird')
|
||||
|
||||
const readFileAsync = promisify(readFile)
|
||||
|
||||
module.exports.ico = function * ico (compiler, next) {
|
||||
const iconFile = compiler.options.ico
|
||||
if (!iconFile) {
|
||||
return next()
|
||||
}
|
||||
const file = yield compiler.readFileAsync('src/res/node.ico')
|
||||
file.contents = yield readFileAsync(normalize(iconFile))
|
||||
return next()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
module.exports.patches = [
|
||||
require('./gyp').nodeGyp, //upstream, sets manifest
|
||||
require('./content').content, //upstream, sets main module content
|
||||
require('./third-party-main').main, //loads main module
|
||||
require('./disable-node-cli').disableNodeCli,
|
||||
require('./flags').flags,
|
||||
require('./ico').ico,
|
||||
require('./node-rc').nodeRc
|
||||
]
|
||||
@@ -0,0 +1,21 @@
|
||||
function* nodeRc (compiler, next) {
|
||||
const options = compiler.options.rc
|
||||
if (!options) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const file = yield compiler.readFileAsync('src/res/node.rc')
|
||||
|
||||
Object.keys(options).forEach((key) => {
|
||||
const value = options[key],
|
||||
isVar = /^[A-Z_]+$/.test(value)
|
||||
|
||||
value = isVar ? value : `"${value}"`
|
||||
file.contents.replace(new RegExp(`VALUE "${key}",*`), `VALUE "${key}", ${value}`)
|
||||
// TODO support keys that are not present?
|
||||
})
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
module.exports.nodeRc = nodeRc
|
||||
@@ -0,0 +1,15 @@
|
||||
module.exports.snapshot = function* snapshot (compiler, next) {
|
||||
const snapshotFile = compiler.options.snapshot
|
||||
|
||||
if (!snapshotFile) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const file = yield compiler.readFileAsync('configure')
|
||||
file.contents = file.contents
|
||||
.replace(
|
||||
'def configure_v8(o):',
|
||||
`def configure_v8(o):\n o['variables']['embed_script'] = '${snapshotFile}'\n o['variables']['warmup_script'] = '${snapshotFile}'`
|
||||
)
|
||||
return next()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
function * main (compiler, next) {
|
||||
const mainFile = yield compiler.readFileAsync('lib/_third_party_main.js')
|
||||
mainFile.contents = `
|
||||
Object.defineProperty(process, '__nexe', {
|
||||
value: true,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
require("${compiler.options.name}");
|
||||
`.trim()
|
||||
|
||||
if (compiler.options.empty === true) {
|
||||
compiler.options.resources.length = 0
|
||||
compiler.input = 'console.log(`nexe-${process.platform}-${process.arch}-${process.version}`)'
|
||||
return next()
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
module.exports.main = main
|
||||
Reference in New Issue
Block a user