diff options
author | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-03-12 23:29:37 -0400 |
---|---|---|
committer | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-03-12 23:29:37 -0400 |
commit | 20dd5c798592e732d81e1f4fd4a405a2a185f55c (patch) | |
tree | ab5adb46fa99549b6b01d3510ff768b7fd361f24 | |
parent | e1e563bbc5b84f8daf698d18cf9f6e2cf205bb83 (diff) | |
download | cmd2-git-20dd5c798592e732d81e1f4fd4a405a2a185f55c.tar.gz |
Documentation updates
- Added a new section on application life cycle and hook methods
- Moved a warning to a more appropriate location
- Added a note about using allow_redirection to disable output redirection and pipes
-rwxr-xr-x | cmd2.py | 51 | ||||
-rw-r--r-- | docs/freefeatures.rst | 17 | ||||
-rw-r--r-- | docs/hooks.rst | 61 | ||||
-rw-r--r-- | docs/index.rst | 1 | ||||
-rw-r--r-- | docs/install.rst | 15 |
5 files changed, 116 insertions, 29 deletions
@@ -833,7 +833,7 @@ class Cmd(cmd.Cmd): # noinspection PyMethodMayBeStatic def preparse(self, raw): - """Hook that runs before parsing the command-line and as the very first hook for a command. + """Hook method executed just before the command line is interpreted, but after the input prompt is generated. :param raw: str - raw command line input :return: str - potentially modified raw command line input @@ -842,7 +842,7 @@ class Cmd(cmd.Cmd): # noinspection PyMethodMayBeStatic def postparse(self, parse_result): - """Hook that runs immediately after parsing the command-line but before parsed() returns a ParsedString. + """Hook that runs immediately after parsing the command-line but before ``parsed()`` returns a ParsedString. :param parse_result: pyparsing.ParseResults - parsing results output by the pyparsing parser :return: pyparsing.ParseResults - potentially modified ParseResults object @@ -888,8 +888,9 @@ class Cmd(cmd.Cmd): If you wish to fatally fail this command and exit the application entirely, set stop = True. If you wish to just fail this command you can do so by raising an exception: - raise EmptyStatement - will silently fail and do nothing - raise <AnyOtherException> - will fail and print an error message + + - raise EmptyStatement - will silently fail and do nothing + - raise <AnyOtherException> - will fail and print an error message :param statement: - the parsed command-line statement :return: (bool, statement) - (stop, statement) containing a potentially modified version of the statement @@ -909,25 +910,13 @@ class Cmd(cmd.Cmd): """ return stop - def func_named(self, arg): - """Gets the method name associated with a given command. - - If self.abbrev is False, it is always just looks for do_arg. However, if self.abbrev is True, - it allows abbreivated command names and looks for any commands which start with do_arg. + def precmd(self, statement): + """Hook method executed just before the command is processed by ``onecmd()`` and after adding it to the history. - :param arg: str - command to look up method name which implements it - :return: str - method name which implements the given command + :param statement: ParsedString - subclass of str which also contains pyparsing ParseResults instance + :return: ParsedString - a potentially modified version of the input ParsedString statement """ - result = None - target = 'do_' + arg - if target in dir(self): - result = target - else: - if self.abbrev: # accept shortened versions of commands - funcs = [fname for fname in self.keywords if fname.startswith(arg)] - if len(funcs) == 1: - result = 'do_' + funcs[0] - return result + return statement def onecmd_plus_hooks(self, line): """Top-level function called by cmdloop() to handle parsing a line and running the command and all of its hooks. @@ -1039,6 +1028,26 @@ class Cmd(cmd.Cmd): os.remove(self._temp_filename) self._temp_filename = None + def func_named(self, arg): + """Gets the method name associated with a given command. + + If self.abbrev is False, it is always just looks for do_arg. However, if self.abbrev is True, + it allows abbreivated command names and looks for any commands which start with do_arg. + + :param arg: str - command to look up method name which implements it + :return: str - method name which implements the given command + """ + result = None + target = 'do_' + arg + if target in dir(self): + result = target + else: + if self.abbrev: # accept shortened versions of commands + funcs = [fname for fname in self.keywords if fname.startswith(arg)] + if len(funcs) == 1: + result = 'do_' + funcs[0] + return result + def onecmd(self, line): """ This executes the actual do_* method for a command. diff --git a/docs/freefeatures.rst b/docs/freefeatures.rst index a036973d..ddde62ca 100644 --- a/docs/freefeatures.rst +++ b/docs/freefeatures.rst @@ -65,7 +65,7 @@ quotation marks if it is more than a one-word command. .. note:: - if you wish to disable cmd2's consumption of command-line arguments, you can do so by setting the ``allow_cli_args`` + If you wish to disable cmd2's consumption of command-line arguments, you can do so by setting the ``allow_cli_args`` attribute of your ``cmd2.Cmd`` class instance to ``False``. This would be useful, for example, if you wish to use someting like Argparse_ to parse the overall command line arguments for your application:: @@ -105,6 +105,21 @@ app's value of ``self.redirector`` to use a different string for output redirect line1 line2 +.. note:: + + If you wish to disable cmd2's output redirection and pipes features, you can do so by setting the ``allow_redirection`` + attribute of your ``cmd2.Cmd`` class instance to ``False``. This would be useful, for example, if you want to restrict + the ability for an end user to write to disk or interact with shell commands for security reasons:: + + from cmd2 import Cmd + class App(Cmd): + def __init__(self): + self.allow_redirection = False + + cmd2's parser will still treat the ``>``, ``>>``, and `|` symbols as output redirection and pipe symbols and will strip + arguments after them from the command line arguments accordingly. But output from a command will not be redirected + to a file or piped to a shell command. + .. _pywin32: http://sourceforge.net/projects/pywin32/ .. _xclip: http://www.cyberciti.biz/faq/xclip-linux-insert-files-command-output-intoclipboard/ diff --git a/docs/hooks.rst b/docs/hooks.rst new file mode 100644 index 00000000..3849cce0 --- /dev/null +++ b/docs/hooks.rst @@ -0,0 +1,61 @@ +.. cmd2 documentation for application and command lifecycle and the hooks which are available + +cmd2 Application Lifecyle and Hooks +=================================== + +The typical way of starting a cmd2 application is as follows:: + + from cmd2 import Cmd + class App(Cmd): + # customized attributes and methods here + app = App() + app.cmdloop() + +There are several pre-existing methods and attributes which you can tweak to control the overall behavior of your +application before, during, and after the main loop. + +Application Lifecycle Hook Methods +---------------------------------- +The ``preloop`` and ``postloop`` methods run before and after the main loop, respectively. + +.. automethod:: cmd2.Cmd.preloop + +.. automethod:: cmd2.Cmd.postloop + +Application Lifecycle Attributes +-------------------------------- + +There are numerous attributes (member variables of the ``cmd2.Cmd``) which have a signficiant effect on the applicaiton +behavior upon entering or during the main loop. A partial list of some of the more important ones is presented here: + +- **intro**: *str* - if provided this serves as the intro banner printed once at start of application, after ``preloop`` runs +- **allow_cli_args**: *bool* - if True (default), then searches for -t or --test at command line to invoke transcript testing mode instead of a normal main loop + and also processes any commands provided as arguments on the command line just prior to entering the main loop +- **echo**: *bool* - if True, then the command line entered is echoed to the screen (most useful when running scripts) +- **prompt**: *str* - sets the prompt which is displayed, can be dynamically changed based on applicatoin state and/or + command results + + +Command Processing Hooks +------------------------ + +Inside the main loop, every time the user hits <Enter> the line is processed by the ``onecmd_plus_hooks`` method. + +.. automethod:: cmd2.Cmd.onecmd_plus_hooks + +As the ``onecmd_plus_hooks`` name implies, there are a number of *hook* methods that can be defined in order to inject +applicaiton-specific behavior at various points during the processing of a line of text entered by the user. ``cmd2`` +increases the 2 hooks provided by ``cmd`` (**precmd** and **postcmd**) to 6 for greater flexibility. Here are +the various hook methods, presented in chronological order starting with the ones called earliest in the process. + +.. automethod:: cmd2.Cmd.preparse + +.. automethod:: cmd2.Cmd.postparse + +.. automethod:: cmd2.Cmd.postparsing_precmd + +.. automethod:: cmd2.Cmd.precmd + +.. automethod:: cmd2.Cmd.postcmd + +.. automethod:: cmd2.Cmd.postparsing_postcmd diff --git a/docs/index.rst b/docs/index.rst index 2251b435..c532c1c6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -65,6 +65,7 @@ Contents: settingchanges unfreefeatures integrating + hooks alternatives Compatibility diff --git a/docs/install.rst b/docs/install.rst index 248d3c3c..dae100a9 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -24,13 +24,6 @@ install from PyPI_. sudo pip install <package_name> -.. warning:: - - Versions of ``cmd2`` before 0.7.0 should be considered to be of unstable "beta" quality and should not be relied upon - for production use. If you cannot get a version >= 0.7 from either pip or your OS repository, then we recommend - installing from GitHub - see :ref:`github`. - - Requirements for Installing ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * If you have Python 2 >=2.7.9 or Python 3 >=3.4 installed from `python.org @@ -51,6 +44,8 @@ Requirements for Installing python -m pip install -U pip setuptools +.. _`pip_install`: + Use pip for Installing ~~~~~~~~~~~~~~~~~~~~~~ @@ -88,6 +83,12 @@ For Python 3:: This will also install the required 3rd-party dependencies. +.. warning:: + + Versions of ``cmd2`` before 0.7.0 should be considered to be of unstable "beta" quality and should not be relied upon + for production use. If you cannot get a version >= 0.7 from your OS repository, then we recommend + installing from either pip or GitHub - see :ref:`pip_install` or :ref:`github`. + Deploy cmd2.py with your project ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |