cmdln.py -- an improved cmd.py
| Home | http://trentm.com/projects/cmdln/ |
|---|---|
| License | MIT (more details at OSI) |
| Platforms | Windows, Linux, Mac OS X, Unix |
| Current Version | 1.1.1 |
| Dev Status | well tested; a similar design has been used in various heavily used scripts at ActiveState for a while; some features of this module *are* faily new though |
| Requirements | Python >= 2.3, (Python >= 2.4 to use some features using decorators) |
| Documentation |
Why cmdln.py?
cmdln.py fixes some of the design flaws in cmd.py and takes
advantage of new Python stdlib modules (e.g. optparse) so that it is
more useful (and convenient) for implementing command-line
scripts/shells.
The main differences are:
- Instead of passing a command line to subcommand handlers, already parsed options and an args list are provided. This is much more convenient when the complexity of commands grows to have options, arguments with spaces, etc.
- By default the help for a subcommand is the associated method's docstring. Default help output is also much nicer and some template vars can be used to automatically fill in some details.
- Defining command aliases is easy (using a new decorator).
- A
.main()method is provided to make using yourCmdlnsubclass a little cleaner. - The error handling (and associated hooks) have been improved so that
trapping and dealing with errors in sub-command handlers (the
do_*methods) can be done -- as might be wanted for a slighty more robust shell.
Install notes and intro docs are below. Please send any feedback to Trent Mick.
Install Notes
Download the latest cmdln.py source package, unzip it, and run
python setup.py install:
unzip cmdln-1.1.1.zip
cd cmdln-1.1.1
python setup.py install
If your install fails then please visit the Troubleshooting FAQ.
This will install cmdln.py into your Python's site-packages area.
cmdln.py has no external dependencies that aren't part of the Python
standard library so, if you like, you may simple copy cmdln.py into
your own Python packages.
Introduction
cmdln.py is an extension of Python's default cmd.py module that
provides "a simple framework for writing line-oriented command
interpreters". The idea (with both cmd.py and cmdln.py) is to be
able to quickly build multi-sub-command tools (think cvs or svn)
and/or simple interactive shells (think gdb or pdb). cmdln.py's
extensions make it more natural to write sub-commands, integrate
optparse for simple
option processing, and make having good command documentation easier.
For example, here is most of the scaffolding for the svn
status command. (Note:
Some options were removed and the doc string truncated for brevity. See
examples/svn.py for a more complete scaffold
re-implementation of the svn command-line interface.)
#!/usr/bin/env python
import sys
import cmdln
class MySVN(cmdln.Cmdln):
name = "svn"
@cmdln.alias("stat", "st")
@cmdln.option("-u", "--show-updates", action="store_true",
help="display update information")
@cmdln.option("-v", "--verbose", action="store_true",
help="print extra information")
def do_status(self, subcmd, opts, *paths):
"""${cmd_name}: print the status of working copy files and directories
${cmd_usage}
${cmd_option_list}
"""
print "'svn %s' opts: %s" % (subcmd, opts)
print "'svn %s' paths: %s" % (subcmd, paths)
if __name__ == "__main__":
svn = MySVN()
sys.exit(svn.main())
The base cmdln.Cmdln class is providing a number of things for free
here. (1) There is a reasonable default help string:
$ python svn.py
Usage:
svn COMMAND [ARGS...]
svn help [COMMAND]
Commands:
help (?) give detailed help on a specific command
status (st, stat) print the status of working copy files and dire...
(2) A default help command is provided for getting detailed help on
specific sub-commands. This is how many such tools already work (e.g.
svn and p4, the command-line interface for the Perforce source
control system).
$ python svn.py help status
status (stat, st): print the status of working copy files and directories.
Usage:
svn status [PATHS...]
Options:
-h, --help show this help message and exit
-v, --verbose print extra information
-u, --show-updates display update information
(3) It makes parsing the command line easy (with optparse
integration):
$ python svn.py status -v foo bar baz
'svn status' opts: {'show_updates': None, 'verbose': True}
'svn status' paths: ('foo', 'bar', 'baz')
and (4) defining command aliases easy:
$ python svn.py st -v foo bar baz
'svn st' opts: {'show_updates': None, 'verbose': True}
'svn st' paths: ('foo', 'bar', 'baz')
Read the Getting Started docs next.
Change Log
v1.1.1
- Issue 1: fix readline-based completion and history (from Joshua Gallagher).
- Experimental automatic bash completion support. See r8 for details: svn diff -r7:8 http://cmdln.googlecode.com/svn/trunk/cmdln.py
- Some minor improvements to line2argv processing (r7).
- Fix "${help_list}" layout problems and more closely follow optparse option list help output (r4).
- Moved project to Google Code (http://code.google.com/p/cmdln) for Subversion there and for the issue tracker.
v1.0.0
- [backward incompat]
Cmdln.main()no longer takes anoptparserargument. Top-level option parsing has been changed so that top-level options for aCmdlnsubclass can more naturally be defined and handled on the class definition. Changes:Cmdln.main()callsself.get_optparserto get an option handler. Subclasses should overload this method for custom top-level options.- After option parsing, but before sub-command handling, the
self.postoptparse()hook is called.
- Add a
versionattribute onCmdlnsubclasses. If set, the default top-level option parser will have a--versionattribute. - [backward incompat] Simplify the StopProcessing/opts.stop handling for option handling in subcommands. The "opts" argument to "do_*" sub-command functions will no longer have a "stop" value. StopProcessing is now called StopOptionProcessing. This shouldn't affect simple usage of cmdln.py.
v0.8.3
- Fix a bug where errors with passing an incorrect number of args to functions in do_foo() implementations would be masked.
v0.8.2
- Remove the implicit prefixing of a command's help string with "${cmdname}: ". This can be surprising for the case of a "helpFOO" function without an associated "cmd_FOO" function.
v0.8.1
- Work on getting started docs.
- Improve the ${command_list} output to better handle long command names.
- Add ${cmd_usage} template var: infering a usage from the command handler signature.
- Add ${option_list} template var for the option table for the whole Cmdln class and add this to the default help output.
v0.8.0
- First version at which I started stabilizing it for public release.
I've been batting around modules to improve on
cmd.pyfor a long time -- variously calledtm/cmd.py, 'cmd2.py', 'tmCmd.py', 'linecmd.py', 'argvcmd.py', etc.

