~bzr/bzr-alldocs/trunk

26.1.5 by Ian Clatworthy
Add plugin installation and development sections under Introduction
1
Developing a plugin
2
===================
3
4
Naming
5
------
6
7
By convention, most plugins are named bzr-xxx and are installed into a
8
directory called xxx. Note that the directory name must be a legal
9
Python package name, so a plugin called bzr-xxx-yyy need to be installed
10
into a directory called xxx_yyy, i.e. '-' in a plugin name gets mapped to
11
an underscore in the directory name.
12
13
14
Licensing
15
---------
16
17
We encourage plugin authors to make their plugins publicly available
18
under the same license as Bazaar itself, namely GPL v2. However, there
19
is no requirement to do so. You are free to create Bazaar plugins for
20
private or internal use within your company and not distribute them.
21
22
By sharing your work, a larger number of people benefit. In our experience,
23
plugin developers also benefit heavily by having more users involved in
24
the design, testing, bug fixing and longer term maintenance. In other words,
25
sharing leads to a better plugin faster.
26
27
28
Registration
29
------------
30
31
If you decide to make your plugin available to others, you are welcome to
32
have it hosted on Launchpad and added to our plugins registry.
33
Non-experimental plugins that you or others in the community can support
34
may also be added to the Plugins Guide, i.e. inclusion in the Guide implies
35
a certain degree of *this works as advertised*.
36
37
To learn about Launchpad project registration, see
38
https://help.launchpad.net/Projects/Registering.
39
40
To add your plugin to the registry:
41
42
1. Fetch a copy of the lp:bzr-alldocs project.
43
2. Edit plugin-registry.ini and commit the change.
44
3. Submit a merge proposal.
45
46
A Bazaar developer will review your change and make some basic checks, e.g.
47
the one line summary (``purpose``) is clear and the branch URL is correct.
48
Once merged, your plugin will be registered and should appear shortly
49
afterwards in the generated web page.
50
51
Information on adding your plugin to this guide is provided later in this
52
document.
53
54
55
Testing
56
-------
57
58
To ensure your plugin under development is available to Bazaar, set
59
the ``BZR_PLUGIN_PATH`` environment variable to its parent directory.
60
Alternatively, you may wish to develop your plugin within a directory
61
under your personal plugins area (``~/.bazaar/plugins`` on GNU/Linux)
68 by Jonathan Riddell
expand documentation for using environment variables to specify which plugins to load
62
or put a symbolic link in that area pointing to your plugin under
63
test.  Finally you can use ``BZR_PLUGINS_AT`` to point to a specific
64
directory for a specific plugin (separated by your platform's value of
65
os.pathsep), e.g.
66
67
  export BZR_PLUGINS_AT=qbzr@/home/me/qbzr:explorer@/home/me/explorer
68
69
You can disable loading plugins with ``BZR_DISABLE_PLUGINS``.
70
71
If you want to stop loading all but installed plugins you can use:
72
73
  BZR_PLUGIN_PATH=-site
26.1.5 by Ian Clatworthy
Add plugin installation and development sections under Introduction
74
75
We also encourage plugin developers to provide tests for their plugin.
76
When you run ``bzr selftest``, Bazaar will scan all its plugins to see if
77
they contain a function named ``test_suite()``.  For each plugin that does,
78
it calls the function and adds any resulting tests to the master test suite.
79
To run just the tests for plugin xxx, the command is::
80
81
  bzr selftest bp.xxx
82
83
84
Providing help
85
--------------
86
87
Plugins in this guide have their documentation automatically
88
generated from the online help provided for a plugin. Sections are
89
ordered as follows:
90
91
1. High level introduction
26.1.11 by Ian Clatworthy
Update the dev guide to note that plugin-specific topics aren't included yet
92
2. Plugin-specific help topics (COMING SOON)
26.1.5 by Ian Clatworthy
Add plugin installation and development sections under Introduction
93
3. Commands defined or extended by the plugin.
94
95
High level help is specified in the docstring for the ``__init__.py`` module.
96
You can register plugin-specific help topics in ``__init__.py`` like this::
97
98
  _xxx_tutorial = """XXX Tutorial
99
100
  Welcome to xxx, your new best friend. ...
101
  """
