summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore32
-rw-r--r--.gitreview4
-rw-r--r--.travis.yml8
-rw-r--r--CONTRIBUTING.rst10
-rw-r--r--LICENSE202
-rw-r--r--MANIFEST.in6
-rw-r--r--Makefile21
-rw-r--r--README.rst12
-rw-r--r--announce.rst37
-rw-r--r--cliff/__init__.py0
-rw-r--r--cliff/app.py305
-rw-r--r--cliff/command.py50
-rw-r--r--cliff/commandmanager.py71
-rw-r--r--cliff/complete.py190
-rw-r--r--cliff/display.py82
-rw-r--r--cliff/formatters/__init__.py0
-rw-r--r--cliff/formatters/base.py48
-rw-r--r--cliff/formatters/commaseparated.py35
-rw-r--r--cliff/formatters/shell.py38
-rw-r--r--cliff/formatters/table.py64
-rw-r--r--cliff/help.py80
-rw-r--r--cliff/interactive.py115
-rw-r--r--cliff/lister.py66
-rw-r--r--cliff/show.py55
-rw-r--r--cliff/tests/__init__.py0
-rw-r--r--cliff/tests/test_app.py389
-rw-r--r--cliff/tests/test_command.py22
-rw-r--r--cliff/tests/test_commandmanager.py121
-rw-r--r--cliff/tests/test_complete.py130
-rw-r--r--cliff/tests/test_help.py116
-rw-r--r--cliff/tests/test_lister.py55
-rw-r--r--cliff/tests/test_show.py54
-rw-r--r--demoapp/README.rst64
-rw-r--r--demoapp/cliffdemo/__init__.py0
-rw-r--r--demoapp/cliffdemo/encoding.py23
-rw-r--r--demoapp/cliffdemo/list.py18
-rw-r--r--demoapp/cliffdemo/main.py37
-rw-r--r--demoapp/cliffdemo/show.py31
-rw-r--r--demoapp/cliffdemo/simple.py24
-rw-r--r--demoapp/setup.py67
-rw-r--r--docs/Makefile153
-rw-r--r--docs/requirements.txt2
-rw-r--r--docs/source/classes.rst63
-rw-r--r--docs/source/complete.rst45
-rw-r--r--docs/source/conf.py251
-rw-r--r--docs/source/demoapp.rst258
-rw-r--r--docs/source/developers.rst83
-rw-r--r--docs/source/history.rst163
-rw-r--r--docs/source/index.rst33
-rw-r--r--docs/source/install.rst51
-rw-r--r--docs/source/interactive_mode.rst94
-rw-r--r--docs/source/introduction.rst64
-rw-r--r--docs/source/list_commands.rst83
-rw-r--r--docs/source/show_commands.rst89
-rw-r--r--setup.py184
-rw-r--r--test-requirements.txt7
-rw-r--r--tox.ini17
57 files changed, 8 insertions, 4314 deletions
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 8a4d01b..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-*.py[co]
-
-# Packages
-*.egg
-*.egg-info
-dist
-build
-eggs
-parts
-bin
-var
-sdist
-develop-eggs
-.installed.cfg
-.venv
-
-# Installer logs
-pip-log.txt
-
-# Unit test / coverage reports
-.coverage
-.tox
-
-#Translations
-*.mo
-
-#Mr Developer
-.mr.developer.cfg
-
-#sample output
-*.log
-*.log.*
diff --git a/.gitreview b/.gitreview
deleted file mode 100644
index 212f062..0000000
--- a/.gitreview
+++ /dev/null
@@ -1,4 +0,0 @@
-[gerrit]
-host=review.openstack.org
-port=29418
-project=stackforge/cliff.git
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index ea35c0e..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: python
-python:
- - 2.7
- - 3.2
- - 3.3
- - pypy
-install: pip install -r test-requirements.txt
-script: nosetests -d \ No newline at end of file
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
deleted file mode 100644
index 3ba612b..0000000
--- a/CONTRIBUTING.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Changes to cliff should be submitted for review via the Gerrit tool,
-following the workflow documented at:
-
- http://wiki.openstack.org/GerritWorkflow
-
-Pull requests submitted through GitHub will be ignored.
-
-Bugs should be filed on Launchpad, not GitHub:
-
- https://bugs.launchpad.net/python-cliff
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index bb56f02..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,6 +0,0 @@
-include setup.py
-recursive-include docs *.rst *.py *.html *.css *.js *.png *.txt
-recursive-include demoapp *.py
-recursive-include tests *.py
-include tox.ini
-
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 65c420d..0000000
--- a/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-help:
- @echo "release - package and upload a release"
- @echo "sdist - package"
- @echo "docs - generate HTML documentation"
- @echo "clean - remove build artifacts"
-
-release: docs
- rm -rf dist build
- python setup.py sdist upload
-
-sdist: docs
- python setup.py sdist
- ls -l dist
-
-clean:
- rm -rf dist build *.egg-info
- (cd docs && make clean)
-
-.PHONY: docs
-docs:
- (cd docs && make clean html)
diff --git a/README.rst b/README.rst
index 567a259..3f90655 100644
--- a/README.rst
+++ b/README.rst
@@ -2,11 +2,15 @@
cliff -- Command Line Interface Formulation Framework
=======================================================
+cliff is now part of the OpenStack Oslo program.
+
cliff is a framework for building command line programs. It uses
-setuptools entry points to provide subcommands, output formatters, and
+`setuptools entry points`_ to provide subcommands, output formatters, and
other extensions.
-Documentation
-=============
+.. _setuptools entry points: http://pythonhosted.org/setuptools/pkg_resources.html#convenience-api
-Documentation for cliff is hosted on readthedocs.org at http://readthedocs.org/docs/cliff/en/latest/
+* Free software: Apache license
+* Documentation: http://docs.openstack.org/developer/cliff
+* Source: http://git.openstack.org/cgit/openstack/cliff
+* Bugs: https://bugs.launchpad.net/python-cliff
diff --git a/announce.rst b/announce.rst
deleted file mode 100644
index 09e57f8..0000000
--- a/announce.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-========================================================================
- cliff -- Command Line Interface Formulation Framework -- version 1.4.5
-========================================================================
-
-.. tags:: python cliff release DreamHost
-
-cliff is a framework for building command line programs. It uses
-setuptools entry points to provide subcommands, output formatters, and
-other extensions.
-
-What's New In This Release?
-===========================
-
-- Update the pyparsing dependency to a version that supports both
- Python 2 and Python 3.
-- Add PyPy testing.
-
-Documentation
-=============
-
-`Documentation for cliff`_ is hosted on `readthedocs.org`_
-
-.. _Documentation for cliff: http://readthedocs.org/docs/cliff/en/latest/
-
-.. _readthedocs.org: http://readthedocs.org
-
-Installation
-============
-
-Use pip::
-
- $ pip install cliff
-
-See `the installation guide`_ for more details.
-
-.. _the installation guide: http://cliff.readthedocs.org/en/latest/install.html
-
diff --git a/cliff/__init__.py b/cliff/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/cliff/__init__.py
+++ /dev/null
diff --git a/cliff/app.py b/cliff/app.py
deleted file mode 100644
index 4a93801..0000000
--- a/cliff/app.py
+++ /dev/null
@@ -1,305 +0,0 @@
-"""Application base class.
-"""
-
-import argparse
-import codecs
-import locale
-import logging
-import logging.handlers
-import os
-import sys
-
-from .complete import CompleteCommand
-from .help import HelpAction, HelpCommand
-from .interactive import InteractiveApp
-
-# Make sure the cliff library has a logging handler
-# in case the app developer doesn't set up logging.
-# For py26 compat, create a NullHandler
-
-if hasattr(logging, 'NullHandler'):
- NullHandler = logging.NullHandler
-else:
- class NullHandler(logging.Handler):
- def handle(self, record):
- pass
-
- def emit(self, record):
- pass
-
- def createLock(self):
- self.lock = None
-
-logging.getLogger('cliff').addHandler(NullHandler())
-
-
-LOG = logging.getLogger(__name__)
-
-
-class App(object):
- """Application base class.
-
- :param description: one-liner explaining the program purpose
- :paramtype description: str
- :param version: application version number
- :paramtype version: str
- :param command_manager: plugin loader
- :paramtype command_manager: cliff.commandmanager.CommandManager
- :param stdin: Standard input stream
- :paramtype stdin: readable I/O stream
- :param stdout: Standard output stream
- :paramtype stdout: writable I/O stream
- :param stderr: Standard error output stream
- :paramtype stderr: writable I/O stream
- :param interactive_app_factory: callable to create an
- interactive application
- :paramtype interactive_app_factory: cliff.interactive.InteractiveApp
- """
-
- NAME = os.path.splitext(os.path.basename(sys.argv[0]))[0]
-
- CONSOLE_MESSAGE_FORMAT = '%(message)s'
- LOG_FILE_MESSAGE_FORMAT = \
- '[%(asctime)s] %(levelname)-8s %(name)s %(message)s'
- DEFAULT_VERBOSE_LEVEL = 1
- DEFAULT_OUTPUT_ENCODING = 'utf-8'
-
- def __init__(self, description, version, command_manager,
- stdin=None, stdout=None, stderr=None,
- interactive_app_factory=InteractiveApp):
- """Initialize the application.
- """
- self.command_manager = command_manager
- self.command_manager.add_command('help', HelpCommand)
- self.command_manager.add_command('complete', CompleteCommand)
- self._set_streams(stdin, stdout, stderr)
- self.interactive_app_factory = interactive_app_factory
- self.parser = self.build_option_parser(description, version)
- self.interactive_mode = False
- self.interpreter = None
-
- def _set_streams(self, stdin, stdout, stderr):
- locale.setlocale(locale.LC_ALL, '')
- if sys.version_info[:2] == (2, 6):
- # Configure the input and output streams. If a stream is
- # provided, it must be configured correctly by the
- # caller. If not, make sure the versions of the standard
- # streams used by default are wrapped with encodings. This
- # works around a problem with Python 2.6 fixed in 2.7 and
- # later (http://hg.python.org/cpython/rev/e60ef17561dc/).
- lang, encoding = locale.getdefaultlocale()
- encoding = (getattr(sys.stdout, 'encoding', None)
- or encoding
- or self.DEFAULT_OUTPUT_ENCODING
- )
- self.stdin = stdin or codecs.getreader(encoding)(sys.stdin)
- self.stdout = stdout or codecs.getwriter(encoding)(sys.stdout)
- self.stderr = stderr or codecs.getwriter(encoding)(sys.stderr)
- else:
- self.stdin = stdin or sys.stdin
- self.stdout = stdout or sys.stdout
- self.stderr = stderr or sys.stderr
-
- def build_option_parser(self, description, version,
- argparse_kwargs=None):
- """Return an argparse option parser for this application.
-
- Subclasses may override this method to extend
- the parser with more global options.
-
- :param description: full description of the application
- :paramtype description: str
- :param version: version number for the application
- :paramtype version: str
- :param argparse_kwargs: extra keyword argument passed to the
- ArgumentParser constructor
- :paramtype extra_kwargs: dict
- """
- argparse_kwargs = argparse_kwargs or {}
- parser = argparse.ArgumentParser(
- description=description,
- add_help=False,
- **argparse_kwargs
- )
- parser.add_argument(
- '--version',
- action='version',
- version='%(prog)s {0}'.format(version),
- )
- parser.add_argument(
- '-v', '--verbose',
- action='count',
- dest='verbose_level',
- default=self.DEFAULT_VERBOSE_LEVEL,
- help='Increase verbosity of output. Can be repeated.',
- )
- parser.add_argument(
- '--log-file',
- action='store',
- default=None,
- help='Specify a file to log output. Disabled by default.',
- )
- parser.add_argument(
- '-q', '--quiet',
- action='store_const',
- dest='verbose_level',
- const=0,
- help='suppress output except warnings and errors',
- )
- parser.add_argument(
- '-h', '--help',
- action=HelpAction,
- nargs=0,
- default=self, # tricky
- help="show this help message and exit",
- )
- parser.add_argument(
- '--debug',
- default=False,
- action='store_true',
- help='show tracebacks on errors',
- )
- return parser
-
- def configure_logging(self):
- """Create logging handlers for any log output.
- """
- root_logger = logging.getLogger('')
- root_logger.setLevel(logging.DEBUG)
-
- # Set up logging to a file
- if self.options.log_file:
- file_handler = logging.FileHandler(
- filename=self.options.log_file,
- )
- formatter = logging.Formatter(self.LOG_FILE_MESSAGE_FORMAT)
- file_handler.setFormatter(formatter)
- root_logger.addHandler(file_handler)
-
- # Always send higher-level messages to the console via stderr
- console = logging.StreamHandler(self.stderr)
- console_level = {0: logging.WARNING,
- 1: logging.INFO,
- 2: logging.DEBUG,
- }.get(self.options.verbose_level, logging.DEBUG)
- console.setLevel(console_level)
- formatter = logging.Formatter(self.CONSOLE_MESSAGE_FORMAT)
- console.setFormatter(formatter)
- root_logger.addHandler(console)
- return
-
- def run(self, argv):
- """Equivalent to the main program for the application.
-
- :param argv: input arguments and options
- :paramtype argv: list of str
- """
- try:
- self.options, remainder = self.parser.parse_known_args(argv)
- self.configure_logging()
- self.interactive_mode = not remainder
- self.initialize_app(remainder)
- except Exception as err:
- if hasattr(self, 'options'):
- debug = self.options.debug
- else:
- debug = True
- if debug:
- LOG.exception(err)
- raise
- else:
- LOG.error(err)
- return 1
- result = 1
- if self.interactive_mode:
- result = self.interact()
- else:
- result = self.run_subcommand(remainder)
- return result
-
- # FIXME(dhellmann): Consider moving these command handling methods
- # to a separate class.
- def initialize_app(self, argv):
- """Hook for subclasses to take global initialization action
- after the arguments are parsed but before a command is run.
- Invoked only once, even in interactive mode.
-
- :param argv: List of arguments, including the subcommand to run.
- Empty for interactive mode.
- """
- return
-
- def prepare_to_run_command(self, cmd):
- """Perform any preliminary work needed to run a command.
-
- :param cmd: command processor being invoked
- :paramtype cmd: cliff.command.Command
- """
- return
-
- def clean_up(self, cmd, result, err):
- """Hook run after a command is done to shutdown the app.
-
- :param cmd: command processor being invoked
- :paramtype cmd: cliff.command.Command
- :param result: return value of cmd
- :paramtype result: int
- :param err: exception or None
- :paramtype err: Exception
- """
- return
-
- def interact(self):
- self.interpreter = self.interactive_app_factory(self,
- self.command_manager,
- self.stdin,
- self.stdout,
- )
- self.interpreter.cmdloop()
- return 0
-
- def run_subcommand(self, argv):
- try:
- subcommand = self.command_manager.find_command(argv)
- except ValueError as err:
- if self.options.debug:
- raise
- else:
- LOG.error(err)
- return 2
- cmd_factory, cmd_name, sub_argv = subcommand
- cmd = cmd_factory(self, self.options)
- err = None
- result = 1
- try:
- self.prepare_to_run_command(cmd)
- full_name = (cmd_name
- if self.interactive_mode
- else ' '.join([self.NAME, cmd_name])
- )
- cmd_parser = cmd.get_parser(full_name)
- parsed_args = cmd_parser.parse_args(sub_argv)
- result = cmd.run(parsed_args)
- except Exception as err:
- if self.options.debug:
- LOG.exception(err)
- else:
- LOG.error(err)
- try:
- self.clean_up(cmd, result, err)
- except Exception as err2:
- if self.options.debug:
- LOG.exception(err2)
- else:
- LOG.error('Could not clean up: %s', err2)
- if self.options.debug:
- raise
- else:
- try:
- self.clean_up(cmd, result, None)
- except Exception as err3:
- if self.options.debug:
- LOG.exception(err3)
- else:
- LOG.error('Could not clean up: %s', err3)
- return result
diff --git a/cliff/command.py b/cliff/command.py
deleted file mode 100644
index 116ae5c..0000000
--- a/cliff/command.py
+++ /dev/null
@@ -1,50 +0,0 @@
-
-import abc
-import argparse
-import inspect
-
-
-class Command(object):
- """Base class for command plugins.
-
- :param app: Application instance invoking the command.
- :paramtype app: cliff.app.App
- """
- __metaclass__ = abc.ABCMeta
-
- def __init__(self, app, app_args):
- self.app = app
- self.app_args = app_args
- return
-
- def get_description(self):
- """Return the command description.
- """
- return inspect.getdoc(self.__class__) or ''
-
- def get_parser(self, prog_name):
- """Return an :class:`argparse.ArgumentParser`.
- """
- parser = argparse.ArgumentParser(
- description=self.get_description(),
- prog=prog_name,
- )
- return parser
-
- @abc.abstractmethod
- def take_action(self, parsed_args):
- """Override to do something useful.
- """
-
- def run(self, parsed_args):
- """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)
- return 0
diff --git a/cliff/commandmanager.py b/cliff/commandmanager.py
deleted file mode 100644
index 2f83eb2..0000000
--- a/cliff/commandmanager.py
+++ /dev/null
@@ -1,71 +0,0 @@
-"""Discover and lookup command plugins.
-"""
-
-import logging
-
-import pkg_resources
-
-
-LOG = logging.getLogger(__name__)
-
-
-class EntryPointWrapper(object):
- """Wrap up a command class already imported to make it look like a plugin.
- """
-
- def __init__(self, name, command_class):
- self.name = name
- self.command_class = command_class
-
- def load(self):
- return self.command_class
-
-
-class CommandManager(object):
- """Discovers commands and handles lookup based on argv data.
-
- :param namespace: String containing the setuptools entrypoint namespace
- for the plugins to be loaded. For example,
- ``'cliff.formatter.list'``.
- :param convert_underscores: Whether cliff should convert underscores to
- to spaces in entry_point commands.
- """
- def __init__(self, namespace, convert_underscores=True):
- self.commands = {}
- self.namespace = namespace
- self.convert_underscores = convert_underscores
- self._load_commands()
-
- def _load_commands(self):
- for ep in pkg_resources.iter_entry_points(self.namespace):
- LOG.debug('found command %r', ep.name)
- cmd_name = (ep.name.replace('_', ' ')
- if self.convert_underscores
- else ep.name)
- self.commands[cmd_name] = ep
- return
-
- def __iter__(self):
- return iter(self.commands.items())
-
- def add_command(self, name, command_class):
- self.commands[name] = EntryPointWrapper(name, command_class)
-
- def find_command(self, argv):
- """Given an argument list, find a command and
- return the processor and any remaining arguments.
- """
- search_args = argv[:]
- name = ''
- while search_args:
- if search_args[0].startswith('-'):
- raise ValueError('Invalid command %r' % search_args[0])
- next_val = search_args.pop(0)
- name = '%s %s' % (name, next_val) if name else next_val
- if name in self.commands:
- cmd_ep = self.commands[name]
- cmd_factory = cmd_ep.load()
- return (cmd_factory, name, search_args)
- else:
- raise ValueError('Unknown command %r' %
- (argv,))
diff --git a/cliff/complete.py b/cliff/complete.py
deleted file mode 100644
index fa1dd5c..0000000
--- a/cliff/complete.py
+++ /dev/null
@@ -1,190 +0,0 @@
-
-"""Bash completion for the CLI.
-"""
-
-import logging
-
-import six
-import stevedore
-
-from cliff import command
-
-
-class CompleteDictionary:
- """dictionary for bash completion
- """
-
- def __init__(self):
- self._dictionary = {}
-
- def add_command(self, command, actions):
- optstr = ' '.join(opt for action in actions
- for opt in action.option_strings)
- dicto = self._dictionary
- for subcmd in command[:-1]:
- dicto = dicto.setdefault(subcmd, {})
- dicto[command[-1]] = optstr
-
- def get_commands(self):
- return ' '.join(k for k in sorted(self._dictionary.keys()))
-
- def _get_data_recurse(self, dictionary, path):
- ray = []
- keys = sorted(dictionary.keys())
- for cmd in keys:
- name = path + "_" + cmd if path else cmd
- value = dictionary[cmd]
- if isinstance(value, six.string_types):
- ray.append((name, value))
- else:
- cmdlist = ' '.join(sorted(value.keys()))
- ray.append((name, cmdlist))
- ray += self._get_data_recurse(value, name)
- return ray
-
- def get_data(self):
- return sorted(self._get_data_recurse(self._dictionary, ""))
-
-
-class CompleteShellBase(object):
- """base class for bash completion generation
- """
- def __init__(self, name, output):
- self.name = str(name)
- self.output = output
-
- def write(self, cmdo, data):
- self.output.write(self.get_header())
- self.output.write(" cmds='{0}'\n".format(cmdo))
- for datum in data:
- self.output.write(' cmds_{0}=\'{1}\'\n'.format(*datum))
- self.output.write(self.get_trailer())
-
-
-class CompleteNoCode(CompleteShellBase):
- """completion with no code
- """
- def __init__(self, name, output):
- super(CompleteNoCode, self).__init__(name, output)
-
- def get_header(self):
- return ''
-
- def get_trailer(self):
- return ''
-
-
-class CompleteBash(CompleteShellBase):
- """completion for bash
- """
- def __init__(self, name, output):
- super(CompleteBash, self).__init__(name, output)
-
- def get_header(self):
- return ('_' + self.name + """()
-{
- local cur prev words
- COMPREPLY=()
- _get_comp_words_by_ref -n : cur prev words
-
- # Command data:
-""")
-
- def get_trailer(self):
- return ("""
- cmd=""
- words[0]=""
- completed="${cmds}"
- for var in "${words[@]:1}"
- do
- if [[ ${var} == -* ]] ; then
- break
- fi
- if [ -z "${cmd}" ] ; then
- proposed="${var}"
- else
- proposed="${cmd}_${var}"
- fi
- local i="cmds_${proposed}"
- local comp="${!i}"
- if [ -z "${comp}" ] ; then
- break
- fi
- if [[ ${comp} == -* ]] ; then
- if [[ ${cur} != -* ]] ; then
- completed=""
- break
- fi
- fi
- cmd="${proposed}"
- completed="${comp}"
- done
-
- if [ -z "${completed}" ] ; then
- COMPREPLY=( $( compgen -f -- "$cur" ) $( compgen -d -- "$cur" ) )
- else
- COMPREPLY=( $(compgen -W "${completed}" -- ${cur}) )
- fi
- return 0
-}
-complete -F _""" + self.name + ' ' + self.name + '\n')
-
-
-class CompleteCommand(command.Command):
- """print bash completion command
- """
-
- log = logging.getLogger(__name__ + '.CompleteCommand')
-
- def __init__(self, app, app_args):
- super(CompleteCommand, self).__init__(app, app_args)
- self._formatters = stevedore.ExtensionManager(
- namespace='cliff.formatter.completion',
- )
-
- def get_parser(self, prog_name):
- parser = super(CompleteCommand, self).get_parser(prog_name)
- parser.add_argument(
- "--name",
- default=None,
- metavar='<command_name>',
- help="Command name to support with command completion"
- )
- parser.add_argument(
- "--shell",
- default='bash',
- metavar='<shell>',
- choices=sorted(self._formatters.names()),
- help="Shell being used. Use none for data only (default: bash)"
- )
- return parser
-
- def get_actions(self, command):
- the_cmd = self.app.command_manager.find_command(command)
- cmd_factory, cmd_name, search_args = the_cmd
- cmd = cmd_factory(self.app, search_args)
- if self.app.interactive_mode:
- full_name = (cmd_name)
- else:
- full_name = (' '.join([self.app.NAME, cmd_name]))
- cmd_parser = cmd.get_parser(full_name)
- return cmd_parser._get_optional_actions()
-
- def take_action(self, parsed_args):
- self.log.debug('take_action(%s)' % parsed_args)
-
- name = parsed_args.name or self.app.NAME
- try:
- shell_factory = self._formatters[parsed_args.shell].plugin
- except KeyError:
- raise RuntimeError('Unknown shell syntax %r' % parsed_args.shell)
- shell = shell_factory(name, self.app.stdout)
-
- dicto = CompleteDictionary()
- for cmd in self.app.command_manager:
- command = cmd[0].split()
- dicto.add_command(command, self.get_actions(command))
-
- shell.write(dicto.get_commands(), dicto.get_data())
-
- return 0
diff --git a/cliff/display.py b/cliff/display.py
deleted file mode 100644
index edea1f3..0000000
--- a/cliff/display.py
+++ /dev/null
@@ -1,82 +0,0 @@
-"""Application base class for displaying data.
-"""
-import abc
-import logging
-
-import stevedore
-
-from .command import Command
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DisplayCommandBase(Command):
- """Command base class for displaying data about a single object.
- """
- __metaclass__ = abc.ABCMeta
-
- def __init__(self, app, app_args):
- super(DisplayCommandBase, self).__init__(app, app_args)
- self.formatters = self._load_formatter_plugins()
-
- @abc.abstractproperty
- def formatter_namespace(self):
- "String specifying the namespace to use for loading formatter plugins."
-
- @abc.abstractproperty
- def formatter_default(self):
- "String specifying the name of the default formatter."
-
- def _load_formatter_plugins(self):
- # Here so tests can override
- return stevedore.ExtensionManager(
- self.formatter_namespace,
- invoke_on_load=True,
- )
-
- def get_parser(self, prog_name):
- parser = super(DisplayCommandBase, self).get_parser(prog_name)
- formatter_group = parser.add_argument_group(
- title='output formatters',
- description='output formatter options',
- )
- formatter_choices = sorted(self.formatters.names())
- formatter_default = self.formatter_default
- if formatter_default not in formatter_choices:
- formatter_default = formatter_choices[0]
- formatter_group.add_argument(
- '-f', '--format',
- dest='formatter',
- action='store',
- choices=formatter_choices,
- default=formatter_default,
- help='the output format, defaults to %s' % formatter_default,
- )
- formatter_group.add_argument(
- '-c', '--column',
- action='append',
- default=[],
- dest='columns',
- metavar='COLUMN',
- help='specify the column(s) to include, can be repeated',
- )
- for formatter in self.formatters:
- formatter.obj.add_argument_group(parser)
- return parser
-
- @abc.abstractmethod
- def produce_output(self, parsed_args, column_names, data):
- """Use the formatter to generate the output.
-
- :param parsed_args: argparse.Namespace instance with argument values
- :param column_names: sequence of strings containing names
- of output columns
- :param data: iterable with values matching the column names
- """
-
- def run(self, parsed_args):
- self.formatter = self.formatters[parsed_args.formatter].obj
- column_names, data = self.take_action(parsed_args)
- self.produce_output(parsed_args, column_names, data)
- return 0
diff --git a/cliff/formatters/__init__.py b/cliff/formatters/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/cliff/formatters/__init__.py
+++ /dev/null
diff --git a/cliff/formatters/base.py b/cliff/formatters/base.py
deleted file mode 100644
index 43b8f17..0000000
--- a/cliff/formatters/base.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""Base classes for formatters.
-"""
-
-import abc
-
-
-class Formatter(object):
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def add_argument_group(self, parser):
- """Add any options to the argument parser.
-
- Should use our own argument group.
- """
-
-
-class ListFormatter(Formatter):
- """Base class for formatters that know how to deal with multiple objects.
- """
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def emit_list(self, column_names, data, stdout, parsed_args):
- """Format and print the list from the iterable data source.
-
- :param column_names: names of the columns
- :param data: iterable data source, one tuple per object
- with values in order of column names
- :param stdout: output stream where data should be written
- :param parsed_args: argparse namespace from our local options
- """
-
-
-class SingleFormatter(Formatter):
- """Base class for formatters that work with single objects.
- """
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def emit_one(self, column_names, data, stdout, parsed_args):
- """Format and print the values associated with the single object.
-
- :param column_names: names of the columns
- :param data: iterable data source with values in order of column names
- :param stdout: output stream where data should be written
- :param parsed_args: argparse namespace from our local options
- """
diff --git a/cliff/formatters/commaseparated.py b/cliff/formatters/commaseparated.py
deleted file mode 100644
index 1e320f3..0000000
--- a/cliff/formatters/commaseparated.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Output formatters using csv format.
-"""
-
-import csv
-
-from .base import ListFormatter
-
-
-class CSVLister(ListFormatter):
-
- QUOTE_MODES = {
- 'all': csv.QUOTE_ALL,
- 'minimal': csv.QUOTE_MINIMAL,
- 'nonnumeric': csv.QUOTE_NONNUMERIC,
- 'none': csv.QUOTE_NONE,
- }
-
- def add_argument_group(self, parser):
- group = parser.add_argument_group('CSV Formatter')
- group.add_argument(
- '--quote',
- choices=sorted(self.QUOTE_MODES.keys()),
- dest='quote_mode',
- default='nonnumeric',
- help='when to include quotes, defaults to nonnumeric',
- )
-
- def emit_list(self, column_names, data, stdout, parsed_args):
- writer = csv.writer(stdout,
- quoting=self.QUOTE_MODES[parsed_args.quote_mode],
- )
- writer.writerow(column_names)
- for row in data:
- writer.writerow(row)
- return
diff --git a/cliff/formatters/shell.py b/cliff/formatters/shell.py
deleted file mode 100644
index d1c392b..0000000
--- a/cliff/formatters/shell.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""Output formatters using shell syntax.
-"""
-
-from .base import SingleFormatter
-
-
-class ShellFormatter(SingleFormatter):
-
- def add_argument_group(self, parser):
- group = parser.add_argument_group(
- title='shell formatter',
- description='a format a UNIX shell can parse (variable="value")',
- )
- group.add_argument(
- '--variable',
- action='append',
- default=[],
- dest='variables',
- metavar='VARIABLE',
- help='specify the variable(s) to include, can be repeated',
- )
- group.add_argument(
- '--prefix',
- action='store',
- default='',
- dest='prefix',
- help='add a prefix to all variable names',
- )
-
- def emit_one(self, column_names, data, stdout, parsed_args):
- variable_names = [c.lower().replace(' ', '_')
- for c in column_names
- ]
- desired_columns = parsed_args.variables
- for name, value in zip(variable_names, data):
- if name in desired_columns or not desired_columns:
- stdout.write('%s%s="%s"\n' % (parsed_args.prefix, name, value))
- return
diff --git a/cliff/formatters/table.py b/cliff/formatters/table.py
deleted file mode 100644
index e625a25..0000000
--- a/cliff/formatters/table.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""Output formatters using prettytable.
-"""
-
-import prettytable
-
-from .base import ListFormatter, SingleFormatter
-
-
-class TableFormatter(ListFormatter, SingleFormatter):
-
- ALIGNMENTS = {
- int: 'r',
- str: 'l',
- float: 'r',
- }
- try:
- ALIGNMENTS[unicode] = 'l'
- except NameError:
- pass
-
- def add_argument_group(self, parser):
- pass
-
- def emit_list(self, column_names, data, stdout, parsed_args):
- x = prettytable.PrettyTable(
- column_names,
- print_empty=False,
- )
- x.padding_width = 1
- # Figure out the types of the columns in the
- # first row and set the alignment of the
- # output accordingly.
- data_iter = iter(data)
- try:
- first_row = next(data_iter)
- except StopIteration:
- pass
- else:
- for value, name in zip(first_row, column_names):
- alignment = self.ALIGNMENTS.get(type(value), 'l')
- x.align[name] = alignment
- # Now iterate over the data and add the rows.
- x.add_row(first_row)
- for row in data_iter:
- x.add_row(row)
- formatted = x.get_string(fields=column_names)
- stdout.write(formatted)
- stdout.write('\n')
- return
-
- def emit_one(self, column_names, data, stdout, parsed_args):
- x = prettytable.PrettyTable(field_names=('Field', 'Value'),
- print_empty=False)
- x.padding_width = 1
- # Align all columns left because the values are
- # not all the same type.
- x.align['Field'] = 'l'
- x.align['Value'] = 'l'
- for name, value in zip(column_names, data):
- x.add_row((name, value))
- formatted = x.get_string(fields=('Field', 'Value'))
- stdout.write(formatted)
- stdout.write('\n')
- return
diff --git a/cliff/help.py b/cliff/help.py
deleted file mode 100644
index 9d96111..0000000
--- a/cliff/help.py
+++ /dev/null
@@ -1,80 +0,0 @@
-import argparse
-import sys
-import traceback
-
-from .command import Command
-
-
-class HelpAction(argparse.Action):
- """Provide a custom action so the -h and --help options
- to the main app will print a list of the commands.
-
- The commands are determined by checking the CommandManager
- instance, passed in as the "default" value for the action.
- """
- def __call__(self, parser, namespace, values, option_string=None):
- app = self.default
- parser.print_help(app.stdout)
- app.stdout.write('\nCommands:\n')
- command_manager = app.command_manager
- for name, ep in sorted(command_manager):
- try:
- factory = ep.load()
- except Exception as err:
- app.stdout.write('Could not load %r\n' % ep)
- if namespace.debug:
- traceback.print_exc(file=app.stdout)
- continue
- try:
- cmd = factory(app, None)
- except Exception as err:
- app.stdout.write('Could not instantiate %r: %s\n' % (ep, err))
- if namespace.debug:
- traceback.print_exc(file=app.stdout)
- continue
- one_liner = cmd.get_description().split('\n')[0]
- app.stdout.write(' %-13s %s\n' % (name, one_liner))
- sys.exit(0)
-
-
-class HelpCommand(Command):
- """print detailed help for another command
- """
-
- def get_parser(self, prog_name):
- parser = super(HelpCommand, self).get_parser(prog_name)
- parser.add_argument('cmd',
- nargs='*',
- help='name of the command',
- )
- return parser
-
- def take_action(self, parsed_args):
- if parsed_args.cmd:
- try:
- the_cmd = self.app.command_manager.find_command(
- parsed_args.cmd,
- )
- cmd_factory, cmd_name, search_args = the_cmd
- except ValueError:
- # Did not find an exact match
- cmd = parsed_args.cmd[0]
- fuzzy_matches = [k[0] for k in self.app.command_manager
- if k[0].startswith(cmd)
- ]
- if not fuzzy_matches:
- raise
- self.app.stdout.write('Command "%s" matches:\n' % cmd)
- for fm in fuzzy_matches:
- self.app.stdout.write(' %s\n' % fm)
- return
- cmd = cmd_factory(self.app, search_args)
- full_name = (cmd_name
- if self.app.interactive_mode
- else ' '.join([self.app.NAME, cmd_name])
- )
- cmd_parser = cmd.get_parser(full_name)
- else:
- cmd_parser = self.get_parser(' '.join([self.app.NAME, 'help']))
- cmd_parser.print_help(self.app.stdout)
- return 0
diff --git a/cliff/interactive.py b/cliff/interactive.py
deleted file mode 100644
index 619c4a2..0000000
--- a/cliff/interactive.py
+++ /dev/null
@@ -1,115 +0,0 @@
-"""Application base class.
-"""
-
-import itertools
-import logging
-import logging.handlers
-import shlex
-
-import cmd2
-
-LOG = logging.getLogger(__name__)
-
-
-class InteractiveApp(cmd2.Cmd):
- """Provides "interactive mode" features.
-
- Refer to the cmd2_ and cmd_ documentation for details
- about subclassing and configuring this class.
-
- .. _cmd2: http://packages.python.org/cmd2/index.html
- .. _cmd: http://docs.python.org/library/cmd.html
-
- :param parent_app: The calling application (expected to be derived
- from :class:`cliff.main.App`).
- :param command_manager: A :class:`cliff.commandmanager.CommandManager`
- instance.
- :param stdin: Standard input stream
- :param stdout: Standard output stream
- """
-
- use_rawinput = True
- doc_header = "Shell commands (type help <topic>):"
- app_cmd_header = "Application commands (type help <topic>):"
-
- def __init__(self, parent_app, command_manager, stdin, stdout):
- self.parent_app = parent_app
- self.prompt = '(%s) ' % parent_app.NAME
- self.command_manager = command_manager
- cmd2.Cmd.__init__(self, 'tab', stdin=stdin, stdout=stdout)
-
- def default(self, line):
- # Tie in the the default command processor to
- # dispatch commands known to the command manager.
- # We send the message through our parent app,
- # since it already has the logic for executing
- # the subcommand.
- line_parts = shlex.split(line.parsed.raw)
- self.parent_app.run_subcommand(line_parts)
-
- def completedefault(self, text, line, begidx, endidx):
- # Tab-completion for commands known to the command manager.
- # Does not handle options on the commands.
- if not text:
- completions = sorted(n for n, v in self.command_manager)
- else:
- completions = sorted(n for n, v in self.command_manager
- if n.startswith(text)
- )
- return completions
-
- def help_help(self):
- # Use the command manager to get instructions for "help"
- self.default('help help')
-
- def do_help(self, arg):
- if arg:
- # Check if the arg is a builtin command or something
- # coming from the command manager
- arg_parts = shlex.split(arg)
- method_name = '_'.join(
- itertools.chain(
- ['do'],
- itertools.takewhile(lambda x: not x.startswith('-'),
- arg_parts)
- )
- )
- # Have the command manager version of the help
- # command produce the help text since cmd and
- # cmd2 do not provide help for "help"
- if hasattr(self, method_name):
- return cmd2.Cmd.do_help(self, arg)
- # Dispatch to the underlying help command,
- # which knows how to provide help for extension
- # commands.
- self.default(self.parsed('help ' + arg))
- else:
- cmd2.Cmd.do_help(self, arg)
- cmd_names = sorted([n for n, v in self.command_manager])
- self.print_topics(self.app_cmd_header, cmd_names, 15, 80)
- return
-
- def get_names(self):
- # Override the base class version to filter out
- # things that look like they should be hidden
- # from the user.
- return [n
- for n in cmd2.Cmd.get_names(self)
- if not n.startswith('do__')
- ]
-
- def precmd(self, statement):
- # Pre-process the parsed command in case it looks like one of
- # our subcommands, since cmd2 does not handle multi-part
- # command names by default.
- line_parts = shlex.split(statement.parsed.raw)
- try:
- the_cmd = self.command_manager.find_command(line_parts)
- cmd_factory, cmd_name, sub_argv = the_cmd
- except ValueError:
- # Not a plugin command
- pass
- else:
- statement.parsed.command = cmd_name
- statement.parsed.args = ' '.join(sub_argv)
- return statement
diff --git a/cliff/lister.py b/cliff/lister.py
deleted file mode 100644
index 1b6c3b6..0000000
--- a/cliff/lister.py
+++ /dev/null
@@ -1,66 +0,0 @@
-"""Application base class for providing a list of data as output.
-"""
-import abc
-
-try:
- from itertools import compress
-except ImportError:
- # for py26 compat
- from itertools import izip
-
- def compress(data, selectors):
- return (d for d, s in izip(data, selectors) if s)
-
-import logging
-
-from .display import DisplayCommandBase
-
-
-LOG = logging.getLogger(__name__)
-
-
-class Lister(DisplayCommandBase):
- """Command base class for providing a list of data as output.
- """
- __metaclass__ = abc.ABCMeta
-
- @property
- def formatter_namespace(self):
- return 'cliff.formatter.list'
-
- @property
- def formatter_default(self):
- return 'table'
-
- @abc.abstractmethod
- def take_action(self, parsed_args):
- """Return a tuple containing the column names and an iterable
- containing the data to be listed.
- """
-
- def produce_output(self, parsed_args, column_names, data):
- if not parsed_args.columns:
- columns_to_include = column_names
- data_gen = data
- else:
- columns_to_include = [c for c in column_names
- if c in parsed_args.columns
- ]
- if not columns_to_include:
- raise ValueError('No recognized column names in %s' %
- str(parsed_args.columns))
- # Set up argument to compress()
- selector = [(c in columns_to_include)
- for c in column_names]
- # Generator expression to only return the parts of a row
- # of data that the user has expressed interest in
- # seeing. We have to convert the compress() output to a
- # list so the table formatter can ask for its length.
- data_gen = (list(compress(row, selector))
- for row in data)
- self.formatter.emit_list(columns_to_include,
- data_gen,
- self.app.stdout,
- parsed_args,
- )
- return 0
diff --git a/cliff/show.py b/cliff/show.py
deleted file mode 100644
index 855b2d2..0000000
--- a/cliff/show.py
+++ /dev/null
@@ -1,55 +0,0 @@
-"""Application base class for displaying data about a single object.
-"""
-import abc
-import itertools
-import logging
-
-from .display import DisplayCommandBase
-
-
-LOG = logging.getLogger(__name__)
-
-
-class ShowOne(DisplayCommandBase):
- """Command base class for displaying data about a single object.
- """
- __metaclass__ = abc.ABCMeta
-
- @property
- def formatter_namespace(self):
- return 'cliff.formatter.show'
-
- @property
- def formatter_default(self):
- return 'table'
-
- @abc.abstractmethod
- def take_action(self, parsed_args):
- """Return a two-part tuple with a tuple of column names
- and a tuple of values.
- """
-
- def produce_output(self, parsed_args, column_names, data):
- if not parsed_args.columns:
- columns_to_include = column_names
- else:
- columns_to_include = [c for c in column_names
- if c in parsed_args.columns]
- # Set up argument to compress()
- selector = [(c in columns_to_include)
- for c in column_names]
- data = list(itertools.compress(data, selector))
- self.formatter.emit_one(columns_to_include,
- data,
- self.app.stdout,
- parsed_args)
- return 0
-
- def dict2columns(self, data):
- """Implement the common task of converting a dict-based object
- to the two-column output that ShowOne expects.
- """
- if not data:
- return ({}, {})
- else:
- return zip(*sorted(data.items()))
diff --git a/cliff/tests/__init__.py b/cliff/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/cliff/tests/__init__.py
+++ /dev/null
diff --git a/cliff/tests/test_app.py b/cliff/tests/test_app.py
deleted file mode 100644
index e3bc12e..0000000
--- a/cliff/tests/test_app.py
+++ /dev/null
@@ -1,389 +0,0 @@
-# -*- encoding: utf-8 -*-
-from argparse import ArgumentError
-try:
- from StringIO import StringIO
-except ImportError:
- # Probably python 3, that test won't be run so ignore the error
- pass
-import sys
-
-import nose
-import mock
-
-from cliff.app import App
-from cliff.command import Command
-from cliff.commandmanager import CommandManager
-
-
-def make_app():
- cmd_mgr = CommandManager('cliff.tests')
-
- # Register a command that succeeds
- command = mock.MagicMock(spec=Command)
- command_inst = mock.MagicMock(spec=Command)
- command_inst.run.return_value = 0
- command.return_value = command_inst
- cmd_mgr.add_command('mock', command)
-
- # Register a command that fails
- err_command = mock.Mock(name='err_command', spec=Command)
- err_command_inst = mock.Mock(spec=Command)
- err_command_inst.run = mock.Mock(
- side_effect=RuntimeError('test exception')
- )
- err_command.return_value = err_command_inst
- cmd_mgr.add_command('error', err_command)
-
- app = App('testing interactive mode',
- '1',
- cmd_mgr,
- stderr=mock.Mock(), # suppress warning messages
- )
- return app, command
-
-
-def test_no_args_triggers_interactive_mode():
- app, command = make_app()
- app.interact = mock.MagicMock(name='inspect')
- app.run([])
- app.interact.assert_called_once_with()
-
-
-def test_interactive_mode_cmdloop():
- app, command = make_app()
- app.interactive_app_factory = mock.MagicMock(
- name='interactive_app_factory'
- )
- assert app.interpreter is None
- app.run([])
- assert app.interpreter is not None
- app.interactive_app_factory.return_value.cmdloop.assert_called_once_with()
-
-
-def test_initialize_app():
- app, command = make_app()
- app.initialize_app = mock.MagicMock(name='initialize_app')
- app.run(['mock'])
- app.initialize_app.assert_called_once_with(['mock'])
-
-
-def test_prepare_to_run_command():
- app, command = make_app()
- app.prepare_to_run_command = mock.MagicMock(name='prepare_to_run_command')
- app.run(['mock'])
- app.prepare_to_run_command.assert_called_once_with(command())
-
-
-def test_clean_up_success():
- app, command = make_app()
- app.clean_up = mock.MagicMock(name='clean_up')
- app.run(['mock'])
- app.clean_up.assert_called_once_with(command.return_value, 0, None)
-
-
-def test_clean_up_error():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(name='clean_up')
- app.run(['error'])
-
- app.clean_up.assert_called_once()
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
-
-
-def test_clean_up_error_debug():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(name='clean_up')
- try:
- app.run(['--debug', 'error'])
- except RuntimeError as err:
- assert app.clean_up.call_args_list[0][0][2] is err
- else:
- assert False, 'Should have had an exception'
-
- app.clean_up.assert_called_once()
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
-
-
-def test_error_handling_clean_up_raises_exception():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- app.run(['error'])
-
- app.clean_up.assert_called_once()
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
-
-
-def test_error_handling_clean_up_raises_exception_debug():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- try:
- app.run(['--debug', 'error'])
- except RuntimeError as err:
- if not hasattr(err, '__context__'):
- # The exception passed to clean_up is not the exception
- # caused *by* clean_up. This test is only valid in python
- # 2 because under v3 the original exception is re-raised
- # with the new one as a __context__ attribute.
- assert app.clean_up.call_args_list[0][0][2] is not err
- else:
- assert False, 'Should have had an exception'
-
- app.clean_up.assert_called_once()
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
-
-
-def test_normal_clean_up_raises_exception():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- app.run(['mock'])
-
- app.clean_up.assert_called_once()
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 0, None)
-
-
-def test_normal_clean_up_raises_exception_debug():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- app.run(['--debug', 'mock'])
-
- app.clean_up.assert_called_once()
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 0, None)
-
-
-def test_build_option_parser_conflicting_option_should_throw():
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- def build_option_parser(self, description, version):
- parser = super(MyApp, self).build_option_parser(description,
- version)
- parser.add_argument(
- '-h', '--help',
- default=self, # tricky
- help="show this help message and exit",
- )
-
- # TODO: tests should really use unittest2.
- try:
- MyApp()
- except ArgumentError:
- pass
- else:
- raise Exception('Exception was not thrown')
-
-
-def test_option_parser_conflicting_option_custom_arguments_should_not_throw():
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- def build_option_parser(self, description, version):
- argparse_kwargs = {'conflict_handler': 'resolve'}
- parser = super(MyApp, self).build_option_parser(
- description,
- version,
- argparse_kwargs=argparse_kwargs)
- parser.add_argument(
- '-h', '--help',
- default=self, # tricky
- help="show this help message and exit",
- )
-
- MyApp()
-
-
-def test_output_encoding_default():
- # The encoding should come from getdefaultlocale() because
- # stdout has no encoding set.
- if sys.version_info[:2] != (2, 6):
- raise nose.SkipTest('only needed for python 2.6')
- data = '\xc3\xa9'
- u_data = data.decode('utf-8')
-
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- stdout = StringIO()
- getdefaultlocale = lambda: ('ignored', 'utf-8')
-
- with mock.patch('sys.stdout', stdout):
- with mock.patch('locale.getdefaultlocale', getdefaultlocale):
- app = MyApp()
- app.stdout.write(u_data)
- actual = stdout.getvalue()
- assert data == actual
-
-
-def test_output_encoding_cliff_default():
- # The encoding should come from cliff.App.DEFAULT_OUTPUT_ENCODING
- # because the other values are missing or None
- if sys.version_info[:2] != (2, 6):
- raise nose.SkipTest('only needed for python 2.6')
- data = '\xc3\xa9'
- u_data = data.decode('utf-8')
-
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- stdout = StringIO()
- getdefaultlocale = lambda: ('ignored', None)
-
- with mock.patch('sys.stdout', stdout):
- with mock.patch('locale.getdefaultlocale', getdefaultlocale):
- app = MyApp()
- app.stdout.write(u_data)
- actual = stdout.getvalue()
- assert data == actual
-
-
-def test_output_encoding_sys():
- # The encoding should come from sys.stdout because it is set
- # there.
- if sys.version_info[:2] != (2, 6):
- raise nose.SkipTest('only needed for python 2.6')
- data = '\xc3\xa9'
- u_data = data.decode('utf-8')
-
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- stdout = StringIO()
- stdout.encoding = 'utf-8'
- getdefaultlocale = lambda: ('ignored', 'utf-16')
-
- with mock.patch('sys.stdout', stdout):
- with mock.patch('locale.getdefaultlocale', getdefaultlocale):
- app = MyApp()
- app.stdout.write(u_data)
- actual = stdout.getvalue()
- assert data == actual
-
-
-def test_error_encoding_default():
- # The encoding should come from getdefaultlocale() because
- # stdout has no encoding set.
- if sys.version_info[:2] != (2, 6):
- raise nose.SkipTest('only needed for python 2.6')
- data = '\xc3\xa9'
- u_data = data.decode('utf-8')
-
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- stderr = StringIO()
- getdefaultlocale = lambda: ('ignored', 'utf-8')
-
- with mock.patch('sys.stderr', stderr):
- with mock.patch('locale.getdefaultlocale', getdefaultlocale):
- app = MyApp()
- app.stderr.write(u_data)
- actual = stderr.getvalue()
- assert data == actual
-
-
-def test_error_encoding_sys():
- # The encoding should come from sys.stdout (not sys.stderr)
- # because it is set there.
- if sys.version_info[:2] != (2, 6):
- raise nose.SkipTest('only needed for python 2.6')
- data = '\xc3\xa9'
- u_data = data.decode('utf-8')
-
- class MyApp(App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=CommandManager('tests'),
- )
-
- stdout = StringIO()
- stdout.encoding = 'utf-8'
- stderr = StringIO()
- getdefaultlocale = lambda: ('ignored', 'utf-16')
-
- with mock.patch('sys.stdout', stdout):
- with mock.patch('sys.stderr', stderr):
- with mock.patch('locale.getdefaultlocale', getdefaultlocale):
- app = MyApp()
- app.stderr.write(u_data)
- actual = stderr.getvalue()
- assert data == actual
-
-
-def test_unknown_cmd():
- app, command = make_app()
- assert app.run(['hell']) == 2
-
-
-def test_unknown_cmd_debug():
- app, command = make_app()
- try:
- app.run(['--debug', 'hell']) == 2
- except ValueError as err:
- assert "['hell']" in ('%s' % err)
diff --git a/cliff/tests/test_command.py b/cliff/tests/test_command.py
deleted file mode 100644
index 39fde51..0000000
--- a/cliff/tests/test_command.py
+++ /dev/null
@@ -1,22 +0,0 @@
-
-from cliff.command import Command
-
-
-class TestCommand(Command):
- """Description of command.
- """
-
- def take_action(self, parsed_args):
- return
-
-
-def test_get_description():
- cmd = TestCommand(None, None)
- desc = cmd.get_description()
- assert desc == "Description of command.\n "
-
-
-def test_get_parser():
- cmd = TestCommand(None, None)
- parser = cmd.get_parser('NAME')
- assert parser.prog == 'NAME'
diff --git a/cliff/tests/test_commandmanager.py b/cliff/tests/test_commandmanager.py
deleted file mode 100644
index 9a50a5e..0000000
--- a/cliff/tests/test_commandmanager.py
+++ /dev/null
@@ -1,121 +0,0 @@
-
-import mock
-
-from cliff.commandmanager import CommandManager
-
-
-class TestCommand(object):
- @classmethod
- def load(cls):
- return cls
-
- def __init__(self):
- return
-
-
-class TestCommandManager(CommandManager):
- def _load_commands(self):
- self.commands = {
- 'one': TestCommand,
- 'two words': TestCommand,
- 'three word command': TestCommand,
- }
-
-
-def test_lookup_and_find():
- def check(mgr, argv):
- cmd, name, remaining = mgr.find_command(argv)
- assert cmd
- assert name == ' '.join(argv)
- assert not remaining
- mgr = TestCommandManager('test')
- for expected in [['one'],
- ['two', 'words'],
- ['three', 'word', 'command'],
- ]:
- yield check, mgr, expected
- return
-
-
-def test_lookup_with_remainder():
- def check(mgr, argv):
- cmd, name, remaining = mgr.find_command(argv)
- assert cmd
- assert remaining == ['--opt']
- mgr = TestCommandManager('test')
- for expected in [['one', '--opt'],
- ['two', 'words', '--opt'],
- ['three', 'word', 'command', '--opt'],
- ]:
- yield check, mgr, expected
- return
-
-
-def test_find_invalid_command():
- mgr = TestCommandManager('test')
-
- def check_one(argv):
- try:
- mgr.find_command(argv)
- except ValueError as err:
- assert '-b' in ('%s' % err)
- else:
- assert False, 'expected a failure'
- for argv in [['a', '-b'],
- ['-b'],
- ]:
- yield check_one, argv
-
-
-def test_find_unknown_command():
- mgr = TestCommandManager('test')
- try:
- mgr.find_command(['a', 'b'])
- except ValueError as err:
- assert "['a', 'b']" in ('%s' % err)
- else:
- assert False, 'expected a failure'
-
-
-def test_add_command():
- mgr = TestCommandManager('test')
- mock_cmd = mock.Mock()
- mgr.add_command('mock', mock_cmd)
- found_cmd, name, args = mgr.find_command(['mock'])
- assert found_cmd is mock_cmd
-
-
-def test_load_commands():
- testcmd = mock.Mock(name='testcmd')
- testcmd.name.replace.return_value = 'test'
- mock_pkg_resources = mock.Mock(return_value=[testcmd])
- with mock.patch('pkg_resources.iter_entry_points',
- mock_pkg_resources) as iter_entry_points:
- mgr = CommandManager('test')
- assert iter_entry_points.called_once_with('test')
- names = [n for n, v in mgr]
- assert names == ['test']
-
-
-def test_load_commands_keep_underscores():
- testcmd = mock.Mock()
- testcmd.name = 'test_cmd'
- mock_pkg_resources = mock.Mock(return_value=[testcmd])
- with mock.patch('pkg_resources.iter_entry_points',
- mock_pkg_resources) as iter_entry_points:
- mgr = CommandManager('test', convert_underscores=False)
- assert iter_entry_points.called_once_with('test')
- names = [n for n, v in mgr]
- assert names == ['test_cmd']
-
-
-def test_load_commands_replace_underscores():
- testcmd = mock.Mock()
- testcmd.name = 'test_cmd'
- mock_pkg_resources = mock.Mock(return_value=[testcmd])
- with mock.patch('pkg_resources.iter_entry_points',
- mock_pkg_resources) as iter_entry_points:
- mgr = CommandManager('test', convert_underscores=True)
- assert iter_entry_points.called_once_with('test')
- names = [n for n, v in mgr]
- assert names == ['test cmd']
diff --git a/cliff/tests/test_complete.py b/cliff/tests/test_complete.py
deleted file mode 100644
index b5a6bbf..0000000
--- a/cliff/tests/test_complete.py
+++ /dev/null
@@ -1,130 +0,0 @@
-"""Bash completion tests
-"""
-
-import mock
-
-from cliff.app import App
-from cliff.commandmanager import CommandManager
-from cliff import complete
-
-
-def test_complete_dictionary():
- sot = complete.CompleteDictionary()
- sot.add_command("image delete".split(),
- [mock.Mock(option_strings=["1"])])
- sot.add_command("image list".split(),
- [mock.Mock(option_strings=["2"])])
- sot.add_command("image create".split(),
- [mock.Mock(option_strings=["3"])])
- sot.add_command("volume type create".split(),
- [mock.Mock(option_strings=["4"])])
- sot.add_command("volume type delete".split(),
- [mock.Mock(option_strings=["5"])])
- assert "image volume" == sot.get_commands()
- result = sot.get_data()
- assert "image" == result[0][0]
- assert "create delete list" == result[0][1]
- assert "image_create" == result[1][0]
- assert "3" == result[1][1]
- assert "image_delete" == result[2][0]
- assert "1" == result[2][1]
- assert "image_list" == result[3][0]
- assert "2" == result[3][1]
-
-
-class FakeStdout:
- def __init__(self):
- self.content = []
-
- def write(self, text):
- self.content.append(text)
-
- def make_string(self):
- result = ''
- for line in self.content:
- result = result + line
- return result
-
-
-def given_cmdo_data():
- cmdo = "image server"
- data = [("image", "create"),
- ("image_create", "--eolus"),
- ("server", "meta ssh"),
- ("server_meta_delete", "--wilson"),
- ("server_ssh", "--sunlight")]
- return cmdo, data
-
-
-def then_data(content):
- assert " cmds='image server'\n" in content
- assert " cmds_image='create'\n" in content
- assert " cmds_image_create='--eolus'\n" in content
- assert " cmds_server='meta ssh'\n" in content
- assert " cmds_server_meta_delete='--wilson'\n" in content
- assert " cmds_server_ssh='--sunlight'\n" in content
-
-
-def test_complete_no_code():
- output = FakeStdout()
- sot = complete.CompleteNoCode("doesNotMatter", output)
- sot.write(*given_cmdo_data())
- then_data(output.content)
-
-
-def test_complete_bash():
- output = FakeStdout()
- sot = complete.CompleteBash("openstack", output)
- sot.write(*given_cmdo_data())
- then_data(output.content)
- assert "_openstack()\n" in output.content[0]
- assert "complete -F _openstack openstack\n" in output.content[-1]
-
-
-def test_complete_command_parser():
- sot = complete.CompleteCommand(mock.Mock(), mock.Mock())
- parser = sot.get_parser('nothing')
- assert "nothing" == parser.prog
- assert "print bash completion command\n " == parser.description
-
-
-def given_complete_command():
- cmd_mgr = CommandManager('cliff.tests')
- app = App('testing', '1', cmd_mgr, stdout=FakeStdout())
- sot = complete.CompleteCommand(app, mock.Mock())
- cmd_mgr.add_command('complete', complete.CompleteCommand)
- return sot, app, cmd_mgr
-
-
-def then_actions_equal(actions):
- optstr = ' '.join(opt for action in actions
- for opt in action.option_strings)
- assert '-h --help --name --shell' == optstr
-
-
-def test_complete_command_get_actions():
- sot, app, cmd_mgr = given_complete_command()
- app.interactive_mode = False
- actions = sot.get_actions(["complete"])
- then_actions_equal(actions)
-
-
-def test_complete_command_get_actions_interactive():
- sot, app, cmd_mgr = given_complete_command()
- app.interactive_mode = True
- actions = sot.get_actions(["complete"])
- then_actions_equal(actions)
-
-
-def test_complete_command_take_action():
- sot, app, cmd_mgr = given_complete_command()
- parsed_args = mock.Mock()
- parsed_args.name = "test_take"
- parsed_args.shell = "bash"
- content = app.stdout.content
- assert 0 == sot.take_action(parsed_args)
- assert "_test_take()\n" in content[0]
- assert "complete -F _test_take test_take\n" in content[-1]
- assert " cmds='complete help'\n" in content
- assert " cmds_complete='-h --help --name --shell'\n" in content
- assert " cmds_help='-h --help'\n" in content
diff --git a/cliff/tests/test_help.py b/cliff/tests/test_help.py
deleted file mode 100644
index bdf9d71..0000000
--- a/cliff/tests/test_help.py
+++ /dev/null
@@ -1,116 +0,0 @@
-try:
- from StringIO import StringIO
-except:
- from io import StringIO
-
-import mock
-
-from cliff.app import App
-from cliff.command import Command
-from cliff.commandmanager import CommandManager
-from cliff.help import HelpCommand
-
-
-class TestParser(object):
-
- def print_help(self, stdout):
- stdout.write('TestParser')
-
-
-class TestCommand(Command):
-
- @classmethod
- def load(cls):
- return cls
-
- def get_parser(self, ignore):
- # Make it look like this class is the parser
- # so parse_args() is called.
- return TestParser()
-
- def take_action(self, args):
- return
-
-
-class TestCommandManager(CommandManager):
- def _load_commands(self):
- self.commands = {
- 'one': TestCommand,
- 'two words': TestCommand,
- 'three word command': TestCommand,
- }
-
-
-def test_show_help_for_command():
- # FIXME(dhellmann): Are commands tied too closely to the app? Or
- # do commands know too much about apps by using them to get to the
- # command manager?
- stdout = StringIO()
- app = App('testing', '1', TestCommandManager('cliff.test'), stdout=stdout)
- app.NAME = 'test'
- help_cmd = HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args(['one'])
- try:
- help_cmd.run(parsed_args)
- except SystemExit:
- pass
- assert stdout.getvalue() == 'TestParser'
-
-
-def test_list_matching_commands():
- # FIXME(dhellmann): Are commands tied too closely to the app? Or
- # do commands know too much about apps by using them to get to the
- # command manager?
- stdout = StringIO()
- app = App('testing', '1', TestCommandManager('cliff.test'), stdout=stdout)
- app.NAME = 'test'
- help_cmd = HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args(['t'])
- try:
- help_cmd.run(parsed_args)
- except SystemExit:
- pass
- help_output = stdout.getvalue()
- assert 'Command "t" matches:' in help_output
- assert 'two' in help_output
- assert 'three' in help_output
-
-
-def test_list_matching_commands_no_match():
- # FIXME(dhellmann): Are commands tied too closely to the app? Or
- # do commands know too much about apps by using them to get to the
- # command manager?
- stdout = StringIO()
- app = App('testing', '1', TestCommandManager('cliff.test'), stdout=stdout)
- app.NAME = 'test'
- help_cmd = HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args(['z'])
- try:
- help_cmd.run(parsed_args)
- except SystemExit:
- pass
- except ValueError:
- pass
- else:
- assert False, 'Should have seen a ValueError'
-
-
-def test_show_help_for_help():
- # FIXME(dhellmann): Are commands tied too closely to the app? Or
- # do commands know too much about apps by using them to get to the
- # command manager?
- stdout = StringIO()
- app = App('testing', '1', TestCommandManager('cliff.test'), stdout=stdout)
- app.NAME = 'test'
- help_cmd = HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args([])
- try:
- help_cmd.run(parsed_args)
- except SystemExit:
- pass
- help_text = stdout.getvalue()
- assert 'usage: test help [-h]' in help_text
diff --git a/cliff/tests/test_lister.py b/cliff/tests/test_lister.py
deleted file mode 100644
index 7d1876f..0000000
--- a/cliff/tests/test_lister.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-
-import weakref
-
-from cliff.lister import Lister
-
-import mock
-
-
-class FauxFormatter(object):
-
- def __init__(self):
- self.args = []
- self.obj = weakref.proxy(self)
-
- def emit_list(self, columns, data, stdout, args):
- self.args.append((columns, data))
-
-
-class ExerciseLister(Lister):
-
- def _load_formatter_plugins(self):
- return {
- 'test': FauxFormatter(),
- }
- return
-
- def take_action(self, parsed_args):
- return (
- parsed_args.columns,
- [('a', 'A'), ('b', 'B')],
- )
-
-
-# def run(self, parsed_args):
-# self.formatter = self.formatters[parsed_args.formatter]
-# column_names, data = self.take_action(parsed_args)
-# self.produce_output(parsed_args, column_names, data)
-# return 0
-
-def test_formatter_args():
- app = mock.Mock()
- test_lister = ExerciseLister(app, [])
-
- parsed_args = mock.Mock()
- parsed_args.columns = ('Col1', 'Col2')
- parsed_args.formatter = 'test'
-
- test_lister.run(parsed_args)
- f = test_lister.formatters['test']
- assert len(f.args) == 1
- args = f.args[0]
- assert args[0] == list(parsed_args.columns)
- data = list(args[1])
- assert data == [['a', 'A'], ['b', 'B']]
diff --git a/cliff/tests/test_show.py b/cliff/tests/test_show.py
deleted file mode 100644
index 41df5e1..0000000
--- a/cliff/tests/test_show.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-
-from cliff.show import ShowOne
-
-import mock
-
-
-class FauxFormatter(object):
-
- def __init__(self):
- self.args = []
-
- def emit_list(self, columns, data, stdout, args):
- self.args.append((columns, data))
-
-
-class ExerciseShowOne(ShowOne):
-
- def load_formatter_plugins(self):
- self.formatters = {
- 'test': FauxFormatter(),
- }
- return
-
- def take_action(self, parsed_args):
- return (
- parsed_args.columns,
- [('a', 'A'), ('b', 'B')],
- )
-
-
-# def test_formatter_args():
-# app = mock.Mock()
-# test_lister = ExerciseLister(app, [])
-
-# parsed_args = mock.Mock()
-# parsed_args.columns = ('Col1', 'Col2')
-# parsed_args.formatter = 'test'
-
-# test_lister.run(parsed_args)
-# f = test_lister.formatters['test']
-# assert len(f.args) == 1
-# args = f.args[0]
-# assert args[0] == list(parsed_args.columns)
-# data = list(args[1])
-# assert data == [['a', 'A'], ['b', 'B']]
-
-def test_dict2columns():
- app = mock.Mock()
- test_show = ExerciseShowOne(app, [])
- d = {'a': 'A', 'b': 'B', 'c': 'C'}
- expected = [('a', 'b', 'c'), ('A', 'B', 'C')]
- actual = list(test_show.dict2columns(d))
- assert expected == actual
diff --git a/demoapp/README.rst b/demoapp/README.rst
deleted file mode 100644
index 24ca9b6..0000000
--- a/demoapp/README.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-=================
- Running demoapp
-=================
-
-Setup
------
-
-First, you need to create a virtual environment and activate it.
-
-::
-
- $ pip install virtualenv
- $ virtualenv .venv
- $ . .venv/bin/activate
- (.venv)$
-
-Next, install ``cliff`` in the environment.
-
-::
-
- (.venv)$ python setup.py install
-
-Now, install the demo application into the virtual environment.
-
-::
-
- (.venv)$ cd demoapp
- (.venv)$ python setup.py install
-
-Usage
------
-
-With cliff and the demo setup up, you can now play with it.
-
-To see a list of commands available, run::
-
- (.venv)$ cliffdemo --help
-
-One of the available commands is "simple" and running it
-
-::
-
- (.venv)$ cliffdemo simple
-
-produces the following
-
-::
-
- sending greeting
- hi!
-
-
-To see help for an individual command, include the command name on the
-command line::
-
- (.venv)$ cliffdemo files --help
-
-Cleaning Up
------------
-
-Finally, when done, deactivate your virtual environment::
-
- (.venv)$ deactivate
- $
diff --git a/demoapp/cliffdemo/__init__.py b/demoapp/cliffdemo/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/demoapp/cliffdemo/__init__.py
+++ /dev/null
diff --git a/demoapp/cliffdemo/encoding.py b/demoapp/cliffdemo/encoding.py
deleted file mode 100644
index 6c6c751..0000000
--- a/demoapp/cliffdemo/encoding.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- encoding: utf-8 -*-
-
-import logging
-
-from cliff.lister import Lister
-
-
-class Encoding(Lister):
- """Show some unicode text
- """
-
- log = logging.getLogger(__name__)
-
- def take_action(self, parsed_args):
- messages = [
- u'pi: π',
- u'GB18030:鼀丅㐀ٸཌྷᠧꌢ€',
- ]
- return (
- ('UTF-8', 'Unicode'),
- [(repr(t.encode('utf-8')), t)
- for t in messages],
- )
diff --git a/demoapp/cliffdemo/list.py b/demoapp/cliffdemo/list.py
deleted file mode 100644
index 3dcee4a..0000000
--- a/demoapp/cliffdemo/list.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import logging
-import os
-
-from cliff.lister import Lister
-
-
-class Files(Lister):
- """Show a list of files in the current directory.
-
- The file name and size are printed by default.
- """
-
- log = logging.getLogger(__name__)
-
- def take_action(self, parsed_args):
- return (('Name', 'Size'),
- ((n, os.stat(n).st_size) for n in os.listdir('.'))
- )
diff --git a/demoapp/cliffdemo/main.py b/demoapp/cliffdemo/main.py
deleted file mode 100644
index 85807c8..0000000
--- a/demoapp/cliffdemo/main.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import logging
-import sys
-
-from cliff.app import App
-from cliff.commandmanager import CommandManager
-
-
-class DemoApp(App):
-
- log = logging.getLogger(__name__)
-
- def __init__(self):
- super(DemoApp, self).__init__(
- description='cliff demo app',
- version='0.1',
- command_manager=CommandManager('cliff.demo'),
- )
-
- def initialize_app(self, argv):
- self.log.debug('initialize_app')
-
- def prepare_to_run_command(self, cmd):
- self.log.debug('prepare_to_run_command %s', cmd.__class__.__name__)
-
- def clean_up(self, cmd, result, err):
- self.log.debug('clean_up %s', cmd.__class__.__name__)
- if err:
- self.log.debug('got an error: %s', err)
-
-
-def main(argv=sys.argv[1:]):
- myapp = DemoApp()
- return myapp.run(argv)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/demoapp/cliffdemo/show.py b/demoapp/cliffdemo/show.py
deleted file mode 100644
index 9351148..0000000
--- a/demoapp/cliffdemo/show.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import logging
-import os
-
-from cliff.show import ShowOne
-
-
-class File(ShowOne):
- "Show details about a file"
-
- log = logging.getLogger(__name__)
-
- def get_parser(self, prog_name):
- parser = super(File, self).get_parser(prog_name)
- parser.add_argument('filename', nargs='?', default='.')
- return parser
-
- def take_action(self, parsed_args):
- stat_data = os.stat(parsed_args.filename)
- columns = ('Name',
- 'Size',
- 'UID',
- 'GID',
- 'Modified Time',
- )
- data = (parsed_args.filename,
- stat_data.st_size,
- stat_data.st_uid,
- stat_data.st_gid,
- stat_data.st_mtime,
- )
- return (columns, data)
diff --git a/demoapp/cliffdemo/simple.py b/demoapp/cliffdemo/simple.py
deleted file mode 100644
index 3800514..0000000
--- a/demoapp/cliffdemo/simple.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import logging
-
-from cliff.command import Command
-
-
-class Simple(Command):
- "A simple command that prints a message."
-
- log = logging.getLogger(__name__)
-
- def take_action(self, parsed_args):
- self.log.info('sending greeting')
- self.log.debug('debugging')
- self.app.stdout.write('hi!\n')
-
-
-class Error(Command):
- "Always raises an error"
-
- log = logging.getLogger(__name__)
-
- def take_action(self, parsed_args):
- self.log.info('causing error')
- raise RuntimeError('this is the expected exception')
diff --git a/demoapp/setup.py b/demoapp/setup.py
deleted file mode 100644
index 4bef32e..0000000
--- a/demoapp/setup.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-
-PROJECT = 'cliffdemo'
-
-# Change docs/sphinx/conf.py too!
-VERSION = '0.1'
-
-from setuptools import setup, find_packages
-
-try:
- long_description = open('README.rst', 'rt').read()
-except IOError:
- long_description = ''
-
-setup(
- name=PROJECT,
- version=VERSION,
-
- description='Demo app for cliff',
- long_description=long_description,
-
- author='Doug Hellmann',
- author_email='doug.hellmann@gmail.com',
-
- url='https://github.com/dreamhost/cliff',
- download_url='https://github.com/dreamhost/cliff/tarball/master',
-
- classifiers=['Development Status :: 3 - Alpha',
- 'License :: OSI Approved :: Apache Software License',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.2',
- 'Intended Audience :: Developers',
- 'Environment :: Console',
- ],
-
- platforms=['Any'],
-
- scripts=[],
-
- provides=[],
- install_requires=['cliff'],
-
- namespace_packages=[],
- packages=find_packages(),
- include_package_data=True,
-
- entry_points={
- 'console_scripts': [
- 'cliffdemo = cliffdemo.main:main'
- ],
- 'cliff.demo': [
- 'simple = cliffdemo.simple:Simple',
- 'two_part = cliffdemo.simple:Simple',
- 'error = cliffdemo.simple:Error',
- 'list files = cliffdemo.list:Files',
- 'files = cliffdemo.list:Files',
- 'file = cliffdemo.show:File',
- 'show file = cliffdemo.show:File',
- 'unicode = cliffdemo.encoding:Encoding',
- ],
- },
-
- zip_safe=False,
-)
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index 0127250..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,153 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = build
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- -rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/cliff.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/cliff.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/cliff"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/cliff"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index 6f01983..0000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-httplib2==0.7.4
-prettytable==0.5
diff --git a/docs/source/classes.rst b/docs/source/classes.rst
deleted file mode 100644
index 14e80e9..0000000
--- a/docs/source/classes.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-===============
- Cliff Classes
-===============
-
-Application
-===========
-
-App
----
-
-.. autoclass:: cliff.app.App
- :members:
-
-InteractiveApp
---------------
-
-.. autoclass:: cliff.interactive.InteractiveApp
- :members:
-
-CommandManager
---------------
-
-.. autoclass:: cliff.commandmanager.CommandManager
- :members:
-
-Command
--------
-
-.. autoclass:: cliff.command.Command
- :members:
-
-ShowOne
--------
-
-.. autoclass:: cliff.show.ShowOne
- :members:
-
-Lister
-------
-
-.. autoclass:: cliff.lister.Lister
- :members:
-
-Formatting Output
-=================
-
-Formatter
----------
-
-.. autoclass:: cliff.formatters.base.Formatter
- :members:
-
-ListFormatter
--------------
-
-.. autoclass:: cliff.formatters.base.ListFormatter
- :members:
-
-SingleFormatter
----------------
-
-.. autoclass:: cliff.formatters.base.SingleFormatter
- :members:
diff --git a/docs/source/complete.rst b/docs/source/complete.rst
deleted file mode 100644
index 2a08098..0000000
--- a/docs/source/complete.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-====================
- Command Completion
-====================
-
-A generic command completion command is available to generate a
-bash-completion script. Currently, the command will generate a script
-for bash versions 3 or 4. There is also a mode that generates only
-data that can be used in your own script. The command completion script
-is generated based on the commands and options that you have specified
-in cliff.
-
-Usage
-=====
-
-In order for your command to support command completions, you need to
-add the `cliff.complete.CompleteCommand` class to your command manager.
-
-::
-
- self.command_manager.add_command('complete', cliff.complete.CompleteCommand)
-
-When you run the command, it will generate a bash-completion script:
-
-::
-
- (.venv)$ mycmd complete
- _mycmd()
- {
- local cur prev words
- COMPREPLY=()
- _get_comp_words_by_ref -n : cur prev words
-
- # Command data:
- cmds='agent aggregate backup'
- cmds_agent='--name'
- ...
- if [ -z "${completed}" ] ; then
- COMPREPLY=( $( compgen -f -- "$cur" ) $( compgen -d -- "$cur" ) )
- else
- COMPREPLY=( $(compgen -W "${completed}" -- ${cur}) )
- fi
- return 0
- }
- complete -F _mycmd mycmd
-
diff --git a/docs/source/conf.py b/docs/source/conf.py
deleted file mode 100644
index 131a9f9..0000000
--- a/docs/source/conf.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# cliff documentation build configuration file, created by
-# sphinx-quickstart on Wed Apr 25 11:14:29 2012.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import datetime
-import subprocess
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration ---------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'cliff'
-copyright = u'2012-%s, Doug Hellmann' % datetime.datetime.today().year
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = subprocess.check_output([
- 'sh', '-c',
- 'cd ../..; python setup.py --version',
-])
-version = version.strip()
-# The full version, including alpha/beta/rc tags.
-release = version
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = []
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'cliffdoc'
-
-
-# -- Options for LaTeX output ------------------------------------------------
-
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- #'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- #'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- #'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author,
-# documentclass [howto/manual]).
-latex_documents = [
- ('index', 'cliff.tex', u'cliff Documentation',
- u'Doug Hellmann', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output ------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'cliff', u'cliff Documentation',
- [u'Doug Hellmann'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ----------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- ('index', 'cliff', u'cliff Documentation',
- u'Doug Hellmann', 'cliff', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
diff --git a/docs/source/demoapp.rst b/docs/source/demoapp.rst
deleted file mode 100644
index 66e66cb..0000000
--- a/docs/source/demoapp.rst
+++ /dev/null
@@ -1,258 +0,0 @@
-========================
- Exploring the Demo App
-========================
-
-The cliff source package includes a ``demoapp`` directory containing
-an example main program with several command plugins.
-
-Setup
-=====
-
-To install and experiment with the demo app you should create a
-virtual environment and activate it. This will make it easy to remove
-the app later, since it doesn't do anything useful and you aren't
-likely to want to hang onto it after you understand how it works.
-
-::
-
- $ pip install virtualenv
- $ virtualenv .venv
- $ . .venv/bin/activate
- (.venv)$
-
-Next, install cliff in the same environment.
-
-::
-
- (.venv)$ python setup.py install
-
-Finally, install the demo application into the virtual environment.
-
-::
-
- (.venv)$ cd demoapp
- (.venv)$ python setup.py install
-
-Usage
-=====
-
-Both cliff and the demo installed, you can now run the command
-``cliffdemo``.
-
-For basic command usage instructions and a list of the commands
-available from the plugins, run::
-
- (.venv)$ cliffdemo -h
-
-or::
-
- (.venv)$ cliffdemo --help
-
-Run the ``simple`` command by passing its name as argument to ``cliffdemo``.
-
-::
-
- (.venv)$ cliffdemo simple
-
-The ``simple`` command prints this output to the console:
-
-::
-
- sending greeting
- hi!
-
-
-To see help for an individual command, use the ``help`` command::
-
- (.venv)$ cliffdemo help files
-
-The Source
-==========
-
-The ``cliffdemo`` application is defined in a ``cliffdemo`` package
-containing several modules.
-
-main.py
--------
-
-The main application is defined in ``main.py``:
-
-.. literalinclude:: ../../demoapp/cliffdemo/main.py
- :linenos:
-
-The :class:`DemoApp` class inherits from :class:`App` and overrides
-:func:`__init__` to set the program description and version number. It
-also passes a :class:`CommandManager` instance configured to look for
-plugins in the ``cliff.demo`` namespace.
-
-The :func:`initialize_app` method of :class:`DemoApp` will be invoked
-after the main program arguments are parsed, but before any command
-processing is performed and before the application enters interactive
-mode. This hook is intended for opening connections to remote web
-services, databases, etc. using arguments passed to the main
-application.
-
-The :func:`prepare_to_run_command` method of :class:`DemoApp` will be
-invoked after a command is identified, but before the command is given
-its arguments and run. This hook is intended for pre-command
-validation or setup that must be repeated and cannot be handled by
-:func:`initialize_app`.
-
-The :func:`clean_up` method of :class:`DemoApp` is invoked after a
-command runs. If the command raised an exception, the exception object
-is passed to :func:`clean_up`. Otherwise the ``err`` argument is
-``None``.
-
-The :func:`main` function defined in ``main.py`` is registered as a
-console script entry point so that :class:`DemoApp` can be run from
-the command line (see the discussion of ``setup.py`` below).
-
-simple.py
----------
-
-Two commands are defined in ``simple.py``:
-
-.. literalinclude:: ../../demoapp/cliffdemo/simple.py
- :linenos:
-
-:class:`Simple` demonstrates using logging to emit messages on the
-console at different verbose levels.
-
-::
-
- (.venv)$ cliffdemo simple
- sending greeting
- hi!
-
- (.venv)$ cliffdemo -v simple
- prepare_to_run_command Simple
- sending greeting
- debugging
- hi!
- clean_up Simple
-
- (.venv)$ cliffdemo -q simple
- hi!
-
-:class:`Error` always raises a :class:`RuntimeError` exception when it
-is invoked, and can be used to experiment with the error handling
-features of cliff.
-
-::
-
- (.venv)$ cliffdemo error
- causing error
- ERROR: this is the expected exception
-
- (.venv)$ cliffdemo -v error
- prepare_to_run_command Error
- causing error
- ERROR: this is the expected exception
- clean_up Error
- got an error: this is the expected exception
-
- (.venv)$ cliffdemo --debug error
- causing error
- this is the expected exception
- Traceback (most recent call last):
- File ".../cliff/app.py", line 218, in run_subcommand
- result = cmd.run(parsed_args)
- 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')
- RuntimeError: this is the expected exception
- Traceback (most recent call last):
- File "/Users/dhellmann/Envs/cliff/bin/cliffdemo", line 9, in <module>
- load_entry_point('cliffdemo==0.1', 'console_scripts', 'cliffdemo')()
- File ".../demoapp/cliffdemo/main.py", line 33, in main
- return myapp.run(argv)
- 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)
- 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')
- RuntimeError: this is the expected exception
-
-.. _demoapp-list:
-
-list.py
--------
-
-``list.py`` includes a single command derived from
-:class:`cliff.lister.Lister` which prints a list of the files in the
-current directory.
-
-.. literalinclude:: ../../demoapp/cliffdemo/list.py
- :linenos:
-
-:class:`Files` prepares the data, and :class:`Lister` manages the
-output formatter and printing the data to the console.
-
-::
-
- (.venv)$ cliffdemo files
- +---------------+------+
- | Name | Size |
- +---------------+------+
- | build | 136 |
- | cliffdemo.log | 2546 |
- | Makefile | 5569 |
- | source | 408 |
- +---------------+------+
-
- (.venv)$ cliffdemo files -f csv
- "Name","Size"
- "build",136
- "cliffdemo.log",2690
- "Makefile",5569
- "source",408
-
-.. _demoapp-show:
-
-show.py
--------
-
-``show.py`` includes a single command derived from
-:class:`cliff.show.ShowOne` which prints the properties of the named
-file.
-
-.. literalinclude:: ../../demoapp/cliffdemo/show.py
- :linenos:
-
-:class:`File` prepares the data, and :class:`ShowOne` manages the
-output formatter and printing the data to the console.
-
-::
-
- (.venv)$ cliffdemo file setup.py
- +---------------+--------------+
- | Field | Value |
- +---------------+--------------+
- | Name | setup.py |
- | Size | 5825 |
- | UID | 502 |
- | GID | 20 |
- | Modified Time | 1335569964.0 |
- +---------------+--------------+
-
-
-setup.py
---------
-
-The demo application is packaged using distribute_, the modern
-implementation of setuptools.
-
-.. literalinclude:: ../../demoapp/setup.py
- :linenos:
-
-The important parts of the packaging instructions are the
-``entry_points`` settings. All of the commands are registered in the
-``cliff.demo`` namespace. Each main program should define its own
-command namespace so that it only loads the command plugins that it
-should be managing.
-
-.. _distribute: http://packages.python.org/distribute/
diff --git a/docs/source/developers.rst b/docs/source/developers.rst
deleted file mode 100644
index ad02ee4..0000000
--- a/docs/source/developers.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-================
- For Developers
-================
-
-If you would like to contribute to cliff directly, these instructions
-should help you get started. Bug reports, and feature requests are
-all welcome through the `Launchpad project`_.
-
-.. _Launchpad project: https://launchpad.net/python-cliff
-
-Changes to cliff should be submitted for review via the Gerrit tool,
-following the workflow documented at
-http://wiki.openstack.org/GerritWorkflow
-
-Pull requests submitted through GitHub will be ignored.
-
-Bugs should be filed under the `Launchpad project`_.
-
-
-.. note::
-
- Before contributing new features to clif core, please consider
- whether they should be implemented as an extension instead. The
- architecture is highly pluggable precisely to keep the core small.
-
-Building Documentation
-======================
-
-The documentation for cliff is written in reStructuredText and
-converted to HTML using Sphinx. The build itself is driven by make.
-You will need the following packages in order to build the docs:
-
-- Sphinx
-- docutils
-
-Once all of the tools are installed into a virtualenv using
-pip, run ``make docs`` to generate the HTML version of the
-documentation::
-
- $ make docs
- (cd docs && make clean html)
- sphinx-build -b html -d build/doctrees source build/html
- Running Sphinx v1.1.3
- loading pickled environment... done
- building [html]: targets for 1 source files that are out of date
- updating environment: 1 added, 1 changed, 0 removed
- reading sources... [100%] index
- looking for now-outdated files... none found
- pickling environment... done
- done
- preparing documents... done
- writing output... [100%] index
- writing additional files... genindex search
- copying static files... done
- dumping search index... done
- dumping object inventory... done
- build succeeded, 2 warnings.
-
- Build finished. The HTML pages are in build/html.
-
-The output version of the documentation ends up in
-``./docs/build/html`` inside your sandbox.
-
-Running Tests
-=============
-
-The test suite for clif uses tox_, which must be installed separately
-(``pip install tox``).
-
-To run the tests under Python 2.7 and 3.3 as well as PyPy, run ``tox``
-from the top level directory of the git repository.
-
-To run tests under a single version of Python, specify the appropriate
-environment when running tox::
-
- $ tox -e py27
-
-Add new tests by modifying an existing file or creating new script in
-the ``tests`` directory.
-
-.. _tox: http://codespeak.net/tox
-
-.. _developer-templates:
diff --git a/docs/source/history.rst b/docs/source/history.rst
deleted file mode 100644
index e62752c..0000000
--- a/docs/source/history.rst
+++ /dev/null
@@ -1,163 +0,0 @@
-=================
- Release History
-=================
-
-dev
-
-- Fix the arguments passed to commands when they are instantiated to
- pull out help. See https://github.com/dreamhost/cliff/issues/52 for
- details.
-- Add bash command completion. (Contributed by Terry Howe)
-- Use stevedore to load formatter plugins.
-
-1.4.5
-
-- Update the pyparsing dependency to a version that supports both
- Python 2 and Python 3.
-- Add PyPy testing.
-
-1.4.4
-
-- Provide better error handling for unknown commands run from the
- command line. (Contributed by Christophe Chauvet.)
-
-1.4.3
-
-- More stdout encoding issues with Python 2.6.
-
-1.4.2
-
-- Fix an issue with unicode output under Python 2.6. See
- https://github.com/dreamhost/cliff/pull/40 for details.
-
-1.4.1
-
-- Add ``dict2columns`` method to ``ShowOne``. (Contributed by Dean
- Troyer)
-- Pin the requirement for cmd2 more tightly.
-
-1.4
-
-- Store a reference to the InteractiveApp on the App while in
- interactive mode to allow commands to update the interactive
- state. (Contributed by Tomaz Muraus)
-- Remove reliance on distribute, now that it has merged with
- setuptools 0.7. Providing an explicit dependency on setuptools
- breaks updates in some cases, so just fail if it isn't there.
-
-1.3.3
-
- - Restore compatibility with prettytable < 0.7.2 by forcing no
- output if there is no data (instead of printing an empty
- table). Contributed by Dirk Mueller.
- - Update to allow cmd2 version 0.6.5.1. Contributed by Dirk Mueller.
-
-1.3.2
-
- - Add ``convert_underscores`` parameter to ``CommandManager`` ``__init__``
- method to allow underscores to be used in command names. This optional
- argument is defaulted to True to maintain current behavior.
- (contributed by Joe Server)
- - Use flake8_ for style checking.
- - Relax version requirement for PrettyTable dependency to allow
- point releases of 0.7.
-
-.. _flake8: https://pypi.python.org/pypi/flake8
-
-1.3.1
-
- - Sort list of commands in interactive help mode. (contributed by
- Ilya Shakhat)
- - Fix a dependency issue with PyParsing until the cmd2 package can
- release an update setting the version of its dependency based on
- the Python version.
-
-1.3
-
- - Allow user to pass ``argparse_kwargs`` argument to the
- ``build_option_parser`` method. This argument can contain extra
- keyword arguments which are passed to the ``ArgumentParser`` constructor.
- (contributed by Tomaz Muraus)
- - Updated documentation to include dependency on distribute.
-
-1.2.1
-
- - Fix problem with documentation packaging.
- - Fix problem with missing ``izip`` import in ``lister.py``.
-
-1.2
-
- - Fix problem with interactive mode ``help`` command.
- - Disable logging by default but add a ``--log-file`` option to
- re-enable it at runtime.
- - Add support for python 2.6. (contributed by Mark McClain for
- OpenStack Quantum)
-
-1.1.2
-
- - Fix a packaging problem introduced in version 1.1.
-
-1.1
-
- - Move tablib support (JSON, YAML, and HTML formatters) to a
- separate project to comply with Ubuntu packaging requirements. See
- https://github.com/dreamhost/cliff-tablib
-
-1.0
-
- - Add trailing newlines after output from tablib-based formatters
- (JSON, YAML, and HTML). Contributed by Matt Joyce.
- - 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
-
- - Clean up interactive mode flag settting.
- - Add support for Python 2.6, contributed by heavenshell.
- - Fix multi-word commands in interactive mode.
-
-0.6
-
- - Pass the non-global argument list to :func:`initialize_app` to be
- used in initialization work.
-
-0.5.1
-
- - Remove pinned version requirement for PrettyTable until the
- OpenStack clients catch up to the API change.
-
-0.5
-
- - Asking for help about a command by prefix lists all matching
- commands.
- - Add formatters for HTML, JSON, and YAML.
-
-0.4
-
- - Add shell formatter for single objects.
- - Add interactive mode.
- - Expand documentation.
-
-0.3
-
- - Add ShowOne base class for commands that show details about single
- objects.
- - Fix a problem with Lister when there is no data to be printed.
-
-0.2
-
- - Incorporate changes from dtroyer to replace use of optparse in App
- with argparse.
- - Added "help" subcommand to replace ``--help`` option handling in
- subcommands.
-
-0.1
-
- - Initial public release.
- - Included App, CommandManager, Lister, csv and table formatters, a
- demo application, and basic documentation.
diff --git a/docs/source/index.rst b/docs/source/index.rst
deleted file mode 100644
index b474208..0000000
--- a/docs/source/index.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-=======================================================
- cliff -- Command Line Interface Formulation Framework
-=======================================================
-
-cliff is a framework for building command line programs. It uses
-plugins to define sub-commands, output formatters, and other
-extensions.
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- introduction
- demoapp
- list_commands
- show_commands
- complete
- interactive_mode
- classes
- install
- developers
- history
-
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
-.. todolist::
diff --git a/docs/source/install.rst b/docs/source/install.rst
deleted file mode 100644
index ad9a211..0000000
--- a/docs/source/install.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-==============
- Installation
-==============
-
-Python Versions
-===============
-
-cliff is being developed under Python 2.7 and tested with Python 3.2.
-
-Dependencies
-============
-
-cliff depends on distribute_, the updated replacement for
-setuptools. If you have an older version of setuptools installed, `you
-may have trouble installing cliff`_ until you upgrade or set up a
-virtualenv_ using distribute instead (by using ``--use-distribute``).
-
-.. _distribute: http://pypi.python.org/pypi/distribute
-
-.. _you may have trouble installing cliff: https://bitbucket.org/tarek/distribute/issue/91/install-glitch-when-using-pip-virtualenv
-
-.. _virtualenv: http://pypi.python.org/pypi/virtualenv
-
-.. _install-basic:
-
-Basic Installation
-==================
-
-cliff should be installed into the same site-packages area where the
-application and extensions are installed (either a virtualenv or the
-global site-packages). You may need administrative privileges to do
-that. The easiest way to install it is using pip_::
-
- $ pip install cliff
-
-or::
-
- $ sudo pip install cliff
-
-.. _pip: http://pypi.python.org/pypi/pip
-
-Source Code
-===========
-
-The source is hosted on github: https://github.com/dreamhost/cliff
-
-Reporting Bugs
-==============
-
-Please report bugs through the github project:
-https://github.com/dreamhost/cliff/issues
diff --git a/docs/source/interactive_mode.rst b/docs/source/interactive_mode.rst
deleted file mode 100644
index 519e89a..0000000
--- a/docs/source/interactive_mode.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-==================
- Interactive Mode
-==================
-
-In addition to running single commands from the command line, cliff
-supports an interactive mode in which the user is presented with a
-separate command shell. All of the command plugins available from the
-command line are automatically configured as commands within the
-shell.
-
-Refer to the cmd2_ documentation for more details about features of
-the shell.
-
-.. _cmd2: http://packages.python.org/cmd2/index.html
-
-.. todo:: Add details about configuring and interacting with the shell (copy from cmd2 docs)
-
-Example
-=======
-
-The ``cliffdemo`` application enters interactive mode if no command is
-specified on the command line.
-
-::
-
- (.venv)$ cliffdemo
- (cliffdemo) help
-
- Shell commands (type help <topic>):
- ===================================
- cmdenvironment edit hi l list pause r save shell show
- ed help history li load py run set shortcuts
-
- Undocumented commands:
- ======================
- EOF eof exit q quit
-
- Application commands (type help <topic>):
- =========================================
- files help simple file error two part
-
-To obtain instructions for a built-in or application command, use the
-``help`` command:
-
-::
-
- (cliffdemo) help simple
- usage: simple [-h]
-
- A simple command that prints a message.
-
- optional arguments:
- -h, --help show this help message and exit
-
-The commands can be run, including options and arguments, as on the
-regular command line:
-
-::
-
- (cliffdemo) simple
- sending greeting
- hi!
- (cliffdemo) files
- +----------------------+-------+
- | Name | Size |
- +----------------------+-------+
- | .git | 578 |
- | .gitignore | 268 |
- | .tox | 238 |
- | .venv | 204 |
- | announce.rst | 1015 |
- | announce.rst~ | 708 |
- | cliff | 884 |
- | cliff.egg-info | 340 |
- | cliffdemo.log | 2193 |
- | cliffdemo.log.1 | 10225 |
- | demoapp | 408 |
- | dist | 136 |
- | distribute_setup.py | 15285 |
- | distribute_setup.pyc | 15196 |
- | docs | 238 |
- | LICENSE | 11358 |
- | Makefile | 376 |
- | Makefile~ | 94 |
- | MANIFEST.in | 186 |
- | MANIFEST.in~ | 344 |
- | README.rst | 1063 |
- | setup.py | 5855 |
- | setup.py~ | 8128 |
- | tests | 204 |
- | tox.ini | 76 |
- | tox.ini~ | 421 |
- +----------------------+-------+
- (cliffdemo)
diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst
deleted file mode 100644
index d9312b9..0000000
--- a/docs/source/introduction.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-==============
- Introduction
-==============
-
-The cliff framework is meant to be used to create multi-level commands
-such as subversion and git, where the main program handles some basic
-argument parsing and then invokes a sub-command to do the work.
-
-Command Plugins
-===============
-
-Cliff takes advantage of Python's ability to load code dynamically to
-allow the sub-commands of a main program to be implemented, packaged,
-and distributed separately from the main program. This organization
-provides a unified view of the command for *users*, while giving
-developers the opportunity organize source code in any way they see
-fit.
-
-Cliff Objects
-=============
-
-Cliff is organized around four objects that are combined to create a
-useful command line program.
-
-The Application
----------------
-
-An :class:`cliff.app.App` is the main program that you run from the shell
-command prompt. It is responsible for global operations that apply to
-all of the commands, such as configuring logging and setting up I/O
-streams.
-
-The CommandManager
-------------------
-
-The :class:`cliff.commandmanager.CommandManager` knows how to load
-individual command plugins. The default implementation uses
-`setuptools entry points`_ but any mechanism for loading commands can
-be used by replacing the default :class:`CommandManager` when
-instantiating an :class:`App`.
-
-The Command
------------
-
-The :class:`cliff.command.Command` class is where the real work
-happens. The rest of the framework is present to help the user
-discover the command plugins and invoke them, and to provide runtime
-support for those plugins. Each :class:`Command` subclass is
-responsible for taking action based on instructions from the user. It
-defines its own local argument parser (usually using argparse_) and a
-:func:`take_action` method that does the appropriate work.
-
-The Interactive Application
----------------------------
-
-The main program uses an :class:`cliff.interactive.InteractiveApp`
-instance to provide a command-shell mode in which the user can type
-multiple commands before the program exits. Many cliff-based
-applications will be able to use the default implementation of
-:class:`InteractiveApp` without subclassing it.
-
-.. _setuptools entry points: http://packages.python.org/distribute/setuptools.html
-
-.. _argparse: http://docs.python.org/library/argparse.html
diff --git a/docs/source/list_commands.rst b/docs/source/list_commands.rst
deleted file mode 100644
index 2be64e7..0000000
--- a/docs/source/list_commands.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-===============
- List Commands
-===============
-
-One of the most common patterns with command line programs is the need
-to print lists of data. cliff provides a base class for commands of
-this type so that they only need to prepare the data, and the user can
-choose from one of several output formatter plugins to see the list of
-data in their preferred format.
-
-Lister
-======
-
-The :class:`cliff.lister.Lister` base class API extends
-:class:`Command` to allow :func:`take_action` to return data to be
-formatted using a user-selectable formatter. Subclasses should provide
-a :func:`take_action` implementation that returns a two member tuple
-containing a tuple with the names of the columns in the dataset and an
-iterable that will yield the data to be output. See the description of
-:ref:`the files command in the demoapp <demoapp-list>` for details.
-
-List Output Formatters
-======================
-
-cliff is delivered with two output formatters for list
-commands. :class:`Lister` adds a command line switch to let the user
-specify the formatter they want, so you don't have to do any extra
-work in your application.
-
-csv
----
-
-The ``csv`` formatter produces a comma-separated-values document as
-output. CSV data can be imported into a database or spreadsheet for
-further manipulation.
-
-::
-
- (.venv)$ cliffdemo files -f csv
- "Name","Size"
- "build",136
- "cliffdemo.log",2690
- "Makefile",5569
- "source",408
-
-table
------
-
-The ``table`` formatter uses PrettyTable_ to produce output formatted
-for human consumption.
-
-.. _PrettyTable: http://code.google.com/p/prettytable/
-
-::
-
- (.venv)$ cliffdemo files
- +---------------+------+
- | Name | Size |
- +---------------+------+
- | build | 136 |
- | cliffdemo.log | 2546 |
- | Makefile | 5569 |
- | source | 408 |
- +---------------+------+
-
-Other Formatters
-----------------
-
-Formatters using tablib_ to produce JSON, YAML, and HTML are available
-as part of `cliff-tablib`_.
-
-.. _cliff-tablib: https://github.com/dreamhost/cliff-tablib
-
-Creating Your Own Formatter
----------------------------
-
-If the standard formatters do not meet your needs, you can bundle
-another formatter with your program by subclassing from
-:class:`cliff.formatters.base.ListFormatter` and registering the
-plugin in the ``cliff.formatter.list`` namespace.
-
-
-.. _tablib: https://github.com/kennethreitz/tablib
diff --git a/docs/source/show_commands.rst b/docs/source/show_commands.rst
deleted file mode 100644
index 87de6ff..0000000
--- a/docs/source/show_commands.rst
+++ /dev/null
@@ -1,89 +0,0 @@
-===============
- Show Commands
-===============
-
-One of the most common patterns with command line programs is the need
-to print properties of objects. cliff provides a base class for
-commands of this type so that they only need to prepare the data, and
-the user can choose from one of several output formatter plugins to
-see the data in their preferred format.
-
-ShowOne
-=======
-
-The :class:`cliff.show.ShowOne` base class API extends
-:class:`Command` to allow :func:`take_action` to return data to be
-formatted using a user-selectable formatter. Subclasses should provide
-a :func:`take_action` implementation that returns a two member tuple
-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
-<demoapp-show>` for details.
-
-Show Output Formatters
-======================
-
-cliff is delivered with output formatters for show
-commands. :class:`ShowOne` adds a command line switch to let the user
-specify the formatter they want, so you don't have to do any extra
-work in your application.
-
-shell
------
-
-The ``shell`` formatter produces output that can be parsed directly by
-a typical UNIX shell as variable assignments. This avoids extra
-parsing overhead in shell scripts.
-
-::
-
- (.venv)$ cliffdemo file -f shell setup.py
- name="setup.py"
- size="5916"
- uid="527"
- gid="501"
- modified_time="1335655655.0"
-
- (.venv)$ eval "$(cliffdemo file -f shell --prefix example_ setup.py)"
- (.venv)$ echo $example_size
- 5916
-
-table
------
-
-The ``table`` formatter uses PrettyTable_ to produce output
-formatted for human consumption.
-
-.. _PrettyTable: http://code.google.com/p/prettytable/
-
-::
-
- (.venv)$ cliffdemo file setup.py
- +---------------+--------------+
- | Field | Value |
- +---------------+--------------+
- | Name | setup.py |
- | Size | 5825 |
- | UID | 502 |
- | GID | 20 |
- | Modified Time | 1335569964.0 |
- +---------------+--------------+
-
-Other Formatters
-----------------
-
-Formatters using tablib_ to produce JSON, YAML, and HTML are available
-as part of `cliff-tablib`_.
-
-.. _cliff-tablib: https://github.com/dreamhost/cliff-tablib
-
-Creating Your Own Formatter
----------------------------
-
-If the standard formatters do not meet your needs, you can bundle
-another formatter with your program by subclassing from
-:class:`cliff.formatters.base.ShowFormatter` and registering the
-plugin in the ``cliff.formatter.show`` namespace.
-
-
-.. _tablib: https://github.com/kennethreitz/tablib
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 7a16b08..0000000
--- a/setup.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/env python
-
-PROJECT = 'cliff'
-VERSION = '1.4.5'
-
-from setuptools import setup, find_packages
-
-from distutils.util import convert_path
-from fnmatch import fnmatchcase
-import os
-import sys
-
-try:
- long_description = open('README.rst', 'rt').read()
-except IOError:
- long_description = ''
-
-install_requires = [
- 'PrettyTable>=0.6,<0.8',
- 'cmd2>=0.6.7',
- 'pyparsing>=2.0.1',
- 'six',
- 'stevedore',
-]
-
-try:
- import argparse # noqa
-except ImportError:
- install_requires.append('argparse')
-
-
-##############################################################################
-# find_package_data is an Ian Bicking creation.
-
-# Provided as an attribute, so you can append to these instead
-# of replicating them:
-standard_exclude = ('*.py', '*.pyc', '*~', '.*', '*.bak', '*.swp*')
-standard_exclude_directories = ('.*', 'CVS', '_darcs', './build',
- './dist', 'EGG-INFO', '*.egg-info')
-
-
-def find_package_data(where='.', package='',
- exclude=standard_exclude,
- exclude_directories=standard_exclude_directories,
- only_in_packages=True,
- show_ignored=False):
- """
- Return a dictionary suitable for use in ``package_data``
- in a distutils ``setup.py`` file.
-
- The dictionary looks like::
-
- {'package': [files]}
-
- Where ``files`` is a list of all the files in that package that
- don't match anything in ``exclude``.
-
- If ``only_in_packages`` is true, then top-level directories that
- are not packages won't be included (but directories under packages
- will).
-
- Directories matching any pattern in ``exclude_directories`` will
- be ignored; by default directories with leading ``.``, ``CVS``,
- and ``_darcs`` will be ignored.
-
- If ``show_ignored`` is true, then all the files that aren't
- included in package data are shown on stderr (for debugging
- purposes).
-
- Note patterns use wildcards, or can be exact paths (including
- leading ``./``), and all searching is case-insensitive.
-
- This function is by Ian Bicking.
- """
-
- out = {}
- stack = [(convert_path(where), '', package, only_in_packages)]
- while stack:
- where, prefix, package, only_in_packages = stack.pop(0)
- for name in os.listdir(where):
- fn = os.path.join(where, name)
- if os.path.isdir(fn):
- bad_name = False
- for pattern in exclude_directories:
- if (fnmatchcase(name, pattern)
- or fn.lower() == pattern.lower()):
- bad_name = True
- if show_ignored:
- print >> sys.stderr, (
- "Directory %s ignored by pattern %s"
- % (fn, pattern))
- break
- if bad_name:
- continue
- if os.path.isfile(os.path.join(fn, '__init__.py')):
- if not package:
- new_package = name
- else:
- new_package = package + '.' + name
- stack.append((fn, '', new_package, False))
- else:
- stack.append((fn,
- prefix + name + '/',
- package,
- only_in_packages))
- elif package or not only_in_packages:
- # is a file
- bad_name = False
- for pattern in exclude:
- if (fnmatchcase(name, pattern)
- or fn.lower() == pattern.lower()):
- bad_name = True
- if show_ignored:
- print >> sys.stderr, (
- "File %s ignored by pattern %s"
- % (fn, pattern))
- break
- if bad_name:
- continue
- out.setdefault(package, []).append(prefix + name)
- return out
-##############################################################################
-
-
-setup(
- name=PROJECT,
- version=VERSION,
-
- description='Command Line Interface Formulation Framework',
- long_description=long_description,
-
- author='Doug Hellmann',
- author_email='doug.hellmann@gmail.com',
-
- url='https://launchpad.net/python-cliff',
-
- classifiers=['Development Status :: 5 - Production/Stable',
- 'License :: OSI Approved :: Apache Software License',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.2',
- 'Programming Language :: Python :: 3.3',
- 'Intended Audience :: Developers',
- 'Environment :: Console',
- ],
-
- platforms=['Any'],
-
- scripts=[],
-
- provides=['cliff',
- ],
- install_requires=install_requires,
-
- namespace_packages=[],
- packages=find_packages(),
- include_package_data=True,
- # Scan the input for package information
- # to grab any data files (text, images, etc.)
- # associated with sub-packages.
- package_data=find_package_data(PROJECT,
- package=PROJECT,
- only_in_packages=False,
- ),
-
- entry_points={
- 'cliff.formatter.list': [
- 'table = cliff.formatters.table:TableFormatter',
- 'csv = cliff.formatters.commaseparated:CSVLister',
- ],
- 'cliff.formatter.show': [
- 'table = cliff.formatters.table:TableFormatter',
- 'shell = cliff.formatters.shell:ShellFormatter',
- ],
- 'cliff.formatter.completion': [
- 'bash = cliff.complete:CompleteBash',
- 'none = cliff.complete:CompleteNoCode',
- ],
- },
-
- zip_safe=False,
-)
diff --git a/test-requirements.txt b/test-requirements.txt
deleted file mode 100644
index 5b46989..0000000
--- a/test-requirements.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-nose
-mock
-coverage
-pep8
-cmd2
-distribute
-PrettyTable
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index bf5163c..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-[tox]
-envlist = py26,py27,py32,py33,pypy,pep8
-
-[testenv]
-distribute = False
-commands = nosetests -d --with-coverage --cover-inclusive --cover-package cliff []
-deps =
- nose
- mock
- coverage
-
-[testenv:pep8]
-deps = flake8
-commands = flake8 cliff docs/source/conf.py setup.py
-
-[testenv:py26]
-basepython=python2.6