1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
**********
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. :py:mod:`libbe.command.remove`) for an example of how that
looks, and to start getting a feel for the libbe interface.
See :py: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 :py:mod:`libbe.command.util`. If you need more
flexibility, see :py: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 :py: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 <python.module.name>
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)"
|