102
  topic_registry.register('xxx-tutorial',
103
      _xxx_tutorial,
104
      'How to use xxx')
105
106
Command level help is specified in the docstring for the relevant 
107
``cmd_xxx`` Command class.
108
109
.. note::
110
111
   The final documentation needs to be in ReST format. Keep in mind though
112
   that the documentation should also be readable via ``bzr help xxx`` so
113
   it's best to keep markup to a reasonable minimum.
114
   
115
116
Providing custom code via hooks
117
-------------------------------
118
119
Hooks let you provide custom code at certain processing points.
120
The available hook point are documented in the `User Reference
121
<http://doc.bazaar-vcs.org/development/en/user-reference/index.html#hooks>`_.
122
123
Adding a new hook is done with, for example::
124
125
  import bzrlib.branch
126
  bzrlib.branch.Branch.hooks.install_named_hook('post_push', post_push_hook,
127
                                 'My post_push hook')
128
129
For more information on how to write hooks,
130
see http://doc.bazaar-vcs.org/development/en/user-guide/hooks.html.
131
132
133
Defining a new command
134
----------------------
135
136
Bazaar commands are defined as subclasses of ``bzrlib.commands.Command``, the
137
command name is specified by the name of the subclass, and they must be
138
registered into ``bzr`` with the ``bzrlib.commands.register_command`` function
139
at module import time.
140
141
To define the ``bzr foo-bar`` command::
142
143
  from bzrlib.commands import Command, register_command
144
145
  class cmd_foo_bar(Command):
146
    # see bzrlib/builtins.py for information about what to put here
147
    pass
148
149
  register_command(cmd_foo_bar)
150
151
If the class name starts with ``cmd_``, the prefix will get dropped
152
and ``_`` will be replaced by ``-`` characters.
153
154
155
Extending an existing command
156
-----------------------------
157
158
TO BE DOCUMENTED.
159
160
161
GUI integration
162
---------------
163
164
TO BE DOCUMENTED. Once supported, explain how to:
165
166
* Register a toolset in the toolbox, providing easy access to new commands.
167
* Define custom widgets for command options in qrun.
168
169
170
Managing data
171
-------------
172
173
Plugin data falls into several categories:
174
175
* Configuration settings.
176
* Data the user can see and version control.
177
* Data behind the scenes.
178
179
Configuration settings are often stored in ``branch.conf``,
180
``locations.conf`` or ``bazaar.conf``.
181
182
User-visible data for a plugin called xxx should be stored in
183
``.bzrmeta/xxx``. If mutiple files are desirable, make ``.bzrmeta/xxx``
184
a directory or give them a common prefix within ``.bzrmeta``, e.g.
185
``xxx-foo``, ``xxx-bar``.
186
187
Data managed behind the scenes should be stored in ``.bzr``.
188
Depending on the nature of the data, it may belong in a subdirectory
189
within there, e.g. ``checkout``, ``branch`` or ``repository``.
190
It's your responsibility to ensure behind-the-scenes data is
191
propagated and merged appropriately via custom code. You may want
192
to use existing hooks for this or ask for new hooks to help. The
193
`Branch Baggage <http://wiki.bazaar.canonical.com/DraftSpecs/BranchBaggage>`_
194
feature may assist as well once implemented.
195
196
197
Useful metadata
198
---------------
199
200
It is highly recommended that plugins define a version number. This
201
is displayed by ``bzr plugins`` and by the ``qplugins`` GUI dialog.
202
To do this, define ``version_info`` in ``__init__.py`` like this::
203
204
  version_info = (1, 2, 0, 'beta', 1)
205
206
Plugins can also declare other useful metadata such as a mimimum
207
bzrlib version, new transports and storage formats. See
208
`Plugin API <http://doc.bazaar-vcs.org/bzr.dev/developers/plugin-api.html>`_
209
for details.
210
211
212
Performance tips
213
----------------
214
215
When bzr starts up, it imports every plugin, so plugins can degrade
216
performance when they're not being used. However, sub-modules are not
217
loaded, only the main name.
218
219
One way you can avoid this slowdown is by putting most of your code
220
in sub-modules, so that the plugin, itself, is small. All you really
221
need in the ``__init__.py`` is the plugin's Command classes, the
222
commands to register them, and the optional ``test_suite()``.
223
224
Another way to reduce your plugin's overhead is to use the bzrlib
225
lazy_import functionality. That looks something like this::
226
227
  from bzrlib.lazy_import import lazy_import
