neon-cli
Version:
Build and load native Rust/Neon modules.
371 lines (370 loc) • 13.4 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const neon_new_1 = __importDefault(require("./ops/neon_new"));
const neon_build_1 = __importDefault(require("./ops/neon_build"));
const neon_clean_1 = __importDefault(require("./ops/neon_clean"));
const style = __importStar(require("./style"));
const cliCommands = require("command-line-commands");
const cliArgs = require("command-line-args");
const cliUsage = require("command-line-usage");
const log_1 = __importDefault(require("./log"));
const log_2 = require("./log");
const JSON = __importStar(require("ts-typed-json"));
let metadata = JSON.loadSync(path_1.default.resolve(__dirname, "..", "package.json"));
function commandUsage(command) {
if (!spec[command]) {
let e = new Error();
e.command = command;
e.name = "INVALID_COMMAND";
throw e;
}
console.error(cliUsage(spec[command].usage));
}
function logIf(multiple, action, cwd, module) {
if (multiple) {
(0, log_1.default)(action + " Neon package at " + (path_1.default.relative(cwd, module) || "."));
}
}
function parseArgv(argv) {
let splitAt = argv.indexOf("--");
// No additional arguments provided
if (splitAt < 0) {
return {
cli: argv,
extra: [],
};
}
return {
cli: argv.slice(0, splitAt),
extra: argv.slice(splitAt + 1),
};
}
function parseModules(cwd, names, paths) {
let modules = names.length
? names.map((m) => paths ? path_1.default.resolve(cwd, m) : path_1.default.resolve(cwd, "node_modules", m))
: [cwd];
return {
modules,
multiple: modules.length > 1,
};
}
const spec = {
null: {
args: [
{ name: "version", alias: "v", type: Boolean },
{ name: "help", alias: "h", type: String, defaultValue: null },
],
usage: [
{
header: "Neon",
content: "Neon is a tool for building native Node.js modules with Rust.",
},
{
header: "Synopsis",
content: "$ neon [options] <command> -- [cargo options]",
},
{
header: "Command List",
content: [
{ name: "new", summary: "Create a new Neon project." },
{ name: "build", summary: "(Re)build a Neon project." },
{
name: "clean",
summary: "Remove build artifacts from a Neon project.",
},
{ name: "version", summary: "Display the Neon version." },
{ name: "help", summary: "Display help information about Neon." },
],
},
],
action: function (options, usage) {
if (options.version && options.help === undefined) {
spec.version.action.call(this, options);
}
else if (options.help !== undefined) {
commandUsage(options.help);
}
else {
console.error(usage);
}
},
},
help: {
args: [
{ name: "command", type: String, defaultOption: true },
{ name: "help", alias: "h", type: Boolean },
],
usage: [
{
header: "neon help",
content: "Get help about a Neon command",
},
{
header: "Synopsis",
content: "$ neon help [command]",
},
],
action: function (options) {
if (options && options.command) {
commandUsage(options.command);
}
else if (options && options.help) {
commandUsage("help");
}
else {
console.error(cliUsage(spec.null.usage));
}
},
},
new: {
args: [
{ name: "name", type: String, defaultOption: true },
{ name: "neon", alias: "n", type: String },
{ name: "features", alias: "f", type: String },
{ name: "no-default-features", type: Boolean },
{ name: "help", alias: "h", type: Boolean },
],
usage: [
{
header: "neon new",
content: "Create a new Neon project.",
},
{
header: "Synopsis",
content: "$ neon new [options] [@<scope>/]<name>",
},
{
header: "Options",
optionList: [
{
name: "neon",
alias: "n",
type: String,
description: "Specify a semver version of Neon or path to a local Neon repository.",
},
{
name: "features",
alias: "f",
type: String,
description: "Space-separated list of experimental Neon features to enable.",
},
{
name: "no-default-features",
type: Boolean,
description: "Do not activate the `default` Neon feature.",
},
],
},
],
action: function (options) {
if (options.help) {
commandUsage("new");
}
else if (!options.name) {
console.error(cliUsage(spec.new.usage));
}
else {
return (0, neon_new_1.default)(this.cwd, options.name, (options.neon || null), (options.features || null), !!options["no-default-features"]);
}
return;
},
},
build: {
args: [
{ name: "release", alias: "r", type: Boolean },
{ name: "path", alias: "p", type: Boolean },
{ name: "modules", type: String, multiple: true, defaultOption: true },
{ name: "help", alias: "h", type: Boolean },
],
usage: [
{
header: "neon build",
content: "(Re)build a Neon project.",
},
{
header: "Synopsis",
content: [
"$ neon build [options]",
"$ neon build [options] {underline module} ...",
],
},
{
header: "Options",
optionList: [
{
name: "release",
alias: "r",
type: Boolean,
description: "Release build.",
},
{
name: "path",
alias: "p",
type: Boolean,
description: "Specify modules by path instead of name.",
},
],
},
],
action: function (options) {
return __awaiter(this, void 0, void 0, function* () {
if (options.help) {
commandUsage("build");
return;
}
let extra = options.extra;
let { modules, multiple } = parseModules(this.cwd, (options.modules || []), !!options.path);
for (let module of modules) {
logIf(multiple, "building", this.cwd, module);
yield (0, neon_build_1.default)(module, this.toolchain, !!options.release, extra);
}
});
},
},
clean: {
args: [
{ name: "path", alias: "p", type: Boolean },
{ name: "modules", type: String, multiple: true, defaultOption: true },
{ name: "help", alias: "h", type: Boolean },
],
usage: [
{
header: "neon clean",
content: "Remove build artifacts from a Neon project.",
},
{
header: "Synopsis",
content: [
"$ neon clean [options]",
"$ neon clean [options] {underline module} ...",
],
},
{
header: "Options",
optionList: [
{
name: "path",
alias: "p",
type: Boolean,
description: "Specify modules by path instead of name.",
},
],
},
],
action: function (options) {
return __awaiter(this, void 0, void 0, function* () {
if (options.help) {
commandUsage("clean");
return;
}
let { modules, multiple } = parseModules(this.cwd, (options.modules || []), !!options.path);
for (let module of modules) {
logIf(multiple, "cleaning", this.cwd, module);
yield (0, neon_clean_1.default)(module);
}
});
},
},
version: {
args: [{ name: "help", alias: "h", type: Boolean }],
usage: [
{
header: "neon version",
content: "Display the Neon version.",
},
{
header: "Synopsis",
content: "$ neon version",
},
],
action: function (options) {
if (options.help) {
commandUsage("version");
return;
}
console.log(JSON.asObject(metadata).version);
},
},
};
class CLI {
constructor(argv, cwd) {
// Check for a toolchain argument in the style of Rust tools (e.g., `neon +nightly build`).
if (argv.length > 2 && argv[2].trim().startsWith("+")) {
this.toolchain = argv[2].substring(1).trim();
this.argv = argv.slice(3);
}
else {
this.toolchain = "default";
this.argv = argv.slice(2);
}
this.cwd = cwd;
}
exec() {
return __awaiter(this, void 0, void 0, function* () {
(0, log_2.setup)((msg) => {
console.log(style.info(msg));
});
let parsed;
try {
parsed = cliCommands([null, "help", "new", "build", "clean", "version"], this.argv);
}
catch (e) {
spec.help.action.call(this);
switch (e.name) {
case "INVALID_COMMAND":
console.error(style.error("No manual entry for `neon " + e.command + "`"));
break;
default:
console.error(style.error(e.message));
break;
}
process.exit(1);
}
try {
let { command, argv } = parsed;
let { cli, extra } = parseArgv(argv);
let options = Object.assign({ extra }, cliArgs(spec[command].args, { argv: cli }));
yield spec[command].action.call(this, options, cliUsage(spec[command].usage));
}
catch (e) {
console.error(style.error(e.message));
console.error();
console.error(e.stack);
throw e;
}
});
}
}
exports.default = CLI;
;