********** Hacking BE ********** Adding commands =============== To write a plugin, you simply create a new file in the :file:`libbe/command/` directory. Take a look at one of the simpler plugins (e.g. :mod:`libbe.command.remove`) for an example of how that looks, and to start getting a feel for the libbe interface. See :mod:`libbe.command.base` for the definition of the important classes :class:`~libbe.command.base.Option`, :class:`~libbe.command.base.Argument`, :class:`~libbe.command.base.Command`, :class:`~libbe.command.base.InputOutput`, :class:`~libbe.command.base.StorageCallbacks`, and :class:`~libbe.command.base.UserInterface`. You'll be subclassing :class:`~libbe.command.base.Command` for your command, but all those classes will be important. Command completion ------------------ BE implements a general framework to make it easy to support command completion for arbitrary plugins. In order to support this system, any of your completable :class:`~libbe.command.base.Argument` instances (in your command's ``.options`` or ``.args``) should be initialized with some valid completion_callback function. Some common cases are defined in :mod:`libbe.command.util`. If you need more flexibility, see :mod:`libbe.command.list`\'s ``--sort`` option for an example of extensions via :class:`libbe.command.util.Completer`, or write a custom completion function from scratch. Adding user interfaces ====================== Take a look at :mod:`libbe.ui.command_line` for an example. Basically you'll need to setup a :class:`~libbe.command.base.UserInterface` instance for running commands. More details to come after I write an HTML UI... Testing ======= Run any tests in your module with:: be$ python test.py for example: be$ python test.py libbe.command.merge For a definition of "any tests", see :file:`test.py`'s ``add_module_tests()`` function. Note that you will need to run ``make`` before testing a clean BE branch to auto-generate required files like :file:`libbe/_version.py`. 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)" If you want to find out who's calling your expensive function (e.g. :py:func:`libbe.util.subproc.invoke`), try:: $ python -c "import pstats; p=pstats.Stats('profile'); p.sort_stats('cumulative').print_callers(20)" You can also toss:: import sys, traceback print >> sys.stderr, '-'*60, '\n', '\n'.join(traceback.format_stack()[-10:]) into the function itself for a depth-first caller list. For a more top-down approach, try:: $ python -c "import pstats; p=pstats.Stats('profile'); p.sort_stats('cumulative').print_callees(20)"