From f0d192fbfdc9a5e9c2c9581f2ce9673a51ec97c1 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 22 Nov 2021 15:37:32 -0500 Subject: [PATCH] feat: autocomplete for activate/reset useless features:tm: --- src/cli/manage.js | 3 +++ src/cli/reset.js | 2 ++ src/plugins/install.js | 12 ++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/cli/manage.js b/src/cli/manage.js index 027c808798..326fc22c93 100644 --- a/src/cli/manage.js +++ b/src/cli/manage.js @@ -25,6 +25,9 @@ async function activate(plugin) { // Allow omission of `nodebb-plugin-` plugin = `nodebb-plugin-${plugin}`; } + + plugin = await plugins.autocomplete(plugin); + const isInstalled = await plugins.isInstalled(plugin); if (!isInstalled) { throw new Error('plugin not installed'); diff --git a/src/cli/reset.js b/src/cli/reset.js index 7d4c7e9e2a..75daeeb153 100644 --- a/src/cli/reset.js +++ b/src/cli/reset.js @@ -25,6 +25,7 @@ exports.reset = async function (options) { themeId = `nodebb-theme-${themeId}`; } + themeId = await plugins.autocomplete(themeId); await resetTheme(themeId); } }, @@ -38,6 +39,7 @@ exports.reset = async function (options) { pluginId = `nodebb-plugin-${pluginId}`; } + pluginId = await plugins.autocomplete(pluginId); await resetPlugin(pluginId); } }, diff --git a/src/plugins/install.js b/src/plugins/install.js index 8c0f6c644a..dcfd7a8c16 100644 --- a/src/plugins/install.js +++ b/src/plugins/install.js @@ -2,7 +2,7 @@ const winston = require('winston'); const path = require('path'); -const fs = require('fs'); +const fs = require('fs').promises; const nconf = require('nconf'); const os = require('os'); const cproc = require('child_process'); @@ -137,7 +137,7 @@ module.exports = function (Plugins) { Plugins.isInstalled = async function (id) { const pluginDir = path.join(paths.nodeModules, id); try { - const stats = await fs.promises.stat(pluginDir); + const stats = await fs.stat(pluginDir); return stats.isDirectory(); } catch (err) { return false; @@ -151,4 +151,12 @@ module.exports = function (Plugins) { Plugins.getActive = async function () { return await db.getSortedSetRange('plugins:active', 0, -1); }; + + Plugins.autocomplete = async (fragment) => { + const pluginDir = paths.nodeModules; + const plugins = (await fs.readdir(pluginDir)).filter(filename => filename.startsWith(fragment)); + + // Autocomplete only if single match + return plugins.length === 1 ? plugins.pop() : fragment; + }; };