def __init__(self): self.core = None description = "%s: %s" % (self.__class__.__name__.lower(), self.__class__.__doc__) #: The :class:`Bcfg2.Options.Parser` that will be used to #: parse options if this subcommand is called from an #: interactive :class:`cmd.Cmd` shell. self.parser = Parser(prog=self.__class__.__name__.lower(), description=description, components=[self], add_base_options=False, epilog=self.help) self._usage = None #: A :class:`logging.Logger` that can be used to produce #: logging output for this command. self.logger = logging.getLogger(self.__class__.__name__.lower())
def __init__(self): self.core = None description = "%s: %s" % (self.__class__.__name__.lower(), self.__class__.__doc__) #: The :class:`Bcfg2.Options.Parser` that will be used to #: parse options if this subcommand is called from an #: interactive :class:`cmd.Cmd` shell. self.parser = Parser( prog=self.__class__.__name__.lower(), description=description, components=[self], add_base_options=False, epilog=self.help) self._usage = None #: A :class:`logging.Logger` that can be used to produce #: logging output for this command. self.logger = logging.getLogger(self.__class__.__name__.lower())
class Subcommand(object): """ Base class for subcommands. This must be subclassed to create commands. Specifically, you must override :func:`Bcfg2.Options.Subcommand.run`. You may want to override: * The docstring, which will be used as the short help. * :attr:`Bcfg2.Options.Subcommand.options` * :attr:`Bcfg2.Options.Subcommand.help` * :attr:`Bcfg2.Options.Subcommand.interactive` * * :func:`Bcfg2.Options.Subcommand.shutdown` You should not need to override :func:`Bcfg2.Options.Subcommand.__call__` or :func:`Bcfg2.Options.Subcommand.usage`. A ``Subcommand`` subclass constructor must not take any arguments. """ #: Options this command takes options = [] #: Longer help message help = None #: Whether or not to expose this command in an interactive #: :class:`cmd.Cmd` shell, if one is used. (``bcfg2-info`` uses #: one, ``bcfg2-admin`` does not.) interactive = True #: Whether or not to expose this command as command line parameter #: or only in an interactive :class:`cmd.Cmd` shell. only_interactive = False #: Additional aliases for the command. The contents of the list gets #: added to the default command name (the lowercased class name) aliases = [] _ws_re = re.compile(r'\s+', flags=re.MULTILINE) def __init__(self): self.core = None description = "%s: %s" % (self.__class__.__name__.lower(), self.__class__.__doc__) #: The :class:`Bcfg2.Options.Parser` that will be used to #: parse options if this subcommand is called from an #: interactive :class:`cmd.Cmd` shell. self.parser = Parser( prog=self.__class__.__name__.lower(), description=description, components=[self], add_base_options=False, epilog=self.help) self._usage = None #: A :class:`logging.Logger` that can be used to produce #: logging output for this command. self.logger = logging.getLogger(self.__class__.__name__.lower()) def __call__(self, args=None): """ Perform option parsing and other tasks necessary to support running ``Subcommand`` objects as part of a :class:`cmd.Cmd` shell. You should not need to override ``__call__``. :param args: Arguments given in the interactive shell :type args: list of strings :returns: The return value of :func:`Bcfg2.Options.Subcommand.run` """ if args is not None: self.parser.namespace = copy.copy(master_setup) self.parser.parsed = False alist = shlex.split(args) try: setup = self.parser.parse(alist) except SystemExit: return sys.exc_info()[1].code return self.run(setup) else: return self.run(master_setup) def usage(self): """ Get the short usage message. """ if self._usage is None: sio = StringIO() self.parser.print_usage(file=sio) usage = self._ws_re.sub(' ', sio.getvalue()).strip()[7:] doc = self._ws_re.sub(' ', getattr(self, "__doc__") or "").strip() if not doc: self._usage = usage else: self._usage = "%s - %s" % (usage, doc) return self._usage def run(self, setup): """ Run the command. :param setup: A namespace giving the options for this command. This must be used instead of :attr:`Bcfg2.Options.setup` because this command may have been called from an interactive :class:`cmd.Cmd` shell, and thus has its own option parser and its own (private) namespace. ``setup`` is guaranteed to contain all of the options in the global :attr:`Bcfg2.Options.setup` namespace, in addition to any local options given to this command from the interactive shell. :type setup: argparse.Namespace """ raise NotImplementedError # pragma: nocover def shutdown(self): """ Perform any necessary shutdown tasks for this command This is called to when the program exits (*not* when this command is finished executing). """ pass # pragma: nocover
class Subcommand(object): """ Base class for subcommands. This must be subclassed to create commands. Specifically, you must override :func:`Bcfg2.Options.Subcommand.run`. You may want to override: * The docstring, which will be used as the short help. * :attr:`Bcfg2.Options.Subcommand.options` * :attr:`Bcfg2.Options.Subcommand.help` * :attr:`Bcfg2.Options.Subcommand.interactive` * * :func:`Bcfg2.Options.Subcommand.shutdown` You should not need to override :func:`Bcfg2.Options.Subcommand.__call__` or :func:`Bcfg2.Options.Subcommand.usage`. A ``Subcommand`` subclass constructor must not take any arguments. """ #: Options this command takes options = [] #: Longer help message help = None #: Whether or not to expose this command in an interactive #: :class:`cmd.Cmd` shell, if one is used. (``bcfg2-info`` uses #: one, ``bcfg2-admin`` does not.) interactive = True #: Whether or not to expose this command as command line parameter #: or only in an interactive :class:`cmd.Cmd` shell. only_interactive = False #: Additional aliases for the command. The contents of the list gets #: added to the default command name (the lowercased class name) aliases = [] _ws_re = re.compile(r'\s+', flags=re.MULTILINE) def __init__(self): self.core = None description = "%s: %s" % (self.__class__.__name__.lower(), self.__class__.__doc__) #: The :class:`Bcfg2.Options.Parser` that will be used to #: parse options if this subcommand is called from an #: interactive :class:`cmd.Cmd` shell. self.parser = Parser(prog=self.__class__.__name__.lower(), description=description, components=[self], add_base_options=False, epilog=self.help) self._usage = None #: A :class:`logging.Logger` that can be used to produce #: logging output for this command. self.logger = logging.getLogger(self.__class__.__name__.lower()) def __call__(self, args=None): """ Perform option parsing and other tasks necessary to support running ``Subcommand`` objects as part of a :class:`cmd.Cmd` shell. You should not need to override ``__call__``. :param args: Arguments given in the interactive shell :type args: list of strings :returns: The return value of :func:`Bcfg2.Options.Subcommand.run` """ if args is not None: self.parser.namespace = copy.copy(master_setup) self.parser.parsed = False alist = shlex.split(args) try: setup = self.parser.parse(alist) except SystemExit: return sys.exc_info()[1].code return self.run(setup) else: return self.run(master_setup) def usage(self): """ Get the short usage message. """ if self._usage is None: sio = StringIO() self.parser.print_usage(file=sio) usage = self._ws_re.sub(' ', sio.getvalue()).strip()[7:] doc = self._ws_re.sub(' ', getattr(self, "__doc__") or "").strip() if not doc: self._usage = usage else: self._usage = "%s - %s" % (usage, doc) return self._usage def run(self, setup): """ Run the command. :param setup: A namespace giving the options for this command. This must be used instead of :attr:`Bcfg2.Options.setup` because this command may have been called from an interactive :class:`cmd.Cmd` shell, and thus has its own option parser and its own (private) namespace. ``setup`` is guaranteed to contain all of the options in the global :attr:`Bcfg2.Options.setup` namespace, in addition to any local options given to this command from the interactive shell. :type setup: argparse.Namespace """ raise NotImplementedError # pragma: nocover def shutdown(self): """ Perform any necessary shutdown tasks for this command This is called to when the program exits (*not* when this command is finished executing). """ pass # pragma: nocover