From 84bf0ea211bba1ed48950c99bea283d226872eec Mon Sep 17 00:00:00 2001 From: yolossn Date: Tue, 14 May 2024 01:37:27 +0530 Subject: [PATCH] headlamp-plugin: Add plugin mgmt commands This patch adds the plugin management commands install,uninstall,update and list to the headlamp-plugin cli. Signed-off-by: yolossn --- plugins/headlamp-plugin/README.md | 5 + .../headlamp-plugin/bin/headlamp-plugin.js | 157 ++++++++++++++++++ plugins/headlamp-plugin/package-lock.json | 13 +- plugins/headlamp-plugin/package.json | 3 +- 4 files changed, 171 insertions(+), 7 deletions(-) diff --git a/plugins/headlamp-plugin/README.md b/plugins/headlamp-plugin/README.md index f761b4d783f..c0128ab0eb2 100644 --- a/plugins/headlamp-plugin/README.md +++ b/plugins/headlamp-plugin/README.md @@ -48,6 +48,11 @@ headlamp-plugin --help headlamp-plugin.js test [package] Test. defaults to current working directory. Can also be a folder of packages. + headlamp-plugin.js list List installed plugins. + headlamp-plugin.js install [URL] Install a plugin from the specified + Artifact Hub URL. + headlamp-plugin.js update [pluginName] Update the plugin to the latest version. + headlamp-plugin.js uninstall [pluginName] Uninstall the plugin. ``` ## Development notes diff --git a/plugins/headlamp-plugin/bin/headlamp-plugin.js b/plugins/headlamp-plugin/bin/headlamp-plugin.js index e7162d70c0d..10a133f74cb 100755 --- a/plugins/headlamp-plugin/bin/headlamp-plugin.js +++ b/plugins/headlamp-plugin/bin/headlamp-plugin.js @@ -13,6 +13,8 @@ const child_process = require('child_process'); const validate = require('validate-npm-package-name'); const yargs = require('yargs/yargs'); const headlampPluginPkg = require('../package.json'); +const pluginManager = require('../plugin-management-utils'); +const { table } = require('table'); /** * Creates a new plugin folder. @@ -1172,6 +1174,161 @@ yargs(process.argv.slice(2)) process.exitCode = test(argv.package); } ) + .command( + 'install [URL]', + 'Install a plugin from the Artiface Hub URL', + yargs => { + yargs + .positional('URL', { + describe: 'URL of the plugin to install', + type: 'string', + }) + .option('folderName', { + describe: 'Name of the folder to install the plugin into', + type: 'string', + }) + .option('headlampVersion', { + describe: 'Version of headlamp to install the plugin into', + type: 'string', + }) + .option('quiet', { + alias: 'q', + describe: 'Do not print logs', + type: 'boolean', + }); + }, + async argv => { + const { URL, folderName, headlampVersion, quiet } = argv; + const progressCallback = quiet + ? null + : data => { + console.log(data.type, ':', data.message); + }; // Use console.log for logs if not in quiet mode + try { + await pluginManager.install(URL, folderName, headlampVersion, progressCallback); + } catch (e) { + console.error(e.message); + process.exit(1); // Exit with error status + } + } + ) + .command( + 'update [pluginName]', + 'Update a plugin to the latest version', + yargs => { + yargs + .positional('pluginName', { + describe: 'Name of the plugin to update', + type: 'string', + }) + .positional('folderName', { + describe: 'Name of the folder that contains the plugin', + type: 'string', + }) + .positional('headlampVersion', { + describe: 'Version of headlamp to update the plugin into', + type: 'string', + }) + .option('quiet', { + alias: 'q', + describe: 'Do not print logs', + type: 'boolean', + }); + }, + async argv => { + const { pluginName, folderName, headlampVersion, quiet } = argv; + const progressCallback = quiet + ? null + : data => { + console.log(data.type, ':', data.message); + }; // Use console.log for logs if not in quiet mode + try { + await pluginManager.update(pluginName, folderName, headlampVersion, progressCallback); + } catch (e) { + console.error(e.message); + process.exit(1); // Exit with error status + } + } + ) + .command( + 'uninstall [pluginName]', + 'Uninstall a plugin', + yargs => { + yargs + .positional('pluginName', { + describe: 'Name of the plugin to uninstall', + type: 'string', + }) + .option('folderName', { + describe: 'Name of the folder that contains the plugin', + type: 'string', + }) + .option('quiet', { + alias: 'q', + describe: 'Do not print logs', + type: 'boolean', + }); + }, + async argv => { + const { pluginName, folderName, quiet } = argv; + const progressCallback = quiet + ? null + : data => { + console.log(data.type, ':', data.message); + }; // Use console.log for logs if not in quiet mode + try { + await pluginManager.uninstall(pluginName, folderName, progressCallback); + } catch (e) { + console.error(e.message); + process.exit(1); // Exit with error status + } + } + ) + .command( + 'list', + 'List installed plugins', + yargs => { + yargs + .option('folderName', { + describe: 'Name of the folder that contains the plugins', + type: 'string', + }) + .option('json', { + alias: 'j', + describe: 'Output in JSON format', + type: 'boolean', + }); + }, + async argv => { + const { folderName, json } = argv; + const progressCallback = data => { + if (json) { + console.log(JSON.stringify(data.data)); + } else { + // display table + const rows = [ + ['Name', 'Version', 'Folder Name', 'ArticaftHub URL', 'ArtifactHub Version'], + ]; + data.data.forEach(plugin => { + rows.push([ + plugin.pluginName, + plugin.pluginVersion, + plugin.folderName, + plugin.artifacthubURL, + plugin.artifacthubVersion, + ]); + }); + console.log(table(rows)); + } + }; + try { + await pluginManager.list(folderName, progressCallback); + } catch (e) { + console.error(e.message); + process.exit(1); // Exit with error status + } + } + ) .demandCommand(1, '') .strict() .help().argv; diff --git a/plugins/headlamp-plugin/package-lock.json b/plugins/headlamp-plugin/package-lock.json index 702d721f454..cc1699f7db5 100644 --- a/plugins/headlamp-plugin/package-lock.json +++ b/plugins/headlamp-plugin/package-lock.json @@ -139,6 +139,7 @@ "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "style-loader": "^3.3.1", + "table": "^6.8.2", "tsconfig-paths-webpack-plugin": "^4.0.0", "typescript": "4.5.5", "url": "^0.11.0", @@ -33362,9 +33363,9 @@ "integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==" }, "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -59880,9 +59881,9 @@ "integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==" }, "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "requires": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", diff --git a/plugins/headlamp-plugin/package.json b/plugins/headlamp-plugin/package.json index 380e4a11006..7ecddff934b 100644 --- a/plugins/headlamp-plugin/package.json +++ b/plugins/headlamp-plugin/package.json @@ -165,7 +165,8 @@ "template", "lib", "types", - ".storybook" + ".storybook", + "plugin-management-utils.js" ], "keywords": [ "headlamp",