Doc updates for API changes.
Clean up docstrings. Bump version to 1.0. Change-Id: I1047c637ffed4ffac8bffbdaa1bddc56895716d9
This commit is contained in:
parent
9bb0a4a13a
commit
83469ad81a
12
announce.rst
12
announce.rst
|
@ -11,9 +11,15 @@ other extensions.
|
||||||
What's New In This Release?
|
What's New In This Release?
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
- Clean up interactive mode flag settting.
|
- Add trailing newlines after output from tablib-based formatters
|
||||||
- Add support for Python 2.6, contributed by heavenshell.
|
(JSON, YAML, and HTML). Contributed by Matt Joyce.
|
||||||
- Fix multi-word commands in interactive mode.
|
- Some PEP-8 fixes.
|
||||||
|
- Refactor the API in ``Command`` to add ``take_action()``
|
||||||
|
and make ``run()`` a concrete method. Existing users should only
|
||||||
|
need to rename ``run()`` to ``take_action()`` since the function
|
||||||
|
signatures have not changed.
|
||||||
|
- In ``Lister`` and ``ShowOne`` use ``take_action()`` instead of
|
||||||
|
``get_data()``.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -143,7 +143,11 @@ class App(object):
|
||||||
self.interactive_mode = not remainder
|
self.interactive_mode = not remainder
|
||||||
self.initialize_app(remainder)
|
self.initialize_app(remainder)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if self.options.debug:
|
if hasattr(self, 'options'):
|
||||||
|
debug = self.options.debug
|
||||||
|
else:
|
||||||
|
debug = True
|
||||||
|
if debug:
|
||||||
LOG.exception(err)
|
LOG.exception(err)
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Command(object):
|
||||||
return inspect.getdoc(self.__class__) or ''
|
return inspect.getdoc(self.__class__) or ''
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
"""Return an argparse.ArgumentParser.
|
"""Return an :class:`argparse.ArgumentParser`.
|
||||||
"""
|
"""
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=self.get_description(),
|
description=self.get_description(),
|
||||||
|
@ -33,12 +33,18 @@ class Command(object):
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
"""Return a two-part tuple with a tuple of column names
|
"""Override to do something useful.
|
||||||
and a tuple of values.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def run(self, parsed_args):
|
def run(self, parsed_args):
|
||||||
"""Do something useful.
|
"""Invoked by the application when the command is run.
|
||||||
|
|
||||||
|
Developers implementing commands should override
|
||||||
|
:meth:`take_action`.
|
||||||
|
|
||||||
|
Developers creating new command base classes (such as
|
||||||
|
:class:`Lister` and :class:`ShowOne`) should override this
|
||||||
|
method to wrap :meth:`take_action`.
|
||||||
"""
|
"""
|
||||||
self.take_action(parsed_args)
|
self.take_action(parsed_args)
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .command import Command
|
from .command import Command
|
||||||
|
@ -12,13 +13,22 @@ class HelpAction(argparse.Action):
|
||||||
instance, passed in as the "default" value for the action.
|
instance, passed in as the "default" value for the action.
|
||||||
"""
|
"""
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
app = self.default
|
app = self.default
|
||||||
parser.print_help(app.stdout)
|
parser.print_help(app.stdout)
|
||||||
app.stdout.write('\nCommands:\n')
|
app.stdout.write('\nCommands:\n')
|
||||||
command_manager = app.command_manager
|
command_manager = app.command_manager
|
||||||
for name, ep in sorted(command_manager):
|
for name, ep in sorted(command_manager):
|
||||||
factory = ep.load()
|
try:
|
||||||
cmd = factory(self, None)
|
factory = ep.load()
|
||||||
|
except Exception as err:
|
||||||
|
app.stdout.write('Could not load %r\n' % ep)
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
cmd = factory(self, None)
|
||||||
|
except Exception as err:
|
||||||
|
app.stdout.write('Could not instantiate %r: %s\n' % (ep, err))
|
||||||
|
continue
|
||||||
one_liner = cmd.get_description().split('\n')[0]
|
one_liner = cmd.get_description().split('\n')[0]
|
||||||
app.stdout.write(' %-13s %s\n' % (name, one_liner))
|
app.stdout.write(' %-13s %s\n' % (name, one_liner))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Simple(Command):
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def run(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
self.log.info('sending greeting')
|
self.log.info('sending greeting')
|
||||||
self.log.debug('debugging')
|
self.log.debug('debugging')
|
||||||
self.app.stdout.write('hi!\n')
|
self.app.stdout.write('hi!\n')
|
||||||
|
@ -19,6 +19,6 @@ class Error(Command):
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def run(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
self.log.info('causing error')
|
self.log.info('causing error')
|
||||||
raise RuntimeError('this is the expected exception')
|
raise RuntimeError('this is the expected exception')
|
||||||
|
|
|
@ -48,7 +48,7 @@ copyright = u'2012, Doug Hellmann'
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.7'
|
version = '1.0'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = version
|
release = version
|
||||||
|
|
||||||
|
|
|
@ -155,19 +155,25 @@ features of cliff.
|
||||||
causing error
|
causing error
|
||||||
this is the expected exception
|
this is the expected exception
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File ".../cliff/app.py", line 148, in run
|
File ".../cliff/app.py", line 218, in run_subcommand
|
||||||
result = cmd.run(parsed_args)
|
result = cmd.run(parsed_args)
|
||||||
File ".../demoapp/cliffdemo/simple.py", line 24, in run
|
File ".../cliff/command.py", line 43, in run
|
||||||
|
self.take_action(parsed_args)
|
||||||
|
File ".../demoapp/cliffdemo/simple.py", line 24, in take_action
|
||||||
raise RuntimeError('this is the expected exception')
|
raise RuntimeError('this is the expected exception')
|
||||||
RuntimeError: this is the expected exception
|
RuntimeError: this is the expected exception
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File "/Users/dhellmann/Envs/cliff/bin/cliffdemo", line 9, in <module>
|
File "/Users/dhellmann/Envs/cliff/bin/cliffdemo", line 9, in <module>
|
||||||
load_entry_point('cliffdemo==0.1', 'console_scripts', 'cliffdemo')()
|
load_entry_point('cliffdemo==0.1', 'console_scripts', 'cliffdemo')()
|
||||||
File ".../demoapp/cliffdemo/main.py", line 30, in main
|
File ".../demoapp/cliffdemo/main.py", line 33, in main
|
||||||
return myapp.run(argv)
|
return myapp.run(argv)
|
||||||
File ".../cliff/app.py", line 148, in run
|
File ".../cliff/app.py", line 160, in run
|
||||||
|
result = self.run_subcommand(remainder)
|
||||||
|
File ".../cliff/app.py", line 218, in run_subcommand
|
||||||
result = cmd.run(parsed_args)
|
result = cmd.run(parsed_args)
|
||||||
File ".../demoapp/cliffdemo/simple.py", line 24, in run
|
File ".../cliff/command.py", line 43, in run
|
||||||
|
self.take_action(parsed_args)
|
||||||
|
File ".../demoapp/cliffdemo/simple.py", line 24, in take_action
|
||||||
raise RuntimeError('this is the expected exception')
|
raise RuntimeError('this is the expected exception')
|
||||||
RuntimeError: this is the expected exception
|
RuntimeError: this is the expected exception
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,17 @@
|
||||||
Release History
|
Release History
|
||||||
=================
|
=================
|
||||||
|
|
||||||
dev
|
1.0
|
||||||
|
|
||||||
- Add trailing newlines after output from tablib-based formatters
|
- Add trailing newlines after output from tablib-based formatters
|
||||||
(JSON, YAML, and HTML). Contributed by Matt Joyce.
|
(JSON, YAML, and HTML). Contributed by Matt Joyce.
|
||||||
- Some :pep:`8` fixes.
|
- Some :pep:`8` fixes.
|
||||||
|
- Refactor the API in :class:`Command` to add :func:`take_action`
|
||||||
|
and make :func:`run` a concrete method. Existing users should only
|
||||||
|
need to rename :func:`run()` to :func:`take_action()` since the
|
||||||
|
function signatures have not changed.
|
||||||
|
- In :class:`Lister` and :class:`ShowOne` use :func:`take_action`
|
||||||
|
instead of :func:`get_data`.
|
||||||
|
|
||||||
0.7
|
0.7
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ discover the command plugins and invoke them, and to provide runtime
|
||||||
support for those plugins. Each :class:`Command` subclass is
|
support for those plugins. Each :class:`Command` subclass is
|
||||||
responsible for taking action based on instructions from the user. It
|
responsible for taking action based on instructions from the user. It
|
||||||
defines its own local argument parser (usually using argparse_) and a
|
defines its own local argument parser (usually using argparse_) and a
|
||||||
:func:`run` method that does the appropriate work.
|
:func:`take_action` method that does the appropriate work.
|
||||||
|
|
||||||
The Interactive Application
|
The Interactive Application
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
@ -12,12 +12,12 @@ Lister
|
||||||
======
|
======
|
||||||
|
|
||||||
The :class:`cliff.lister.Lister` base class API extends
|
The :class:`cliff.lister.Lister` base class API extends
|
||||||
:class:`Command` to add a :func:`get_data` method. Subclasses should
|
:class:`Command` to allow :func:`take_action` to return data to be
|
||||||
provide a :func:`get_data` implementation that returns a two member
|
formatted using a user-selectable formatter. Subclasses should provide
|
||||||
tuple containing a tuple with the names of the columns in the dataset
|
a :func:`take_action` implementation that returns a two member tuple
|
||||||
and an iterable that will yield the data to be output. See the
|
containing a tuple with the names of the columns in the dataset and an
|
||||||
description of :ref:`the files command in the demoapp <demoapp-list>`
|
iterable that will yield the data to be output. See the description of
|
||||||
for details.
|
:ref:`the files command in the demoapp <demoapp-list>` for details.
|
||||||
|
|
||||||
List Output Formatters
|
List Output Formatters
|
||||||
======================
|
======================
|
||||||
|
|
|
@ -12,10 +12,11 @@ ShowOne
|
||||||
=======
|
=======
|
||||||
|
|
||||||
The :class:`cliff.show.ShowOne` base class API extends
|
The :class:`cliff.show.ShowOne` base class API extends
|
||||||
:class:`Command` to add a :func:`get_data` method. Subclasses should
|
:class:`Command` to allow :func:`take_action` to return data to be
|
||||||
provide a :func:`get_data` implementation that returns a two member
|
formatted using a user-selectable formatter. Subclasses should provide
|
||||||
tuple containing a tuple with the names of the columns in the dataset
|
a :func:`take_action` implementation that returns a two member tuple
|
||||||
and an iterable that contains the data values associated with those
|
containing a tuple with the names of the columns in the dataset and an
|
||||||
|
iterable that contains the data values associated with those
|
||||||
names. See the description of :ref:`the file command in the demoapp
|
names. See the description of :ref:`the file command in the demoapp
|
||||||
<demoapp-show>` for details.
|
<demoapp-show>` for details.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue