europa-build
Version:
Tool for generating and maintaining Europa plugins and presets
171 lines • 7.87 kB
JavaScript
;
/*
* Copyright (C) 2022 neocotic
*
* 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 __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cli = void 0;
const commander_1 = require("commander");
const PackageInfo_1 = require("./PackageInfo");
const Logger_1 = require("./logger/Logger");
const ScriptRunner_1 = require("./script/ScriptRunner");
const TemplateManager_1 = require("./template/TemplateManager");
const TemplateProviderType_1 = require("./template/provider/TemplateProviderType");
const _cwd = Symbol();
const _command = Symbol();
const _logger = Symbol();
const _onError = Symbol();
const _outputStream = Symbol();
/**
* A command-line interface for generating and maintaining Europa plugins and presets.
*/
class Cli {
/**
* Creates an instance of {@link Cli} using the `options` provided.
*
* @param [options] - The options to be used.
*/
constructor(options = {}) {
var _a;
this[_cwd] = (_a = options.cwd) !== null && _a !== void 0 ? _a : process.cwd();
this[_logger] = (0, Logger_1.createLogger)({ outputStream: options.outputStream }).child({ name: 'Cli' });
this[_onError] = options.onError;
this[_outputStream] = options.outputStream;
}
/**
* Parses the specified `args` and executes the relevant sub-command.
*
* @param [args] - The command-line arguments to be parsed. Defaults to those passed to the Node.js process.
*/
async parse(args = process.argv) {
const command = await this.getCommand();
command.parse(args);
}
activateDebugLogging() {
this[_logger].transports[0].level = 'debug';
}
async createCommand() {
const outputStream = this[_outputStream];
const parentLogger = this[_logger];
const packageInfo = await PackageInfo_1.PackageInfo.getSingleton();
const scriptRunner = new ScriptRunner_1.ScriptRunner({ outputStream, parentLogger });
const templateManager = new TemplateManager_1.TemplateManager({ outputStream, parentLogger });
return commander_1.program
.version(packageInfo.json.version)
.addCommand(this.createGenerateSubCommand(templateManager, 'generate-plugin', 'generate a plugin package', TemplateProviderType_1.TemplateProviderType.Plugin))
.addCommand(this.createGenerateSubCommand(templateManager, 'generate-preset', 'generate a preset package', TemplateProviderType_1.TemplateProviderType.Preset))
.addCommand(this.createRunScriptSubCommand(scriptRunner));
}
static createDebugOption() {
return new commander_1.Option('-d, --debug', 'enable debug logging');
}
createGenerateSubCommand(templateManager, name, description, type) {
const templateProviders = templateManager.getProvidersForType(type);
const subCommand = new commander_1.Command(name)
.description(description)
.usage('[options] <template>')
.addArgument(new commander_1.Argument('<template>', 'name of the template to generate').choices(templateProviders.map((provider) => provider.getName())))
.addOption(Cli.createDebugOption());
templateProviders.forEach((provider) => {
subCommand.addCommand(this.createTemplateSubCommand(name, provider));
});
return subCommand;
}
createRunScriptSubCommand(scriptRunner) {
return new commander_1.Command('run-script')
.description('run the named script')
.addArgument(new commander_1.Argument('<name>', 'name of the script to run').choices(scriptRunner.getScriptNames()))
.addOption(Cli.createDebugOption())
.action(async (scriptName, { debug }) => {
var _a;
if (debug) {
this.activateDebugLogging();
}
try {
await scriptRunner.run(scriptName, { cwd: this[_cwd] });
}
catch (e) {
this[_logger].error('Failed to execute "run-script" command');
this[_logger].error(e);
(_a = this[_onError]) === null || _a === void 0 ? void 0 : _a.call(this, e);
}
});
}
static createTemplateOption(cliOption) {
let flags = `--${cliOption.longName}`;
if (cliOption.shortName) {
flags = `-${cliOption.shortName}, ${flags}`;
}
if (cliOption.arg) {
flags += ` ${cliOption.arg}`;
}
const option = new commander_1.Option(flags, cliOption.description);
if (typeof cliOption.defaultValue !== 'undefined') {
option.default(cliOption.defaultValue, cliOption.defaultValueDescription);
}
return option;
}
createTemplateSubCommand(rootCommand, templateProvider) {
const subCommand = new commander_1.Command(templateProvider.getName())
.addArgument(new commander_1.Argument('[target]', 'path of the template output').default(process.cwd(), 'current working directory'))
.addOption(Cli.createDebugOption());
templateProvider.createCliOptions().map(Cli.createTemplateOption).forEach(subCommand.addOption.bind(subCommand));
subCommand.action(async (targetDirectory, _a) => {
var _b;
var { debug } = _a, options = __rest(_a, ["debug"]);
if (debug) {
this.activateDebugLogging();
}
try {
const context = await templateProvider.createContext(options);
const generator = templateProvider.createGenerator();
await generator.generate(context, targetDirectory);
}
catch (e) {
this[_logger].error(`Failed to execute "${rootCommand} ${templateProvider.getName()}" command`);
this[_logger].error(e);
(_b = this[_onError]) === null || _b === void 0 ? void 0 : _b.call(this, e);
}
});
return subCommand;
}
async getCommand() {
const cachedCommand = this[_command];
if (cachedCommand) {
return cachedCommand;
}
const command = await this.createCommand();
this[_command] = command;
return command;
}
}
exports.Cli = Cli;
//# sourceMappingURL=Cli.js.map