Interactive mode, cli changes

This commit is contained in:
Evert Prants 2020-11-28 21:08:56 +02:00
parent 2ed151ac51
commit 7633dda7a5
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
6 changed files with 504 additions and 20 deletions

146
package-lock.json generated
View File

@ -33,8 +33,11 @@
"@squeebot/core": { "@squeebot/core": {
"version": "file:../core", "version": "file:../core",
"requires": { "requires": {
"@types/semver": "^7.3.4",
"dateformat": "^4.0.0", "dateformat": "^4.0.0",
"fs-extra": "^9.0.1" "fs-extra": "^9.0.1",
"semver": "^7.3.2",
"tar": "^6.0.5"
}, },
"dependencies": { "dependencies": {
"@babel/code-frame": { "@babel/code-frame": {
@ -73,6 +76,11 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.9.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.9.tgz",
"integrity": "sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw==" "integrity": "sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw=="
}, },
"@types/semver": {
"version": "7.3.4",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz",
"integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ=="
},
"ansi-styles": { "ansi-styles": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@ -123,6 +131,11 @@
"supports-color": "^5.3.0" "supports-color": "^5.3.0"
} }
}, },
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"color-convert": { "color-convert": {
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -177,6 +190,14 @@
"universalify": "^1.0.0" "universalify": "^1.0.0"
} }
}, },
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"fs.realpath": { "fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -283,6 +304,23 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
}, },
"minipass": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"requires": {
"yallist": "^4.0.0"
}
},
"minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
}
},
"mkdirp": { "mkdirp": {
"version": "0.5.5", "version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
@ -319,9 +357,9 @@
} }
}, },
"semver": { "semver": {
"version": "5.7.1", "version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
}, },
"sprintf-js": { "sprintf-js": {
"version": "1.0.3", "version": "1.0.3",
@ -336,6 +374,26 @@
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
}, },
"tar": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"dependencies": {
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
}
}
},
"tslib": { "tslib": {
"version": "1.14.1", "version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@ -356,7 +414,6 @@
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"mkdirp": "^0.5.3", "mkdirp": "^0.5.3",
"resolve": "^1.3.2", "resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.13.0", "tslib": "^1.13.0",
"tsutils": "^2.29.0" "tsutils": "^2.29.0"
} }
@ -383,6 +440,11 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
} }
} }
}, },
@ -395,12 +457,31 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/minipass": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@types/minipass/-/minipass-2.2.0.tgz",
"integrity": "sha512-wuzZksN4w4kyfoOv/dlpov4NOunwutLA/q7uc00xU02ZyUY+aoM5PWIXEKBMnm0NHd4a+N71BMjq+x7+2Af1fg==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": { "@types/node": {
"version": "14.14.8", "version": "14.14.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz",
"integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==",
"dev": true "dev": true
}, },
"@types/tar": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/tar/-/tar-4.0.4.tgz",
"integrity": "sha512-0Xv+xcmkTsOZdIF4yCnd7RkOOyfyqPaqJ7RZFKnwdxfDbkN3eAAE9sHl8zJFqBz4VhxolW9EErbjR1oyH7jK2A==",
"dev": true,
"requires": {
"@types/minipass": "*",
"@types/node": "*"
}
},
"@types/yargs": { "@types/yargs": {
"version": "15.0.10", "version": "15.0.10",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz",
@ -477,6 +558,11 @@
"supports-color": "^5.3.0" "supports-color": "^5.3.0"
} }
}, },
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"cliui": { "cliui": {
"version": "7.0.4", "version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@ -553,6 +639,14 @@
"universalify": "^1.0.0" "universalify": "^1.0.0"
} }
}, },
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"fs.realpath": { "fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -681,6 +775,23 @@
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true "dev": true
}, },
"minipass": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"requires": {
"yallist": "^4.0.0"
}
},
"minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
}
},
"mkdirp": { "mkdirp": {
"version": "0.5.5", "version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
@ -770,6 +881,26 @@
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
}, },
"tar": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"dependencies": {
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
}
}
},
"tslib": { "tslib": {
"version": "1.14.1", "version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@ -861,6 +992,11 @@
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
}, },
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"yargs": { "yargs": {
"version": "16.1.1", "version": "16.1.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz",

View File

@ -22,6 +22,7 @@
"devDependencies": { "devDependencies": {
"@types/fs-extra": "^9.0.4", "@types/fs-extra": "^9.0.4",
"@types/node": "^14.14.8", "@types/node": "^14.14.8",
"@types/tar": "^4.0.4",
"@types/yargs": "^15.0.10", "@types/yargs": "^15.0.10",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"typescript": "^4.0.5" "typescript": "^4.0.5"
@ -30,6 +31,7 @@
"@squeebot/core": "file:../core", "@squeebot/core": "file:../core",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"node-watch": "^0.7.0", "node-watch": "^0.7.0",
"tar": "^6.0.5",
"yargs": "^16.1.1" "yargs": "^16.1.1"
} }
} }

