doc: update :func: to :py:func: for modern Sphinx.
[be.git] / doc / hacking.txt
1 **********
2 Hacking BE
3 **********
4
5 Adding commands
6 ===============
7
8 To write a plugin, you simply create a new file in the
9 :file:`libbe/command/` directory.  Take a look at one of the simpler
10 plugins (e.g. :mod:`libbe.command.remove`) for an example of how that
11 looks, and to start getting a feel for the libbe interface.
12
13 See :mod:`libbe.command.base` for the definition of the important
14 classes :class:`~libbe.command.base.Option`,
15 :class:`~libbe.command.base.Argument`,
16 :class:`~libbe.command.base.Command`,
17 :class:`~libbe.command.base.InputOutput`,
18 :class:`~libbe.command.base.StorageCallbacks`, and
19 :class:`~libbe.command.base.UserInterface`.  You'll be subclassing
20 :class:`~libbe.command.base.Command` for your command, but all those
21 classes will be important.
22
23
24 Command completion
25 ------------------
26
27 BE implements a general framework to make it easy to support command
28 completion for arbitrary plugins.  In order to support this system,
29 any of your completable :class:`~libbe.command.base.Argument`
30 instances (in your command's ``.options`` or ``.args``) should be
31 initialized with some valid completion_callback function.  Some common
32 cases are defined in :mod:`libbe.command.util`.  If you need more
33 flexibility, see :mod:`libbe.command.list`\'s ``--sort`` option for an
34 example of extensions via :class:`libbe.command.util.Completer`, or
35 write a custom completion function from scratch.
36
37
38 Adding user interfaces
39 ======================
40
41 Take a look at :mod:`libbe.ui.command_line` for an example.
42 Basically you'll need to setup a
43 :class:`~libbe.command.base.UserInterface` instance for running
44 commands.  More details to come after I write an HTML UI...
45
46
47 Testing
48 =======
49
50 Run any tests in your module with::
51
52     be$ python test.py <python.module.name>
53
54 for example:
55
56     be$ python test.py libbe.command.merge
57
58 For a definition of "any tests", see :file:`test.py`'s
59 ``add_module_tests()`` function.
60
61 Note that you will need to run ``make`` before testing a clean BE
62 branch to auto-generate required files like :file:`libbe/_version.py`.
63
64
65 Profiling
66 =========
67
68 Find out which 20 calls take the most cumulative time (time of
69 execution + childrens' times)::
70
71     $ python -m cProfile -o profile be [command] [args]
72     $ python -c "import pstats; p=pstats.Stats('profile'); p.sort_stats('cumulative').print_stats(20)"
73
74 If you want to find out who's calling your expensive function
75 (e.g. :py:func:`libbe.util.subproc.invoke`), try::
76
77     $ python -c "import pstats; p=pstats.Stats('profile'); p.sort_stats('cumulative').print_callers(20)"
78
79 You can also toss::
80
81     import sys, traceback
82     print >> sys.stderr, '-'*60, '\n', '\n'.join(traceback.format_stack()[-10:])
83
84 into the function itself for a depth-first caller list.
85
86 For a more top-down approach, try::
87
88     $ python -c "import pstats; p=pstats.Stats('profile'); p.sort_stats('cumulative').print_callees(20)"