diff options
Diffstat (limited to 'doc/README.dev')
-rw-r--r-- | doc/README.dev | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/doc/README.dev b/doc/README.dev new file mode 100644 index 0000000..2a09463 --- /dev/null +++ b/doc/README.dev @@ -0,0 +1,96 @@ +Extending BE +============ + +To write a plugin, you simply create a new file in the becommands +directory. Take a look at one of the simpler plugins (e.g. open.py) +for an example of how that looks, and to start getting a feel for the +libbe interface. + +To fit into the current framework, your extension module should +provide the following elements: + __desc__ + A short string describing the purpose of your plugin + execute(args, manipulate_encodings=True, restrict_file_access=False, + dir=".") + The entry function for your plugin. args is everything from + sys.argv after the name of your plugin (e.g. for the command + `be open abc', args=['abc']). + + manipulate_encodings should be passed through to any calls to + bugdir.BugDir(). See the BugDir documentation for details. + + If restrict_file_access==True, you should call + cmdutil.restrict_file_access(bugdir, path) + before attempting to read or write a file. See the + restrict_file_access documentation for details. + + dir is a directory inside the repository of interest. + + Note: be supports command-completion. To avoid raising errors you + need to deal with possible '--complete' options and arguments. + See the 'Command completion' section below for more information. + help() + Return the string to be output by `be help <yourplugin>', + `be <yourplugin> --help', etc. + +While that's all that's strictly necessary, many plugins (all the +current ones) use libbe.cmdutil.CmdOptionParser to provide a +consistent interface + get_parser() + Return an instance of CmdOptionParser("<usage string>"). You can + alter the parser (e.g. add some more options) before returning it. + +Again, you can just browse around in becommands to get a feel for things. + + +Testing +------- + +Run any doctests in your plugin with + be$ python test.py <yourplugin> +for example + be$ python test.py merge + + +Command completion +------------------ + +BE implements a general framework to make it easy to support command +completion for arbitrary plugins. In order to support this system, +all becommands should properly handle the '--complete' commandline +argument, returning a list of possible completions. For example + $ be --commands + lists options accepted by be and the names of all available becommands. + $ be list --commands + lists options accepted by becommand/list + $ be list --status --commands + lists arguments accepted by the becommand/list --status option + $ be show -- --commands + lists possible vals for the first positional argument of becommand/show +This is a lot of information, but command-line completion is really +convenient for the user. See becommand/list.py and becommand/show.py +for example implementations. The basic idea is to raise + cmdutil.GetCompletions(['list','of','possible','completions']) +once you've determined what that list should be. + +However, command completion is not critical. The first priority is to +implement the target functionality, with fancy shell sugar coming +later. In recognition of this, cmdutil provides the default_complete +function which ensures that if '--complete' is any one of the +arguments, options, or option-arguments, GetCompletions will be raised +with and empty list. + +Profiling +========= + +Find out which 20 calls take the most cumulative time (time of +execution + childrens' times). + + $ python -m cProfile -o profile be [command] [args] + $ python -c "import pstats; p=pstats.Stats('profile'); p.sort_stats('cumulative').print_stats(20)" + +It's often useful to toss a + import sys, traceback + print >> sys.stderr, '-'*60, '\n', '\n'.join(traceback.format_stack()[-10:]) +into expensive functions (e.g. libbe.util.subproc.invoke()), if you're +not sure why they're being called. |