mirror of
https://github.com/tiennm99/FBcount.git
synced 2026-05-14 14:58:04 +00:00
533 lines
13 KiB
JavaScript
533 lines
13 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault.js");
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.exec = exec;
|
|
|
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator.js"));
|
|
|
|
var _fsExtra = require("fs-extra");
|
|
|
|
var _log = require("./log.js");
|
|
|
|
var _pkgFetch = require("pkg-fetch");
|
|
|
|
var _assert = _interopRequireDefault(require("assert"));
|
|
|
|
var _help = _interopRequireDefault(require("./help"));
|
|
|
|
var _common = require("../prelude/common.js");
|
|
|
|
var _minimist = _interopRequireDefault(require("minimist"));
|
|
|
|
var _packer = _interopRequireDefault(require("./packer.js"));
|
|
|
|
var _path = _interopRequireDefault(require("path"));
|
|
|
|
var _chmod = require("./chmod.js");
|
|
|
|
var _producer = _interopRequireDefault(require("./producer.js"));
|
|
|
|
var _refiner = _interopRequireDefault(require("./refiner.js"));
|
|
|
|
var _fabricator = require("./fabricator.js");
|
|
|
|
var _package = require("../package.json");
|
|
|
|
var _walker = _interopRequireDefault(require("./walker.js"));
|
|
|
|
/* eslint-disable require-atomic-updates */
|
|
function isConfiguration(file) {
|
|
return (0, _common.isPackageJson)(file) || file.endsWith('.config.json');
|
|
} // http://www.openwall.com/lists/musl/2012/12/08/4
|
|
|
|
|
|
const {
|
|
hostArch,
|
|
hostPlatform,
|
|
isValidNodeRange,
|
|
knownArchs,
|
|
knownPlatforms,
|
|
toFancyArch,
|
|
toFancyPlatform
|
|
} = _pkgFetch.system;
|
|
const hostNodeRange = 'node' + process.version.match(/^v(\d+)/)[1];
|
|
|
|
function parseTargets(items) {
|
|
// [ 'node6-macos-x64', 'node6-linux-x64' ]
|
|
const targets = [];
|
|
|
|
for (const item of items) {
|
|
const target = {
|
|
nodeRange: hostNodeRange,
|
|
platform: hostPlatform,
|
|
arch: hostArch
|
|
};
|
|
|
|
if (item !== 'host') {
|
|
for (const token of item.split('-')) {
|
|
if (!token) continue;
|
|
|
|
if (isValidNodeRange(token)) {
|
|
target.nodeRange = token;
|
|
continue;
|
|
}
|
|
|
|
const p = toFancyPlatform(token);
|
|
|
|
if (knownPlatforms.indexOf(p) >= 0) {
|
|
target.platform = p;
|
|
continue;
|
|
}
|
|
|
|
const a = toFancyArch(token);
|
|
|
|
if (knownArchs.indexOf(a) >= 0) {
|
|
target.arch = a;
|
|
continue;
|
|
}
|
|
|
|
throw (0, _log.wasReported)(`Unknown token '${token}' in '${item}'`);
|
|
}
|
|
}
|
|
|
|
targets.push(target);
|
|
}
|
|
|
|
return targets;
|
|
}
|
|
|
|
function stringifyTarget(target) {
|
|
const {
|
|
nodeRange,
|
|
platform,
|
|
arch
|
|
} = target;
|
|
return `${nodeRange}-${platform}-${arch}`;
|
|
}
|
|
|
|
function differentParts(targets) {
|
|
const nodeRanges = {};
|
|
const platforms = {};
|
|
const archs = {};
|
|
|
|
for (const target of targets) {
|
|
nodeRanges[target.nodeRange] = true;
|
|
platforms[target.platform] = true;
|
|
archs[target.arch] = true;
|
|
}
|
|
|
|
const result = {};
|
|
|
|
if (Object.keys(nodeRanges).length > 1) {
|
|
result.nodeRange = true;
|
|
}
|
|
|
|
if (Object.keys(platforms).length > 1) {
|
|
result.platform = true;
|
|
}
|
|
|
|
if (Object.keys(archs).length > 1) {
|
|
result.arch = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function stringifyTargetForOutput(output, target, different) {
|
|
const a = [output];
|
|
if (different.nodeRange) a.push(target.nodeRange);
|
|
if (different.platform) a.push(target.platform);
|
|
if (different.arch) a.push(target.arch);
|
|
return a.join('-');
|
|
}
|
|
|
|
function fabricatorForTarget(target) {
|
|
const {
|
|
nodeRange,
|
|
arch
|
|
} = target;
|
|
return {
|
|
nodeRange,
|
|
platform: hostPlatform,
|
|
arch
|
|
};
|
|
}
|
|
|
|
const dryRunResults = {};
|
|
|
|
function needWithDryRun(_x) {
|
|
return _needWithDryRun.apply(this, arguments);
|
|
}
|
|
|
|
function _needWithDryRun() {
|
|
_needWithDryRun = (0, _asyncToGenerator2.default)(function* (target) {
|
|
const target2 = Object.assign({
|
|
dryRun: true
|
|
}, target);
|
|
const result = yield (0, _pkgFetch.need)(target2);
|
|
(0, _assert.default)(['exists', 'fetched', 'built'].indexOf(result) >= 0);
|
|
dryRunResults[result] = true;
|
|
});
|
|
return _needWithDryRun.apply(this, arguments);
|
|
}
|
|
|
|
const targetsCache = {};
|
|
|
|
function needViaCache(_x2) {
|
|
return _needViaCache.apply(this, arguments);
|
|
}
|
|
|
|
function _needViaCache() {
|
|
_needViaCache = (0, _asyncToGenerator2.default)(function* (target) {
|
|
const s = stringifyTarget(target);
|
|
let c = targetsCache[s];
|
|
if (c) return c;
|
|
c = yield (0, _pkgFetch.need)(target);
|
|
targetsCache[s] = c;
|
|
return c;
|
|
});
|
|
return _needViaCache.apply(this, arguments);
|
|
}
|
|
|
|
function exec(_x3) {
|
|
return _exec.apply(this, arguments);
|
|
}
|
|
|
|
function _exec() {
|
|
_exec = (0, _asyncToGenerator2.default)(function* (argv2) {
|
|
// eslint-disable-line complexity
|
|
const argv = (0, _minimist.default)(argv2, {
|
|
boolean: ['b', 'build', 'bytecode', 'd', 'debug', 'h', 'help', 'public', 'v', 'version'],
|
|
string: ['_', 'c', 'config', 'o', 'options', 'output', 'outdir', 'out-dir', 'out-path', 'public-packages', 't', 'target', 'targets'],
|
|
default: {
|
|
bytecode: true
|
|
}
|
|
});
|
|
|
|
if (argv.h || argv.help) {
|
|
(0, _help.default)();
|
|
return;
|
|
} // version
|
|
|
|
|
|
if (argv.v || argv.version) {
|
|
console.log(_package.version);
|
|
return;
|
|
}
|
|
|
|
_log.log.info(`pkg@${_package.version}`); // debug
|
|
|
|
|
|
_log.log.debugMode = argv.d || argv.debug; // forceBuild
|
|
|
|
const forceBuild = argv.b || argv.build; // _
|
|
|
|
if (!argv._.length) {
|
|
throw (0, _log.wasReported)('Entry file/directory is expected', ['Pass --help to see usage information']);
|
|
}
|
|
|
|
if (argv._.length > 1) {
|
|
throw (0, _log.wasReported)('Not more than one entry file/directory is expected');
|
|
} // input
|
|
|
|
|
|
let input = _path.default.resolve(argv._[0]);
|
|
|
|
if (!(yield (0, _fsExtra.exists)(input))) {
|
|
throw (0, _log.wasReported)('Input file does not exist', [input]);
|
|
}
|
|
|
|
if ((yield (0, _fsExtra.stat)(input)).isDirectory()) {
|
|
input = _path.default.join(input, 'package.json');
|
|
|
|
if (!(yield (0, _fsExtra.exists)(input))) {
|
|
throw (0, _log.wasReported)('Input file does not exist', [input]);
|
|
}
|
|
} // inputJson
|
|
|
|
|
|
let inputJson, inputJsonName;
|
|
|
|
if (isConfiguration(input)) {
|
|
inputJson = JSON.parse((yield (0, _fsExtra.readFile)(input)));
|
|
inputJsonName = inputJson.name;
|
|
|
|
if (inputJsonName) {
|
|
inputJsonName = inputJsonName.split('/').pop(); // @org/foo
|
|
}
|
|
} // inputBin
|
|
|
|
|
|
let inputBin;
|
|
|
|
if (inputJson) {
|
|
let bin = inputJson.bin;
|
|
|
|
if (bin) {
|
|
if (typeof bin === 'object') {
|
|
if (bin[inputJsonName]) {
|
|
bin = bin[inputJsonName];
|
|
} else {
|
|
bin = bin[Object.keys(bin)[0]]; // TODO multiple inputs to pkg them all?
|
|
}
|
|
}
|
|
|
|
inputBin = _path.default.resolve(_path.default.dirname(input), bin);
|
|
|
|
if (!(yield (0, _fsExtra.exists)(inputBin))) {
|
|
throw (0, _log.wasReported)('Bin file does not exist (taken from package.json ' + '\'bin\' property)', [inputBin]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (inputJson && !inputBin) {
|
|
throw (0, _log.wasReported)('Property \'bin\' does not exist in', [input]);
|
|
} // inputFin
|
|
|
|
|
|
const inputFin = inputBin || input; // config
|
|
|
|
let config = argv.c || argv.config;
|
|
|
|
if (inputJson && config) {
|
|
throw (0, _log.wasReported)('Specify either \'package.json\' or config. Not both');
|
|
} // configJson
|
|
|
|
|
|
let configJson;
|
|
|
|
if (config) {
|
|
config = _path.default.resolve(config);
|
|
|
|
if (!(yield (0, _fsExtra.exists)(config))) {
|
|
throw (0, _log.wasReported)('Config file does not exist', [config]);
|
|
}
|
|
|
|
configJson = require(config); // may be either json or js
|
|
|
|
if (!configJson.name && !configJson.files && !configJson.dependencies && !configJson.pkg) {
|
|
// package.json not detected
|
|
configJson = {
|
|
pkg: configJson
|
|
};
|
|
}
|
|
} // output, outputPath
|
|
|
|
|
|
let output = argv.o || argv.output;
|
|
const outputPath = argv['out-path'] || argv.outdir || argv['out-dir'];
|
|
let autoOutput = false;
|
|
|
|
if (output && outputPath) {
|
|
throw (0, _log.wasReported)('Specify either \'output\' or \'out-path\'. Not both');
|
|
}
|
|
|
|
if (!output) {
|
|
let name;
|
|
|
|
if (inputJson) {
|
|
name = inputJsonName;
|
|
|
|
if (!name) {
|
|
throw (0, _log.wasReported)('Property \'name\' does not exist in', [argv._[0]]);
|
|
}
|
|
} else if (configJson) {
|
|
name = configJson.name;
|
|
}
|
|
|
|
if (!name) {
|
|
name = _path.default.basename(inputFin);
|
|
}
|
|
|
|
autoOutput = true;
|
|
|
|
const ext = _path.default.extname(name);
|
|
|
|
output = name.slice(0, -ext.length || undefined);
|
|
output = _path.default.resolve(outputPath || '', output);
|
|
} else {
|
|
output = _path.default.resolve(output);
|
|
} // targets
|
|
|
|
|
|
const sTargets = argv.t || argv.target || argv.targets || '';
|
|
|
|
if (typeof sTargets !== 'string') {
|
|
throw (0, _log.wasReported)(`Something is wrong near ${JSON.stringify(sTargets)}`);
|
|
}
|
|
|
|
let targets = parseTargets(sTargets.split(',').filter(t => t));
|
|
|
|
if (!targets.length) {
|
|
let jsonTargets;
|
|
|
|
if (inputJson && inputJson.pkg) {
|
|
jsonTargets = inputJson.pkg.targets;
|
|
} else if (configJson && configJson.pkg) {
|
|
jsonTargets = configJson.pkg.targets;
|
|
}
|
|
|
|
if (jsonTargets) {
|
|
targets = parseTargets(jsonTargets);
|
|
}
|
|
}
|
|
|
|
if (!targets.length) {
|
|
if (!autoOutput) {
|
|
targets = parseTargets(['host']);
|
|
(0, _assert.default)(targets.length === 1);
|
|
} else {
|
|
targets = parseTargets(['linux', 'macos', 'win']);
|
|
}
|
|
|
|
_log.log.info('Targets not specified. Assuming:', `${targets.map(stringifyTarget).join(', ')}`);
|
|
} // differentParts
|
|
|
|
|
|
const different = differentParts(targets); // targets[].output
|
|
|
|
for (const target of targets) {
|
|
let file;
|
|
|
|
if (targets.length === 1) {
|
|
file = output;
|
|
} else {
|
|
file = stringifyTargetForOutput(output, target, different);
|
|
}
|
|
|
|
if (target.platform === 'win' && _path.default.extname(file) !== '.exe') file += '.exe';
|
|
target.output = file;
|
|
} // bakes
|
|
|
|
|
|
const bakes = (argv.options || '').split(',').filter(bake => bake).map(bake => '--' + bake); // check if input is going
|
|
// to be overwritten by output
|
|
|
|
for (const target of targets) {
|
|
if (target.output === inputFin) {
|
|
if (autoOutput) {
|
|
target.output += '-' + target.platform;
|
|
} else {
|
|
throw (0, _log.wasReported)('Refusing to overwrite input file', [inputFin]);
|
|
}
|
|
}
|
|
} // fetch targets
|
|
|
|
|
|
const {
|
|
bytecode
|
|
} = argv;
|
|
|
|
for (const target of targets) {
|
|
target.forceBuild = forceBuild;
|
|
yield needWithDryRun(target);
|
|
const f = target.fabricator = fabricatorForTarget(target);
|
|
f.forceBuild = forceBuild;
|
|
|
|
if (bytecode) {
|
|
yield needWithDryRun(f);
|
|
}
|
|
}
|
|
|
|
if (dryRunResults.fetched && !dryRunResults.built) {
|
|
_log.log.info('Fetching base Node.js binaries to PKG_CACHE_PATH');
|
|
}
|
|
|
|
for (const target of targets) {
|
|
target.binaryPath = yield needViaCache(target);
|
|
const f = target.fabricator;
|
|
|
|
if (bytecode) {
|
|
f.binaryPath = yield needViaCache(f);
|
|
|
|
if (f.platform !== 'win') {
|
|
yield (0, _chmod.plusx)(f.binaryPath);
|
|
}
|
|
}
|
|
} // marker
|
|
|
|
|
|
let marker;
|
|
|
|
if (configJson) {
|
|
marker = {
|
|
config: configJson,
|
|
base: _path.default.dirname(config),
|
|
configPath: config
|
|
};
|
|
} else {
|
|
marker = {
|
|
config: inputJson || {},
|
|
// not `inputBin` because only `input`
|
|
base: _path.default.dirname(input),
|
|
// is the place for `inputJson`
|
|
configPath: input
|
|
};
|
|
}
|
|
|
|
marker.toplevel = true; // public
|
|
|
|
const params = {};
|
|
|
|
if (argv.public) {
|
|
params.publicToplevel = true;
|
|
}
|
|
|
|
if (argv['public-packages']) {
|
|
params.publicPackages = argv['public-packages'].split(',');
|
|
|
|
if (params.publicPackages.indexOf('*') !== -1) {
|
|
params.publicPackages = ['*'];
|
|
}
|
|
} // records
|
|
|
|
|
|
let records;
|
|
let entrypoint = inputFin;
|
|
const addition = isConfiguration(input) ? input : undefined;
|
|
const walkResult = yield (0, _walker.default)(marker, entrypoint, addition, params);
|
|
entrypoint = walkResult.entrypoint;
|
|
records = walkResult.records;
|
|
const refineResult = (0, _refiner.default)(records, entrypoint);
|
|
entrypoint = refineResult.entrypoint;
|
|
records = refineResult.records;
|
|
const backpack = (0, _packer.default)({
|
|
records,
|
|
entrypoint,
|
|
bytecode
|
|
});
|
|
|
|
_log.log.debug('Targets:', JSON.stringify(targets, null, 2));
|
|
|
|
for (const target of targets) {
|
|
if (yield (0, _fsExtra.exists)(target.output)) {
|
|
if ((yield (0, _fsExtra.stat)(target.output)).isFile()) {
|
|
yield (0, _fsExtra.remove)(target.output);
|
|
} else {
|
|
throw (0, _log.wasReported)('Refusing to overwrite non-file output', [target.output]);
|
|
}
|
|
} else {
|
|
yield (0, _fsExtra.mkdirp)(_path.default.dirname(target.output));
|
|
}
|
|
|
|
const slash = target.platform === 'win' ? '\\' : '/';
|
|
yield (0, _producer.default)({
|
|
backpack,
|
|
bakes,
|
|
slash,
|
|
target
|
|
});
|
|
|
|
if (target.platform !== 'win') {
|
|
yield (0, _chmod.plusx)(target.output);
|
|
}
|
|
}
|
|
|
|
(0, _fabricator.shutdown)();
|
|
});
|
|
return _exec.apply(this, arguments);
|
|
} |