cli-engine
Version:
Generic CLI Framework
235 lines (191 loc) • 6.78 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Manager = exports.PluginPath = undefined;
var _cliEngineCommand = require('cli-engine-command');
var _legacy = require('./legacy');
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _cliUx = require('cli-ux');
var _hooks = require('../hooks');
var _help = require('cli-engine-command/lib/help');
var _help2 = _interopRequireDefault(_help);
var _pluginHelp = require('@oclif/plugin-help');
var _pluginHelp2 = _interopRequireDefault(_pluginHelp);
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const debug = require('debug')('cli-engine:plugins:manager');
function makeID(o) {
return o.id || [o.topic || o.name, o.command].filter(s => s).join(':');
}
function buildHelp(c, config) {
if (!c.id) c.id = makeID(c);
c.flags = (0, _legacy.convertFlagsFromV5)(c.flags);
if (c.buildHelp) return c.buildHelp(config);
const help = new _help2.default(config);
return help.command(c);
}
function buildHelpOCLIF(c, config) {
const help = new _pluginHelp2.default(config);
return help.command(c);
}
function buildHelpLine(c, config) {
if (!c.id) c.id = makeID(c);
c.flags = (0, _legacy.convertFlagsFromV5)(c.flags);
if (c.buildHelpLine) return c.buildHelpLine(config);
const help = new _help2.default(config);
return help.commandLine(c);
}
class PluginPath {
constructor(options) {
this.config = options.config;
this.path = options.path;
this.type = options.type;
this.tag = options.tag;
this.cli = new _cliUx.CLI({ mock: this.config.mock });
}
async convertToCached() {
let plugin = await this.require();
const getAliases = c => {
let aliases = c.aliases || [];
if (c.default) {
this.cli.warn(`default setting on ${c.topic} is deprecated`);
aliases.push(c.topic);
}
return aliases;
};
if (!plugin.commands) throw new Error('no commands found');
const commands = plugin.commands.map(c => ({
id: c.id || makeID(c),
topic: c.topic,
command: c.command,
description: c.description,
args: c.args,
variableArgs: c.variableArgs,
help: c.help,
usage: c.usage,
hidden: !!c.hidden,
aliases: getAliases(c),
buildHelpLine: buildHelpLine(c, this.config),
buildHelp: buildHelp(c, this.config),
flags: (0, _legacy.convertFlagsFromV5)(c.flags)
}));
const topics = (plugin.topics || []).map(t => ({
id: t.id || '',
topic: t.topic || '',
description: t.description,
hidden: !!t.hidden
}));
for (let command of commands) {
if (topics.find(t => t.id === command.topic)) continue;
let topic = {
id: command.topic,
topic: command.topic,
hidden: true
};
topics.push(topic);
}
const { name, version } = this.pjson();
return { name, path: this.path, version, commands, topics };
}
undefaultTopic(t) {
if (t.default) t = t.default;
// normalize v5 exported topic
if (!t.topic) t.topic = t.name || '';
if (!t.id) t.id = t.topic;
return t;
}
undefaultCommand(c) {
if (c.default && typeof c.default !== 'boolean') return c.default;
return c;
}
async require() {
if ((await _fsExtra2.default.pathExists(_path2.default.join(this.path, '.oclif.manifest.json'))) || (await _fsExtra2.default.pathExists(_path2.default.join(this.path, 'oclif.manifest.json')))) return this.requireOCLIF();
let required;
try {
required = require(this.path);
} catch (err) {
if (await this.repair(err)) return this.require();else throw err;
}
const hooks = new _hooks.Hooks({ config: this.config });
await hooks.run('plugins:parse', { module: required });
const exportedTopic = required.topic && this.undefaultTopic(required.topic);
const exportedTopics = required.topics && required.topics.map(t => this.undefaultTopic(t));
const topics = this.parsePjsonTopics().concat(exportedTopics || []).concat(exportedTopic || []);
const commands = required.commands && required.commands.map(t => this.undefaultCommand(t));
return { topics, commands };
}
parsePjsonTopics() {
// flow$ignore
const topics = (this.pjson()['cli-engine'] || {}).topics;
return this.transformPjsonTopics(topics);
}
transformPjsonTopics(topics, prefix) {
const flatten = require('lodash.flatten');
return flatten(this._transformPjsonTopics(topics));
}
_transformPjsonTopics(topics, prefix) {
if (!topics) return [];
return Object.keys(topics || {}).map(k => {
let t = topics[k];
let id = prefix ? `${prefix}:${k}` : k;
let topic = Object.assign(t, { id, topic: id });
if (t.subtopics) {
return [topic].concat(this._transformPjsonTopics(t.subtopics, topic.id));
}
return topic;
});
}
pjson() {
if (this.type === 'builtin') {
return { name: 'builtin', version: this.config.version };
}
return require(_path2.default.join(this.path, 'package.json'));
}
async repair(err) {
debug(err);
return false;
}
async requireOCLIF() {
let p = this.path;
let manifest;
try {
manifest = _fsExtra2.default.readJSONSync(_path2.default.join(p, '.oclif.manifest.json'));
} catch (e) {
manifest = _fsExtra2.default.readJSONSync(_path2.default.join(p, 'oclif.manifest.json'));
}
let Config = require('@oclif/config');
let config = await Config.load();
await config.loadPlugins(p, this.type, [{ root: p }], { must: true });
let topics = config.topics.map(t => ({ id: t.name, ...t }));
let commands = Object.entries(manifest.commands).map(([id, c]) => {
var _class, _temp;
return _temp = _class = class extends _cliEngineCommand.Command {
static get id() {
return id;
}
async run() {
return config.runCommand(id, process.argv.slice(3));
}
}, _class.topic = id.split(':').slice(0, -1).join(':'), _class.command = id.split(':').pop(), _class.description = c.description, _class.variableArgs = true, _class.buildHelp = conf => buildHelpOCLIF(c, conf), _temp;
});
return { topics, commands };
}
}
exports.PluginPath = PluginPath;
class Manager {
constructor({ config, cache }) {
this.config = config;
this.cache = cache;
this.cli = new _cliUx.CLI({ mock: config.mock });
}
async list() {
throw new Error('abstract method Manager.list');
}
async handleNodeVersionChange() {
// user and linked will override
}
}
exports.Manager = Manager;