diff options
Diffstat (limited to 'lmi/scripts/_metacommand/manager.py')
-rw-r--r-- | lmi/scripts/_metacommand/manager.py | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/lmi/scripts/_metacommand/manager.py b/lmi/scripts/_metacommand/manager.py deleted file mode 100644 index 773979b..0000000 --- a/lmi/scripts/_metacommand/manager.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright (C) 2013-2014 Red Hat, Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# The views and conclusions contained in the software and documentation are -# those of the authors and should not be interpreted as representing official -# policies, either expressed or implied, of the FreeBSD Project. -# -# Authors: Michal Minar <miminar@redhat.com> -# -""" -Manager module for direct subcommands of lmi metacommand. Most of them are -loaded from entry_points of installed python eggs. -""" - -import pkg_resources - -from lmi.scripts.common import Configuration -from lmi.scripts.common import errors -from lmi.scripts.common import get_logger -from lmi.scripts.common.command import base -from lmi.scripts.common.command import util - -LOG = get_logger(__name__) - -class _CustomCommandWrapper(object): - """ - Provide an interface mocking an entry_point object for custom commands - added by lmi metacommand application. - - :param name: (``str``) Name of command. - :param cmd_class: (``LmiBaseCommand``) Factory for custom commands. - """ - - def __init__(self, name, cmd_class): - if not isinstance(name, basestring): - raise TypeError("name must be a string") - if not issubclass(cmd_class, base.LmiBaseCommand): - raise TypeError("cmd_class must be a LmiBaseCommand") - self._name = name - self._cmd_class = cmd_class - - @property - def name(self): - """ Return command name. """ - return self._name - - def load(self): - """ Return command class. """ - return self._cmd_class - -class CommandManager(object): - """ - Manager of direct subcommands of lmi metacommand. It manages commands - registered with entry_points under particular namespace installed by - python eggs. Custom commands may also be added. - - :param namespace: (``str``) Namespace, where commands are registered. - For example ``lmi.scripts.cmd``. - """ - - def __init__(self, namespace=None): - if namespace is not None and not isinstance(namespace, basestring): - raise TypeError("namespace must be a string") - if namespace is None: - namespace = Configuration.get_instance().get_safe( - "Main", "CommandNamespace") - self._namespace = namespace - self._commands = {} - self._load_commands() - - @property - def command_names(self): - """ Returns list of command names. """ - return self._commands.keys() - - def __len__(self): - return len(self._commands) - - def __iter__(self): - """ Yields command names. """ - return iter(self._commands) - - def __getitem__(self, cmd_name): - """ Gets command factory for name. """ - return self.find_command(cmd_name) - - def _load_commands(self): - """ Loads commands from entry points under provided namespace. """ - def _add_entry_point(epoint): - """ - Convenience function taking an entry point, making some name - checks and adding it to registered commands. - """ - if not util.RE_COMMAND_NAME.match(epoint.name): - LOG().error('Invalid command name: %s, ignoring.', epoint.name) - return - if epoint.name in self._commands: - LOG().warn('Command "%s" already registered, ignoring.', - epoint.name) - else: - LOG().debug('Found registered command "%s".', epoint.name) - self._commands[epoint.name] = epoint - - for entry_point in pkg_resources.iter_entry_points(self._namespace): - if isinstance(entry_point, dict): - for epoint in entry_point.values(): - _add_entry_point(epoint) - else: - _add_entry_point(entry_point) - - - def add_command(self, name, cmd_class): - """ - Registers custom command. May be used for example for *help* command. - - :param name: (``str``) Name of command. - :param cmd_class: (``LmiBaseCommand``) Factory for commands. - """ - if not isinstance(name, basestring): - raise TypeError("name must be a string") - if not issubclass(cmd_class, base.LmiBaseCommand): - raise TypeError("cmd_class must be a LmiBaseCommand") - if not util.RE_COMMAND_NAME.match(name): - raise errors.LmiCommandInvalidName( - cmd_class.__module__, cmd_class.__class__.__name__, name) - if name in self._commands: - LOG().warn('Command "%s" already managed, overwriting with "%s:%s".', - name, cmd_class.__module__, cmd_class.__name__) - self._commands[name] = _CustomCommandWrapper(name, cmd_class) - - def find_command(self, cmd_name): - """ - Loads a command associated with given name and returns it. - - :param cmd_name: (``str``) Name of command to load. - :rtype: (``LmiBaseCommand``) Factory for commands. - """ - try: - return self._commands[cmd_name].load() - except KeyError: - raise errors.LmiCommandNotFound(cmd_name) - except ImportError as err: - LOG().debug('Failed to import command "%s".', cmd_name, exc_info=err) - raise errors.LmiCommandImportError( - cmd_name, self._commands[cmd_name].module_name, err) - - def reload_commands(self, keep_custom=True): - """ - Flushes all commands and reloads entry points. - - :param keep_custom: (``bool``) Custom commands -- not loaded from - entry points -- are preserved. - """ - if keep_custom: - keep = { n: c for n, c in self._commands.items() - if isinstance(c, _CustomCommandWrapper)} - else: - keep = {} - self._commands = {} - self._load_commands() - self._commands.update(keep) - |