|
|
|
@ -66,7 +66,7 @@ def cli(ctx, default_config_path, local_operation, only_default_layer, new_devic
|
|
|
|
log.info(F"Shepherd Agent [{version_text}]")
|
|
|
|
log.info(F"Shepherd Agent [{version_text}]")
|
|
|
|
|
|
|
|
|
|
|
|
# Drop down to subcommand if it doesn't need default config file processing
|
|
|
|
# Drop down to subcommand if it doesn't need default config file processing
|
|
|
|
if ctx.invoked_subcommand == "template":
|
|
|
|
if ctx.invoked_subcommand in ["template", "info"]:
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# Get a default config path to use
|
|
|
|
# Get a default config path to use
|
|
|
|
@ -293,3 +293,86 @@ def template(ctx, plugin_name, include_all, config_path, plugin_dir):
|
|
|
|
click.echo(F"Writing [{plugin_name}] template to {config_path}")
|
|
|
|
click.echo(F"Writing [{plugin_name}] template to {config_path}")
|
|
|
|
with open(config_path, 'w+') as f:
|
|
|
|
with open(config_path, 'w+') as f:
|
|
|
|
f.write(template_toml)
|
|
|
|
f.write(template_toml)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cli.command()
|
|
|
|
|
|
|
|
@click.argument('plugin_name', required=False)
|
|
|
|
|
|
|
|
@click.option('-d', '--plugin-dir', type=click.Path(),
|
|
|
|
|
|
|
|
help="Directory to search for plugin modules, in addition to built in Shepherd"
|
|
|
|
|
|
|
|
" plugins and the global import path. Defaults to current directory.")
|
|
|
|
|
|
|
|
@click.pass_context
|
|
|
|
|
|
|
|
def info(ctx, plugin_name, plugin_dir):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Show plugin information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If plugin_name is not provided, shows list of all discovered plugins and their sources. Note
|
|
|
|
|
|
|
|
that this will detect _all_ valid python modules in the plugin_dir as custom plugins, as these
|
|
|
|
|
|
|
|
are not validated as proper Shepherd plugins until they are loaded.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If plugin_name is provided, attempts to load (but not initialise) the desired plugin and show
|
|
|
|
|
|
|
|
all registered plugin features (interface functions, hooks, attachments, and
|
|
|
|
|
|
|
|
config specification).
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_heading("Shepherd - Info")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not plugin_dir:
|
|
|
|
|
|
|
|
plugin_dir = Path.cwd()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not plugin_name:
|
|
|
|
|
|
|
|
log.info("Running plugin discovery...")
|
|
|
|
|
|
|
|
base_plugins = plugin.discover_base_plugins()
|
|
|
|
|
|
|
|
custom_plugins = plugin.discover_custom_plugins(plugin_dir)
|
|
|
|
|
|
|
|
installed_plugins = plugin.discover_installed_plugins()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Discovered base plugins:")
|
|
|
|
|
|
|
|
if len(base_plugins) == 0:
|
|
|
|
|
|
|
|
click.echo("---none---")
|
|
|
|
|
|
|
|
for name in base_plugins:
|
|
|
|
|
|
|
|
click.secho(F" {name}", fg='green')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Discovered custom plugins:")
|
|
|
|
|
|
|
|
if len(custom_plugins) == 0:
|
|
|
|
|
|
|
|
click.echo("---none---")
|
|
|
|
|
|
|
|
for name in custom_plugins:
|
|
|
|
|
|
|
|
click.secho(F" {name}", fg='green')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Discovered installed plugins:")
|
|
|
|
|
|
|
|
if len(installed_plugins) == 0:
|
|
|
|
|
|
|
|
click.echo("---none---")
|
|
|
|
|
|
|
|
for name in installed_plugins:
|
|
|
|
|
|
|
|
click.secho(F" {name}", fg='green')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Plugin name supplied, so load it
|
|
|
|
|
|
|
|
plugin_interface = None
|
|
|
|
|
|
|
|
log.info(F"Attempting to load plugin {plugin_name}...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
plugin_interface = plugin.load_plugin(plugin_name, plugin_dir)
|
|
|
|
|
|
|
|
except plugin.PluginLoadError as e:
|
|
|
|
|
|
|
|
log.error(e.args[0])
|
|
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Plugin info for", input_text=plugin_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# template_dict = confspec.get_template(include_all)
|
|
|
|
|
|
|
|
# template_toml = toml.dumps({plugin_name: template_dict}, encoder=BlankEncoder())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Interface functions:")
|
|
|
|
|
|
|
|
for ifunc_name, ifunc in plugin_interface._functions.items():
|
|
|
|
|
|
|
|
args = ""
|
|
|
|
|
|
|
|
if ifunc.remote:
|
|
|
|
|
|
|
|
args = F"{ifunc.spec}"
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
args = F"{inspect.signature(ifunc.func)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
click.echo(F"{ifunc_name} {args}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Hooks:")
|
|
|
|
|
|
|
|
for hook in plugin_interface._hooks:
|
|
|
|
|
|
|
|
click.echo(hook)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo_section("Config:")
|
|
|
|
|
|
|
|
click.echo(plugin_interface._confspec)
|
|
|
|
|