python-openstackclient/doc/source/contributor/command-wrappers.rst
Doug Hellmann 9599ffe65d reorganize existing documentation according to the new standard layout
Move existing content around based on the doc-migration specification.

Replace :doc: markup with :ref: to have sphinx keep track of where the
files move and generate valid hyperlinks.

Add a few toctrees and index pages for the new directories.

Depends-On: Ia750cb049c0f53a234ea70ce1f2bbbb7a2aa9454
Change-Id: I253ee8f89d3ec40e39310c18bb87ed1d3d5de330
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
2017-06-23 11:54:32 +02:00

2.0 KiB

Command Class Wrappers

When we want to deprecate a command, policy says we need to alert the user. We do this with a message logged at WARNING level before any command output is emitted.

OpenStackClient command classes are derived from the cliff classes. Cliff uses setuptools entry points for dispatching the parsed command to the respective handler classes. This lends itself to modifying the command execution at run-time.

The obvious approach to adding the deprecation message would be to just add the message to the command class take_action() method directly. But then the various deprecations are scattered throughout the code base. If we instead wrap the deprecated command class with a new class we can put all of the wrappers into a separate, dedicated module. This also lets us leave the original class unmodified and puts all of the deprecation bits in one place.

This is an example of a minimal wrapper around a command class that logs a deprecation message as a warning to the user then calls the original class.

  • Subclass the deprecated command.
  • Set class attribute deprecated to True to signal cliff to not emit help text for this command.
  • Log the deprecation message at WARNING level and refer to the replacement for the deprecated command in the log warning message.
  • Change the entry point class in setup.cfg to point to the new class.

Example Deprecation Class

class ListFooOld(ListFoo):
    """List resources"""

    # This notifies cliff to not display the help for this command
    deprecated = True

    log = logging.getLogger('deprecated')

    def take_action(self, parsed_args):
        self.log.warning(
            "%s is deprecated, use 'foobar list'",
            getattr(self, 'cmd_name', 'this command'),
        )
        return super(ListFooOld, self).take_action(parsed_args)