314
src/cli.ts Normal file
View File

@ -0,0 +1,314 @@
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 checkUpdate(repo: IRepository): void {
this.bot.repositoryManager.checkForUpdates(repo).then((updatable) => {
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);
}
}, (e) => logger.error(e.message));
}
private repositoryCommand(...args: any[]): 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;
}
this.bot.repositoryManager.installRepository(args[1]).then((repo) => {
logger.log('Installed repository %s!', repo.name);
}, (e) => logger.error(e.message));
break;
case 'r':
case 'rem':
case 'remove':
case 'uninstall':
if (!args[1]) {
logger.error('Name is required');
return;
}
this.bot.repositoryManager.uninstallRepository(args[1]).then(() => {
logger.log('Installed repository %s.', args[1]);
}, (e) => logger.error(e.message));
break;
case 'u':
case 'upd':
case 'update':
if (!args[1]) {
const repos = this.bot.repositoryManager.getAll();
for (const repo of repos) {
this.checkUpdate(repo);
}
return;
}
const repo = this.bot.repositoryManager.getRepoByName(args[1]);
if (!repo) {
logger.error('No such repository found.');
return;
}
this.checkUpdate(repo);
break;
default:
logger.log(help);
}
}
private pluginCommand(...args: any[]): 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':
this.bot.repositoryManager.installPlugin(args[1]).then((mf) => {
logger.log('Installed plugin %s version %s!', mf.name, mf.version);
}, (e) => console.error(e.message));
break;
case 'uninst':
case 'remove':
case 'uninstall':
this.bot.repositoryManager.uninstallPlugin(args[1]).then(() => {
logger.log('Uninstalled plugin %s.', args[1]);
}, (e) => console.error(e.message));
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':
const plugin = this.bot.pluginManager.getAvailableByName(args[1]);
if (!plugin) {
logger.error('No such plugin is available. Maybe try installing it? plugin install', args[1]);
return;
}
this.bot.pluginManager.load(plugin).then((p) => {
logger.log('Started plugin "%s" successfully.', args[1]);
}, (e) => logger.error(e.stack));
break;
case 'stop':
case 'kill':
if (!this.bot.pluginManager.getAvailableByName(args[1])) {
logger.error('No such plugin is available.');
return;
}
logger.log('Stopping plugin', args[1]);
this.bot.stream.emitTo(args[1], 'pluginUnload', args[1]);
break;
case 'enable':
if (!this.bot.pluginManager.getAvailableByName(args[1])) {
logger.error('No such plugin is available.');
return;
}
logger.log('Enabling plugin', args[1]);
if (!this.bot.config.config.enabled) {
this.bot.config.config.enabled = [args[1]];
return;
}
if (this.bot.config.config.enabled.indexOf(args[1]) === -1) {
this.bot.config.config.enabled.push(args[1]);
}
this.bot.config.save();
break;
case 'disable':
if (!this.bot.pluginManager.getAvailableByName(args[1])) {
logger.error('No such plugin is available.');
return;
}
logger.log('Disabling plugin', args[1]);
if (!this.bot.config.config.enabled) {
return;
}
const indx = this.bot.config.config.enabled.indexOf(args[1]);
if (indx > -1) {
this.bot.config.config.enabled.splice(indx, 1);
}
this.bot.config.save();
break;
default:
logger.log(help);
}
}
private channelCommand(...args: any[]): void {
const help = 'channel new | del | 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':
const chan = this.bot.channelManager.getChannelByName(args[1]);
if (!chan) {
logger.error('No such channel exists!');
return;
}
this.bot.channelManager.removeChannel(chan);
logger.log('Channel removed!');
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;
}
if (chan1.plugins.indexOf(args[2]) !== -1) {
chan1.plugins.push(args[2]);
}
logger.log('Plugin added to channel!');
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;
}
const idx = chan2.plugins.indexOf(args[2]);
if (idx !== -1) {
chan2.plugins.splice(idx, 1);
}
logger.log('Plugin added to channel!');
break;
case 'enable':
const chan3 = this.bot.channelManager.getChannelByName(args[1]);
if (!chan3) {
logger.error('No such channel exists!');
return;
}
chan3.enabled = true;
logger.log('Channel enabled!');
break;
case 'disable':
const chan4 = this.bot.channelManager.getChannelByName(args[1]);
if (!chan4) {
logger.error('No such channel exists!');
return;
}
chan4.enabled = false;
logger.log('Channel disabled!');
break;
}
this.bot.config.config.channels = this.bot.channelManager.getAll();
this.bot.config.save();
}
public attach(rl: ReadLine) {
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));
break;
case 'p':
case 'pl':
case 'plugin':
this.pluginCommand(...split.slice(1));
break;
case 'c':
case 'chan':
case 'channel':
this.channelCommand(...split.slice(1));
break;
case 'stop':
case 'exit':
case 'quit':
case 'shutdown':
this.bot.shutdown();
break;
}
})
}
}

