From 222f8ce12788f3e28daf238edf1095cc1066e5b3 Mon Sep 17 00:00:00 2001 From: Mike Pirog Date: Fri, 24 Sep 2021 11:32:58 -0400 Subject: [PATCH] #25: remove lodash dep from init. reorganize in prep for abstraction --- bin/hyperdrive | 1 - cli/commands/add.js | 10 +-- cli/commands/install.js | 17 ++++ cli/commands/remove.js | 8 +- cli/commands/uninstall.js | 19 +++++ cli/hooks/init.js | 83 ++++++++++--------- .../docker-desktop.js} | 4 +- .../docker-desktop.js} | 2 +- utils/plugin.js | 35 ++++---- 9 files changed, 112 insertions(+), 67 deletions(-) create mode 100644 cli/commands/install.js create mode 100644 cli/commands/uninstall.js rename cli/{commands/install-docker-desktop.js => installers/docker-desktop.js} (91%) rename cli/{commands/uninstall-docker-desktop.js => uninstallers/docker-desktop.js} (95%) diff --git a/bin/hyperdrive b/bin/hyperdrive index 3ced4b8..9bfeea8 100755 --- a/bin/hyperdrive +++ b/bin/hyperdrive @@ -1,5 +1,4 @@ #!/usr/bin/env node - require('@oclif/command') .run() .then(require('@oclif/command/flush')) diff --git a/cli/commands/add.js b/cli/commands/add.js index 6782cb2..f994330 100644 --- a/cli/commands/add.js +++ b/cli/commands/add.js @@ -1,19 +1,19 @@ const {Command} = require('@oclif/command'); -class InstallCommand extends Command { - static description = 'install things'; +class AddCommand extends Command { + static description = 'add things'; static usage = 'usage'; - static aliases = ['install']; + // static aliases = ['install']; static examples = []; async run() { - const {flags} = this.parse(InstallCommand); + const {flags} = this.parse(AddCommand); const name = flags.name || 'world'; this.log(`goodbye ${name} from ./src/commands/hello.js`); } } -module.exports = InstallCommand; +module.exports = AddCommand; diff --git a/cli/commands/install.js b/cli/commands/install.js new file mode 100644 index 0000000..eb7181b --- /dev/null +++ b/cli/commands/install.js @@ -0,0 +1,17 @@ +const {Command} = require('@oclif/command'); + +class InstallCommand extends Command { + static description = 'install things'; + + static usage = 'usage'; + + static examples = []; + + async run() { + const {flags} = this.parse(InstallCommand); + const name = flags.name || 'world'; + this.log(`goodbye ${name} from ./src/commands/hello.js`); + } +} + +module.exports = InstallCommand; diff --git a/cli/commands/remove.js b/cli/commands/remove.js index 2aa3f76..b26dc52 100644 --- a/cli/commands/remove.js +++ b/cli/commands/remove.js @@ -1,6 +1,6 @@ const {Command, flags} = require('@oclif/command'); -class UninstallCommand extends Command { +class RemoveCommand extends Command { // static _base = 'thing'; // static id = 'thing'; // static title = 'title'; @@ -15,7 +15,7 @@ class UninstallCommand extends Command { static help = 'stuff'; - static aliases = ['uninstall']; + // static aliases = ['uninstall']; // static strict = false; // static parse = true; @@ -30,10 +30,10 @@ class UninstallCommand extends Command { // static async run() { - const {flags} = this.parse(UninstallCommand); + const {flags} = this.parse(RemoveCommand); const name = flags.name || 'unin'; this.log(`erg ${name} from ./src/commands/hello.js`); } } -module.exports = UninstallCommand; +module.exports = RemoveCommand; diff --git a/cli/commands/uninstall.js b/cli/commands/uninstall.js new file mode 100644 index 0000000..e057d30 --- /dev/null +++ b/cli/commands/uninstall.js @@ -0,0 +1,19 @@ +const {Command} = require('@oclif/command'); + +class UninstallCommand extends Command { + static description = 'install things'; + + static usage = 'usage'; + + // static aliases = ['install']; + + static examples = []; + + async run() { + const {flags} = this.parse(UninstallCommand); + const name = flags.name || 'world'; + this.log(`goodbye ${name} from ./src/commands/hello.js`); + } +} + +module.exports = UninstallCommand; diff --git a/cli/hooks/init.js b/cli/hooks/init.js index 497c7a1..a2ac9d5 100644 --- a/cli/hooks/init.js +++ b/cli/hooks/init.js @@ -1,43 +1,21 @@ -const _ = require('lodash'); // eslint-disable-line node/no-unpublished-require -const createDebugger = require('../../utils/debug'); -const Config = require('@oclif/config'); +const createDebugger = require('./../../utils/debug'); +const path = require('path'); -class DynamicPlugin extends Config.Plugin { - constructor(config, replace) { - super(config); - this.replace = replace; - } - - get hooks() { - return {}; - } - - get topics() { - return []; - } - - // @TODO: do we need this? - get commandIDs() { - return [this.replace.id]; - } - - get commands() { - const cmd = require(this.replace.path); - cmd.id = this.replace.id; - cmd.load = () => cmd; - return [cmd]; - } -} +// @TODO: only load this if we need it +const LandoOclifPlugin = require('./../../utils/plugin'); module.exports = async({id, argv, config}) => { let debug = createDebugger(config.dirname, 'hooks', 'init'); // Check for --debug and internally set DEBUG=* if its set // @TODO: we should make debug a string flag so it can work like setting DEBUG=something // @TODO: should we handle --debug on our own or use something lightweight like minimist? + // @TODO: or maybe add this as a util? + // @TODO: this should go at the top of bin/hyperdrive so we get debug output before this point + // @TODO: we should give preference to process.env.DEBUG if its set. if ([id, ...argv].find(element => element === '--debug') === '--debug') { require('debug').enable('*'); // eslint-disable-line node/no-extraneous-require } - // Below is mostly just to DEBUG confirm we get this far + // Below is mostly just to DEBUG confirm we can get this far debug('cli init start with id=%s, argv=%O', id, argv); // @TODOS: @@ -55,30 +33,61 @@ module.exports = async({id, argv, config}) => { * 10. move configurator into its own thing, move oclif helpers in their own thing? */ - // handle argv aliases + // handle argv install aliases + // @TODO: eventually this should be powered by config metadata + // @TODO: where will that metadata go? if ((id === 'install' || id === 'uninstall') && argv[0] === 'engine') { argv[0] = 'docker-desktop'; } + // @TODO: Below should be loaded via Configurator when that is ready to go + // @TODO: When a plugins manifest data is loaded it should construct an id for each component which is + // pluginname/component so for below this would give something like hyperdrive-core/docker-desktop + config.installers = [ + {name: 'docker-desktop', path: path.join(__dirname, '..', 'installers', 'docker-desktop.js')}, + ]; + config.uninstallers = [ + {name: 'docker-desktop', path: path.join(__dirname, '..', 'uninstallers', 'docker-desktop.js')}, + ]; + + // @TODO: move findPlugin to utils/utils.js? and eventually into @lando/oclifer? + // @TODO: eventually we should make criteria able to match by more than just name/id + const findPlugin = (plugins = [], criteria) => plugins.find(({name}) => name === criteria); + // @TODO: remove command should eventually be a method on LandoOclifPlugin + const removeCommand = (plugin = {}, cmdId) => { + const commandIndex = plugin.commands.findIndex(({id}) => id === cmdId); + if (commandIndex === -1) { + debug('could not find a command called %s in plugin %s, doing nothing', cmdId, plugin.name); + return plugin.commands; + } + plugin.commands.splice(commandIndex, 1); + debug('removed command %s: plugin now has commands %o', cmdId, plugin.commands.map(command => command.id).join(', ')); + return plugin.commands; + }; + + // @TODO: restantiate corePlugin as a ocliflandoplugin? + // if id-argv matches a signature then remove id and load up queuer // @NOTE: should this be both add and install? if (id === 'install' && argv[0] === 'docker-desktop') { // Lets remove the add command - const corePlugin = _.find(config.plugins, {name: '@lando/hyperdrive'}); + const corePlugin = findPlugin(config.plugins, '@lando/hyperdrive'); // delete corePlugin.manifest.commands.add; - _.remove(corePlugin.commands, {id: 'add'}); + corePlugin.commands = removeCommand(corePlugin, 'install'); // find the correct install plugin? - config.plugins.push(new DynamicPlugin(config, {id: 'install', path: './../commands/install-docker-desktop.js'})); + const installerPlugin = findPlugin(config.installers, 'docker-desktop'); + config.plugins.push(new LandoOclifPlugin(config, {id: 'install', path: installerPlugin.path})); } // if id-argv matches a signature then remove id and load up queuer // @NOTE: should this be both add and install? if (id === 'uninstall' && argv[0] === 'docker-desktop') { // Lets remove the add command - const corePlugin = _.find(config.plugins, {name: '@lando/hyperdrive'}); + const corePlugin = findPlugin(config.plugins, '@lando/hyperdrive'); // delete corePlugin.manifest.commands.add; - _.remove(corePlugin.commands, {id: 'remove'}); + corePlugin.commands = removeCommand(corePlugin, 'uninstall'); // find the correct install plugin? - config.plugins.push(new DynamicPlugin(config, {id: 'uninstall', path: './../commands/uninstall-docker-desktop.js'})); + const uninstallerPlugin = findPlugin(config.uninstallers, 'docker-desktop'); + config.plugins.push(new LandoOclifPlugin(config, {id: 'uninstall', path: uninstallerPlugin.path})); } }; diff --git a/cli/commands/install-docker-desktop.js b/cli/installers/docker-desktop.js similarity index 91% rename from cli/commands/install-docker-desktop.js rename to cli/installers/docker-desktop.js index caee3f9..b707a78 100644 --- a/cli/commands/install-docker-desktop.js +++ b/cli/installers/docker-desktop.js @@ -2,7 +2,7 @@ const {Command, flags} = require('@oclif/command'); class InstallDockerDesktop extends Command { // static _base = 'thing'; - // static id = 'thing'; + static id = 'install'; // static title = 'title'; static description = 'install docker desktop' @@ -13,8 +13,6 @@ class InstallDockerDesktop extends Command { static help = 'stuff'; - static aliases = ['add']; - // static strict = false; // static parse = true; static flags = { diff --git a/cli/commands/uninstall-docker-desktop.js b/cli/uninstallers/docker-desktop.js similarity index 95% rename from cli/commands/uninstall-docker-desktop.js rename to cli/uninstallers/docker-desktop.js index 72bd415..6620cf8 100644 --- a/cli/commands/uninstall-docker-desktop.js +++ b/cli/uninstallers/docker-desktop.js @@ -13,7 +13,7 @@ class UninstallDockerDesktop extends Command { static help = 'stuff'; - static aliases = ['remove']; + // static aliases = ['remove']; // static strict = false; // static parse = true; diff --git a/utils/plugin.js b/utils/plugin.js index e776622..c1f2d4b 100644 --- a/utils/plugin.js +++ b/utils/plugin.js @@ -1,27 +1,30 @@ -/* - * New plugin types: - * HyperdrivePlugin extends Config.Plugin - * 1. accepts a list of commands and an optional selector function for a "parent" - * - * -*/ -/* -const Config = require('@oclif/config'); +const OclifPlugin = require('@oclif/config').Plugin; + +class LandoOclifPlugin extends OclifPlugin { + constructor(config, replace) { + super(config); + this.replace = replace; + } + + get hooks() { + return {}; + } -class DynamicPlugin extends Config.Plugin { - get hooks() { return {} } get topics() { - return [] + return []; } + + // @TODO: do we need this? get commandIDs() { - return ['mydynamiccommand'] + return [this.replace.id]; } get commands() { - const cmd = require('../more/bye'); - cmd.id = 'bye'; + const cmd = require(this.replace.path); + cmd.id = this.replace.id; cmd.load = () => cmd; return [cmd]; } } -*/ + +module.exports = LandoOclifPlugin;