import { parse } from "https://deno.land/std/flags/mod.ts"; var parsed_args = parse( Deno.args, { default: { h: false, }, stopEarly: true, boolean: [ "h" ], string: [], alias: { h: [ "help", "usage", "u" ] }, collect: [], negatable: [], // a function which is invoked with a command line parameter not defined // in the options configuration object. If the function returns false, // the unknown option is not added to parsedArgs. unknown: null } ); let printUsage = () => { let usage = ` Command-line interface for LibResilient. This script creates a common interface to CLI actions implemented by LibResilient plugins. Usage: ${new URL('', import.meta.url).toString().split('/').at(-1)} [options] [plugin-name [plugin-options]] Options: -h, --help [plugin-name] -u, --usage [plugin-name] Print this message, if no plugin-name is given. If plugin-name is provided, print usage information of that plugin. ` console.log(usage) } let printpluginUsage = (plugin) => { let usage = ` LibResilient CLI for plugin: ${plugin.name}. Plugin Description: ${plugin.description} Usage: ${new URL('', import.meta.url).toString().split('/').at(-1)} [general-options] ${plugin.name} [plugin-action [action-options]] General Options: -h, --help [plugin-name] -u, --usage [plugin-name] Print this message, if no plugin-name is given. If plugin-name is provided, print usage information of that plugin. Actions and Action Options: ` console.log(usage) } let parsePluginActionArgs = (args, argdef) => { var plugin_args_config = { boolean: [], string: [], alias: {}, collect: [], negatable: [], unknown: null, default: {}, alias: {} } for (const [argname, argconfig] of Object.entries(argdef)) { if (argname == '_') { continue; } if ( ("collect" in argconfig) && (argconfig.collect === true) ) { plugin_args_config.collect.push(argname) } if ( ("string" in argconfig) && (argconfig.string === true) ) { plugin_args_config.string.push(argname) } if ( ("boolean" in argconfig) && (argconfig.boolean === true) ) { plugin_args_config.boolean.push(argname) } if ( ("negatable" in argconfig) && (argconfig.negatable === true) ) { plugin_args_config.negatable.push(argname) } if ("default" in argconfig) { plugin_args_config.default[argname] = argconfig.default } } var parsed = parse(args, plugin_args_config) //console.log(parsed) var result = [] for (const argname of Object.keys(argdef)) { if (argname in parsed) { result.push(parsed[argname]) } } return result } // assuming: // - the first unknown argument is the name of the plugin // - plugins live in ../plugins//cli.js, relative to lrcli.js location // - only one plugin loaded per invocation, at least for now // // we *always* pass arguments to plugins as arrays of strings, // even if we only got one value let plugin if (parsed_args._.length > 0) { plugin = await import(`../plugins/${parsed_args._[0]}/cli.js`); if (parsed_args._.length > 1) { let action = parsed_args._[1] if (action in plugin.actions) { var parsed_plugin_args = parsePluginActionArgs( // removing the plugin name and the method name parsed_args._.slice(2), plugin.actions[action].arguments ) // not using console.log here because we want the *exact* output // without any extra ending newlines await Deno.stdout.write( new TextEncoder().encode( await plugin.actions[action].run(...parsed_plugin_args) ) ) } else { printpluginUsage(plugin) } } else { printpluginUsage(plugin) } } else { printUsage() } //console.log(new URL('', import.meta.url).toString().split('/').at(-1))