View File

@ -4,6 +4,8 @@ import { ChannelManager } from '@squeebot/core/lib/channel';
import { PluginManager, PluginMetaLoader } from '@squeebot/core/lib/plugin'; import { PluginManager, PluginMetaLoader } from '@squeebot/core/lib/plugin';
import { RepositoryManager } from '@squeebot/core/lib/plugin/repository';
import { NPMExecutor } from '@squeebot/core/lib/npm'; import { NPMExecutor } from '@squeebot/core/lib/npm';
import { Configuration, IEnvironment } from '@squeebot/core/lib/types'; import { Configuration, IEnvironment } from '@squeebot/core/lib/types';
@ -24,19 +26,24 @@ export class Squeebot {
public stream: ScopedEventEmitter = new ScopedEventEmitter(); public stream: ScopedEventEmitter = new ScopedEventEmitter();
private pluginManager: PluginManager = new PluginManager( public pluginManager: PluginManager = new PluginManager(
[], [],
this.stream, this.stream,
this.environment, this.environment,
this.npm); this.npm);
private channelManager: ChannelManager = new ChannelManager(this.stream); public repositoryManager: RepositoryManager = new RepositoryManager(
this.environment,
this.pluginManager,
);
private pluginLoader: PluginMetaLoader = new PluginMetaLoader( public channelManager: ChannelManager = new ChannelManager(this.stream);
public pluginLoader: PluginMetaLoader = new PluginMetaLoader(
this.environment, this.environment,
); );
private config: Configuration = new Configuration( public config: Configuration = new Configuration(
this.environment, this.environment,
path.join(this.environment.configurationPath, 'squeebot.json'), path.join(this.environment.configurationPath, 'squeebot.json'),
defaultConfiguration, defaultConfiguration,
@ -44,7 +51,7 @@ export class Squeebot {
private shuttingDown = false; private shuttingDown = false;
constructor(private environment: IEnvironment) {} constructor(public environment: IEnvironment) {}
public async initialize(autostart: boolean = true): Promise<void> { public async initialize(autostart: boolean = true): Promise<void> {
// Load configuration // Load configuration
@ -59,11 +66,12 @@ export class Squeebot {
// Give manager all loaded manifests // Give manager all loaded manifests
this.pluginManager.addAvailable(plugins); this.pluginManager.addAvailable(plugins);
// Load repositories
await this.repositoryManager.loadFromFiles();
// Start channels // Start channels
this.channelManager.initialize(this.config.get('channels')); this.channelManager.initialize(this.config.get('channels'));
logger.debug(this.channelManager);
if (autostart) { if (autostart) {
// Start enabled plugins // Start enabled plugins
await this.startPlugins(); await this.startPlugins();

View File

@ -2,8 +2,8 @@ import child_process from 'child_process';
import fs from 'fs-extra'; import fs from 'fs-extra';
import watch from 'node-watch'; import watch from 'node-watch';
import path from 'path'; import path from 'path';
import readline from 'readline';
import yargs from 'yargs'; import yargs from 'yargs';
import tar from 'tar';
import { logger } from '@squeebot/core/lib/core'; import { logger } from '@squeebot/core/lib/core';
import { NPMExecutor } from '@squeebot/core/lib/npm'; import { NPMExecutor } from '@squeebot/core/lib/npm';
@ -168,7 +168,7 @@ async function deploy(
console.log('Copying plugins to', pluginsPath); console.log('Copying plugins to', pluginsPath);
const listAllFiles = await fs.readdir(outDir); const listAllFiles = await fs.readdir(outDir);
for (const f of listAllFiles) { for (const f of listAllFiles) {
if (f === 'repository') { if (f === 'repository' || f.indexOf('.tgz') !== -1) {
continue; continue;
} }
const dst = path.join(pluginsPath, f); const dst = path.join(pluginsPath, f);
@ -220,8 +220,6 @@ async function buildRepository(
const loader = new PluginMetaLoader(env); const loader = new PluginMetaLoader(env);
const plugins = await loader.loadAll(false); const plugins = await loader.loadAll(false);
const savedList: any[] = []; const savedList: any[] = [];
let indexFileContents = 'name=' + meta.name + '\n';
indexFileContents += 'created=' + Math.floor(Date.now() / 1000) + '\n';
console.log('Found the following plugins:', plugins.map((plugin) => { console.log('Found the following plugins:', plugins.map((plugin) => {
return `${plugin.name}@${plugin.version}`; return `${plugin.name}@${plugin.version}`;
@ -232,7 +230,6 @@ async function buildRepository(
name: plugin.name, name: plugin.name,
version: plugin.version, version: plugin.version,
}); });
indexFileContents += `${plugin.name} ${plugin.version} "${plugin.description}"\n`;
}); });
meta.plugins = savedList; meta.plugins = savedList;
@ -251,7 +248,12 @@ async function buildRepository(
console.log('Creating repository index'); console.log('Creating repository index');
await fs.remove(outDir); await fs.remove(outDir);
await fs.ensureDir(outDir); await fs.ensureDir(outDir);
await fs.writeFile(path.join(outDir, 'repository'), indexFileContents); await fs.writeJSON(path.join(outDir, 'repository.json'), {
created: Math.floor(Date.now() / 1000),
name: meta.name,
plugins: meta.plugins,
schema: 1,
});
console.log('Copying plugins'); console.log('Copying plugins');
for (const plugin of plugins) { for (const plugin of plugins) {
@ -273,6 +275,16 @@ async function buildRepository(
} }
} }
console.log('Creating tarballs');
for (const plugin of plugins) {
const plOut = path.join(outDir, plugin.name);
await tar.c({
gzip: true,
file: plOut + '.plugin.tgz',
C: outDir,
}, [plugin.name]);
}
if (doDeploy == null) { if (doDeploy == null) {
console.log('Done!'); console.log('Done!');
return; return;
@ -287,7 +299,7 @@ async function watchRepository(
location?: string, location?: string,
out = true, out = true,
doDeploy?: string, doDeploy?: string,
onlyDeploy = false): void { onlyDeploy = false): Promise<void> {
if (!location) { if (!location) {
location = process.cwd(); location = process.cwd();

View File

@ -8,6 +8,7 @@ import { loadEnvironment } from '@squeebot/core/lib/core';
import { IEnvironment } from '@squeebot/core/lib/types'; import { IEnvironment } from '@squeebot/core/lib/types';
import { Squeebot } from './core'; import { Squeebot } from './core';
import { SqueebotCLI } from './cli';
const rl = readline.createInterface({ const rl = readline.createInterface({
input: process.stdin, input: process.stdin,
@ -29,7 +30,13 @@ async function start(argv: any): Promise<void> {
const sb = new Squeebot(env); const sb = new Squeebot(env);
await sb.initialize(); await sb.initialize(argv.e !== true);
// Create a CLI if interactive mode is enabled
if (argv.i === true) {
const sbrl = new SqueebotCLI(sb);
sbrl.attach(rl);
}
sb.attachReadline(rl); sb.attachReadline(rl);
} }
@ -50,6 +57,11 @@ yargs.scriptName('squeebotd')
alias: 'no-enable', alias: 'no-enable',
describe: 'Do not automatically execute enabled plugins on startup', describe: 'Do not automatically execute enabled plugins on startup',
type: 'boolean', type: 'boolean',
})
.option('i', {
alias: 'interactive',
describe: 'Enable built-in command line interface',
type: 'boolean',
}); });
}); });