Added a simple plugin validator
This commit is contained in:
parent
552146551c
commit
1a9001e956
3 changed files with 152 additions and 8 deletions
|
@ -25,6 +25,7 @@ Issues = "https://forge.monodon.me/Gnarwhal/sshare/issues"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
sshare = "sshare.main:main"
|
sshare = "sshare.main:main"
|
||||||
|
sshare-validate = "sshare.validator:main"
|
||||||
|
|
||||||
[tool.setuptools_scm]
|
[tool.setuptools_scm]
|
||||||
version_file = "src/sshare/version.py"
|
version_file = "src/sshare/version.py"
|
||||||
|
|
|
@ -21,11 +21,11 @@ from sshare import config_directory
|
||||||
|
|
||||||
class PluginLoader:
|
class PluginLoader:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def all(command_line=False, logger=None, config=None, flags=None):
|
def all(command_line=False, logger=None, config=dict(), flags=dict()):
|
||||||
return PluginLoader.internal(command_line, logger, config, flags) + PluginLoader.external(logger, config, flags)
|
return PluginLoader.internal(command_line, logger, config, flags) + PluginLoader.external(logger, config, flags)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def internal(command_line=False, logger=None, config=None, flags=None):
|
def internal(command_line=False, logger=None, config=dict(), flags=dict()):
|
||||||
return [
|
return [
|
||||||
Plugin.internal(plugin, logger, config, flags)
|
Plugin.internal(plugin, logger, config, flags)
|
||||||
for plugin
|
for plugin
|
||||||
|
@ -41,7 +41,7 @@ class PluginLoader:
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def external(logger=None, config=None, flags=None):
|
def external(logger=None, config=dict(), flags=dict()):
|
||||||
return [
|
return [
|
||||||
Plugin.external(plugin, logger, config, flags)
|
Plugin.external(plugin, logger, config, flags)
|
||||||
for plugin
|
for plugin
|
||||||
|
@ -49,7 +49,7 @@ class PluginLoader:
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def at(logger=None, config=None, flags=None, *args):
|
def at(logger=None, config=dict(), flags=dict(), *args):
|
||||||
return [
|
return [
|
||||||
Plugin.external(plugin, logger, config, flags)
|
Plugin.external(plugin, logger, config, flags)
|
||||||
for plugin
|
for plugin
|
||||||
|
@ -91,8 +91,19 @@ class PluginManager:
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def types():
|
def types(methods=False):
|
||||||
return [ "logger", "source", "name", "upload", "location", "feedback" ]
|
types = {
|
||||||
|
"logger": { "info", "warn", "error" },
|
||||||
|
"source": { "get_source" },
|
||||||
|
"name": { "get_name" },
|
||||||
|
"upload": { "upload" },
|
||||||
|
"location": { "get_location" },
|
||||||
|
"feedback": { "give_feedback"},
|
||||||
|
}
|
||||||
|
if methods:
|
||||||
|
return types
|
||||||
|
else:
|
||||||
|
return types.keys()
|
||||||
|
|
||||||
def __init__(self, name, module, logger, external_config, external_flags):
|
def __init__(self, name, module, logger, external_config, external_flags):
|
||||||
self.__dict__ = module.__dict__
|
self.__dict__ = module.__dict__
|
||||||
|
@ -169,11 +180,11 @@ class Plugin:
|
||||||
return activate
|
return activate
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def internal(name=None, logger=None, config=None, flags=None):
|
def internal(name=None, logger=None, config=dict(), flags=dict()):
|
||||||
return Plugin(name, importlib.import_module(f"sshare.plugins.{name}"), logger, config.get(name, dict()), flags.get(name, dict()))
|
return Plugin(name, importlib.import_module(f"sshare.plugins.{name}"), logger, config.get(name, dict()), flags.get(name, dict()))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def external(path, logger=None, config=None, flags=None):
|
def external(path, logger=None, config=dict(), flags=dict()):
|
||||||
module_spec = importlib.util.spec_from_file_location(
|
module_spec = importlib.util.spec_from_file_location(
|
||||||
path.stem,
|
path.stem,
|
||||||
path.as_posix(),
|
path.as_posix(),
|
||||||
|
|
132
src/sshare/validator.py
Normal file
132
src/sshare/validator.py
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
# This file is part of SSHare.
|
||||||
|
#
|
||||||
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
# the GNU General Public License as published by the Free Software Foundation,
|
||||||
|
# either version 3 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# SSHare. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from sshare import config_directory
|
||||||
|
from sshare.plugin import Plugin
|
||||||
|
from sshare.plugin import PluginLoader
|
||||||
|
from sshare.version import version
|
||||||
|
|
||||||
|
def validate(plugin, quiet=False):
|
||||||
|
def log(message):
|
||||||
|
if not quiet:
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
error_count = 0
|
||||||
|
def error(message, end=False):
|
||||||
|
nonlocal error_count
|
||||||
|
nonlocal log
|
||||||
|
|
||||||
|
if error_count == 0:
|
||||||
|
log("[\033[91mFAILED\033[0m]")
|
||||||
|
error_count = error_count + 1
|
||||||
|
log(f"\033[91m => {message}\033[0m")
|
||||||
|
|
||||||
|
def success():
|
||||||
|
nonlocal log
|
||||||
|
|
||||||
|
log(f"[\033[92mOK\033[0m]")
|
||||||
|
|
||||||
|
mandatory_keys = dict()
|
||||||
|
def validate_type_and_add_keys(type):
|
||||||
|
nonlocal mandatory_keys
|
||||||
|
|
||||||
|
types = Plugin.types(methods=True)
|
||||||
|
if type in types:
|
||||||
|
mandatory_keys[type] = types[type]
|
||||||
|
|
||||||
|
else:
|
||||||
|
error(f"plugin_type '{type}' is not a valid plugin type")
|
||||||
|
if not hasattr(plugin, "plugin_type"):
|
||||||
|
error("must define plugin_type")
|
||||||
|
else:
|
||||||
|
if isinstance(plugin.plugin_type, set):
|
||||||
|
for index, type in enumerate(plugin.plugin_type):
|
||||||
|
validate_type_and_add_keys(type)
|
||||||
|
elif isinstance(plugin.plugin_type, str):
|
||||||
|
validate_type_and_add_keys(plugin.plugin_type)
|
||||||
|
else:
|
||||||
|
error("plugin_type must be either a string or a set of strings")
|
||||||
|
|
||||||
|
for type, keys in mandatory_keys.items():
|
||||||
|
for key in keys:
|
||||||
|
if not hasattr(plugin, key):
|
||||||
|
error(f"plugin type '{type}' requires definition of '{key}' ")
|
||||||
|
|
||||||
|
if hasattr(plugin, "activate"):
|
||||||
|
def validate_activate(args, type=None):
|
||||||
|
def validate_activate_arg(arg):
|
||||||
|
nonlocal plugin
|
||||||
|
nonlocal type
|
||||||
|
|
||||||
|
if hasattr(plugin, "args"):
|
||||||
|
if arg in plugin.args.keys():
|
||||||
|
return
|
||||||
|
error(f"activate arg '{arg}' does not exist in 'args'")
|
||||||
|
if isinstance(args, set):
|
||||||
|
for arg in args:
|
||||||
|
validate_activate_arg(arg)
|
||||||
|
else:
|
||||||
|
validate_activate_arg(arg)
|
||||||
|
|
||||||
|
if isinstance(plugin.activate, dict):
|
||||||
|
for type, args in plugin.activate.items():
|
||||||
|
if not type in Plugin.types():
|
||||||
|
error(f"activate specified for unrecognized plugin type '{type}'")
|
||||||
|
validate_activate(args, type)
|
||||||
|
else:
|
||||||
|
validate_activate(plugin.activate)
|
||||||
|
|
||||||
|
if error_count == 0:
|
||||||
|
success()
|
||||||
|
return error_count
|
||||||
|
|
||||||
|
def main():
|
||||||
|
arg_parser = argparse.ArgumentParser(
|
||||||
|
prog="sshare-validate",
|
||||||
|
description="Validate sshare plugins",
|
||||||
|
)
|
||||||
|
arg_parser.add_argument(
|
||||||
|
"-v",
|
||||||
|
"--version",
|
||||||
|
action="version",
|
||||||
|
version=f"%(prog)s version {version}",
|
||||||
|
)
|
||||||
|
arg_parser.add_argument(
|
||||||
|
"--dev",
|
||||||
|
action="store_const",
|
||||||
|
const=True,
|
||||||
|
help="Validate all internal and external plugins"
|
||||||
|
)
|
||||||
|
arg_parser.add_argument(
|
||||||
|
"plugins",
|
||||||
|
nargs="*",
|
||||||
|
help="plugin(s) to be validated",
|
||||||
|
)
|
||||||
|
arguments = arg_parser.parse_args()
|
||||||
|
if arguments.dev:
|
||||||
|
to_be_validated = PluginLoader.all(command_line=True)
|
||||||
|
elif len(arguments.plugins) > 0:
|
||||||
|
to_be_validated = PluginLoader.at(*arguments.plugins)
|
||||||
|
else:
|
||||||
|
to_be_validated = PluginLoader.external()
|
||||||
|
|
||||||
|
longest = 0
|
||||||
|
for plugin in to_be_validated:
|
||||||
|
if len(plugin.name) > longest:
|
||||||
|
longest = len(plugin.name)
|
||||||
|
for plugin in to_be_validated:
|
||||||
|
print(f"{plugin.name}{"".join([ " " for _ in range(0, longest-len(plugin.name))])} ", end="")
|
||||||
|
validate(plugin)
|
Loading…
Reference in a new issue