cli/src/cli.ts

343 lines
9.7 KiB
TypeScript

import { logger } from '@squeebot/core/lib/core';
import { IRepository } from '@squeebot/core/lib/plugin/repository';
import { ReadLine } from 'readline';
import { Squeebot } from './core';
export class SqueebotCLI {
constructor(private bot: Squeebot) {}
private async checkUpdate(repo: IRepository): Promise<void> {
const updatable = await this.bot.repositoryManager.checkForUpdates(repo);
if (updatable.length) {
logger.log('[%s] The following plugins can be updated:', repo.name,
updatable.map((u) => u.name).join(', '));
} else {
logger.log('[%s] All plugins are up-to-date!', repo.name);
}
}
private async repositoryCommand(...args: any[]): Promise<void> {
const help = 'repository add <url> | update <name> | remove <name>';
if (!args[0] || args[0] === 'help') {
logger.log(help);
return;
}
switch (args[0]) {
case 'a':
case 'i':
case 'add':
case 'install':
if (!args[1]) {
logger.error('URL is required');
return;
}
for (const urlp of args.slice(1)) {
const repo = await this.bot.repositoryManager.installRepository(urlp);
logger.log('Installed repository %s!', repo.name);
}
break;
case 'r':
case 'rem':
case 'remove':
case 'uninstall':
if (!args[1]) {
logger.error('Name is required');
return;
}
for (const namep of args.slice(1)) {
await this.bot.repositoryManager.uninstallRepository(namep);
logger.log('Installed repository %s.', namep);
}
break;
case 'u':
case 'upd':
case 'update':
if (!args[1]) {
const repos = this.bot.repositoryManager.getAll();
for (const repo of repos) {
await this.checkUpdate(repo);
}
return;
}
for (const namep of args.slice(1)) {
const repo = this.bot.repositoryManager.getRepoByName(namep);
if (!repo) {
logger.error('No such repository "%s" found.', namep);
return;
}
await this.checkUpdate(repo);
}
break;
default:
logger.log(help);
}
}
private async pluginCommand(...args: any[]): Promise<void> {
const help = 'plugin install | update | uninstall | enable | disable | start | stop | list | running [<name>]';
if (!args[0] || args[0] === 'help' || (!args[1] && args[0] !== 'list' && args[0] !== 'running')) {
logger.log(help);
return;
}
switch (args[0]) {
case 'i':
case 'u':
case 'install':
case 'update':
for (const name of args.slice(1)) {
const mf = await this.bot.repositoryManager.installPlugin(name);
logger.log('Installed plugin %s version %s!', mf.name, mf.version);
}
break;
case 'uninst':
case 'remove':
case 'uninstall':
for (const name of args.slice(1)) {
await this.bot.repositoryManager.uninstallPlugin(name);
logger.log('Uninstalled plugin %s.', name);
}
break;
case 'list':
logger.log('Installed plugins:',
this.bot.pluginManager.availablePlugins.map((mf) => mf.name).join(', '));
break;
case 'running':
logger.log('Currently running plugins:',
this.bot.pluginManager.getLoaded().map((p) => p.manifest.name).join(', '));
break;
case 's':
case 'run':
case 'load':
case 'start':
for (const name of args.slice(1)) {
const plugin = this.bot.pluginManager.getAvailableByName(name);
if (!plugin) {
logger.error('"%s" is not available. Maybe try installing it? plugin install', name, name);
return;
}
await this.bot.pluginManager.load(plugin);
logger.log('Started plugin "%s" successfully.', name);
}
break;
case 'stop':
case 'kill':
for (const name of args.slice(1)) {
if (!this.bot.pluginManager.getAvailableByName(name)) {
logger.error('No such plugin is available.');
return;
}
logger.log('Stopping plugin', name);
this.bot.stream.emitTo(name, 'pluginUnload', name);
}
break;
case 'enable':
for (const name of args.slice(1)) {
if (!this.bot.pluginManager.getAvailableByName(name)) {
logger.error('No such plugin "%s" is available.', name);
return;
}
logger.log('Enabling plugin', name);
if (!this.bot.config.config.enabled) {
this.bot.config.config.enabled = [name];
return;
}
if (this.bot.config.config.enabled.indexOf(name) === -1) {
this.bot.config.config.enabled.push(name);
}
}
await this.bot.config.save();
break;
case 'disable':
for (const name of args.slice(1)) {
if (!this.bot.pluginManager.getAvailableByName(name)) {
logger.error('No such plugin "%s" is available.', name);
return;
}
logger.log('Disabling plugin', name);
if (!this.bot.config.config.enabled) {
return;
}
const indx = this.bot.config.config.enabled.indexOf(name);
if (indx > -1) {
this.bot.config.config.enabled.splice(indx, 1);
}
}
await this.bot.config.save();
break;
default:
logger.log(help);
}
}
private async channelCommand(...args: any[]): Promise<void> {
const help = 'channel new | del | list | addplugin | delplugin [<name>] [<plugin>]';
if (!args[0] || args[0] === 'help' || (!args[1] && args[0] !== 'list')) {
logger.log(help);
return;
}
switch (args[0]) {
case 'new':
if (this.bot.channelManager.getChannelByName(args[1])) {
logger.error('A channel by that name already exists!');
break;
}
this.bot.channelManager.addChannel({
name: args[1],
plugins: [],
enabled: true,
});
logger.log('Channel added!');
break;
case 'del':
case 'delete':
case 'remove':
for (const name of args.slice(1)) {
const chan = this.bot.channelManager.getChannelByName(name);
if (!chan) {
logger.error('No such channel "%s" exists!', name);
return;
}
this.bot.channelManager.removeChannel(chan);
logger.log('Channel "%s" removed!', name);
}
break;
case 'addp':
case 'addplugin':
const chan1 = this.bot.channelManager.getChannelByName(args[1]);
if (!chan1) {
logger.error('No such channel exists!');
return;
}
if (!args[2]) {
logger.error('A plugin name is required.');
return;
}
for (const name of args.slice(2)) {
if (chan1.plugins.indexOf(name) === -1) {
chan1.plugins.push(name);
}
logger.log('Plugin "%s" added to channel!', name);
}
break;
case 'list':
logger.log('Channels:\n', this.bot.channelManager.getAll().map((chan) => {
return ` => ${chan.name}: ${chan.plugins.join(', ')} (${chan.enabled ? 'enabled' : 'disabled'})`;
}).join('\n'));
break;
case 'remp':
case 'delp':
case 'remplugin':
case 'delplugin':
const chan2 = this.bot.channelManager.getChannelByName(args[1]);
if (!chan2) {
logger.error('No such channel exists!');
return;
}
if (!args[2]) {
logger.error('A plugin name is required.');
return;
}
for (const name of args.slice(2)) {
const idx = chan2.plugins.indexOf(args[2]);
if (idx !== -1) {
chan2.plugins.splice(idx, 1);
}
logger.log('Plugin "%s" added to channel!', name);
}
break;
case 'enable':
for (const name of args.slice(1)) {
const chan = this.bot.channelManager.getChannelByName(name);
if (!chan) {
logger.error('No such channel "%s" exists!', name);
return;
}
chan.enabled = true;
logger.log('Channel "%s" enabled!', name);
}
break;
case 'disable':
for (const name of args.slice(1)) {
const chan = this.bot.channelManager.getChannelByName(name);
if (!chan) {
logger.error('No such channel "%s" exists!', name);
return;
}
chan.enabled = false;
logger.log('Channel "%s" disabled!', name);
}
break;
}
this.bot.config.config.channels = this.bot.channelManager.getAll();
await this.bot.config.save();
}
public attach(rl: ReadLine): void {
rl.on('line', (line: string) => {
const split = line.split(' ');
if (!split[0]) {
return;
}
switch (split[0]) {
case 'r':
case 'repo':
case 'repository':
this.repositoryCommand(...split.slice(1)).catch(
e => logger.error(e.message));
break;
case 'p':
case 'pl':
case 'plugin':
this.pluginCommand(...split.slice(1)).catch(
e => logger.error(e.message));
break;
case 'c':
case 'chan':
case 'channel':
this.channelCommand(...split.slice(1)).catch(
e => logger.error(e.message));
break;
case 'stop':
case 'exit':
case 'quit':
case 'shutdown':
this.bot.shutdown();
break;
}
});
}
}