UNPKG

neon-cli

Version:

Build and load native Rust/Neon modules.

371 lines (370 loc) 13.4 kB
"use strict"; 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;