228
  lazy_import(globals(), """
229
  from bzrlib import (
230
      branch as _mod_branch,
231
      option,
232
      workingtree,
233
      )
234
  """)
235
236
Lazy importing only works for packages and modules, not classes or
237
functions. It defers the import until you actually need it.
238
239
240
Adding your plugin to the Plugins Guide
241
---------------------------------------
242
243
To add your (registered) plugin to the Plugins Guide, submit a merge
244
proposal to lp:bzr-alldocs. Here are the steps to follow:
245
246
1. Use ``scripts/document-plugin.py`` to generate ``plugins/en/xxx-plugin.txt``.
34 by Ian Clatworthy
Smarter detection of plugin registry and generated file locations
247
   To do this, run the above script in either the top level directory
248
   (where ``plugins-registry.ini`` is) or in the ``plugins/en`` directory,
249
   passing the plugin name as the argument.
26.1.5 by Ian Clatworthy
Add plugin installation and development sections under Introduction
250
251
2. Add *xxx-plugin* to the relevant category in ``plugins/en/index.txt``.
252
253
3. Test your changes::
254
255
     cd plugins/en
256
     make html
257
     Open _build/html/index.html in your web browser.
258
     Check your plugin appears as expected and it's help formatted correctly.
259
260
4. Add the new file and commit the changes.
261
262
5. Submit a merge proposal with your changes.
263
264
265
Learning more
266
-------------
267
268
`Integrating with Bazaar <http://wiki.bazaar.canonical.com/Integrating_with_Bazaar>`_
269
explains how to do such operations as ``add``, ``commit``, ``log`` and more.
270
271
Reference documentation on some key APIs is provided below. For a more
272
detailed reference, see the `complete bzrlib API documentation
273
<http://starship.python.net/crew/mwh/bzrlibapi/>`_.
274
275
276
Mini API Reference
277
------------------
278
279
Command Class
280
~~~~~~~~~~~~~
281
282
Base class for commands. Commands are the heart of the command-line bzr
283
interface.
284
285
The command object mostly handles the mapping of command-line parameters into
286
one or more bzrlib operations, and of the results into textual output.
287
288
Commands normally don't have any state. All their arguments are passed in to
289
the run method. (Subclasses may take a different policy if the behaviour of the
290
instance needs to depend on e.g. a shell plugin and not just its Python class.)
291
292
The docstring for an actual command should give a single-line summary, then a
293
complete description of the command. A grammar description will be inserted.
294
295
aliases
296
    Other accepted names for this command.
297
298
takes_args
299
    List of argument forms, marked with whether they are optional,
300
    repeated, etc.
301
302
    For example: ``['to_location', 'from_branch?', 'file*']`` means:
303
304
    * 'to_location' is required
305
    * 'from_branch' is optional
306
    * 'file' can be specified 0 or more times
307
308
takes_options
309
    List of options that may be given for this command. These can be either
310
    strings, referring to globally-defined options, or option objects.
311
    Retrieve through options().
312
313
hidden
314
    If true, this command isn't advertised. This is typically for commands
315
    intended for expert users.
316
317
run()
318
    Actually run the command. This is invoked with the options and arguments
319
    bound to keyword parameters.
320
321
    Return 0 or None if the command was successful, or a non-zero shell error
322
    code if not. It's OK for this method to allow an exception to raise up.
323
324
325
register_command Function
326
~~~~~~~~~~~~~~~~~~~~~~~~~
327
328
Utility function to help register a command.
329
330
param *cmd*
331
  Command subclass to register
332
333
param *decorate*
334
  If true, allow overriding an existing command of the same name; the old
335
  command is returned by this function. Otherwise it is an error to try to
336
  override an existing command.