7
By convention, most plugins are named brz-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 brz-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.
17
We encourage plugin authors to make their plugins publicly available
18
under the same license as Breezy itself, namely GPL v2. However, there
19
is no requirement to do so. You are free to create Breezy plugins for
20
private or internal use within your company and not distribute them.
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.
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*.
37
To learn about Launchpad project registration, see
38
https://help.launchpad.net/Projects/Registering.
40
To add your plugin to the registry:
42
1. Fetch a copy of the lp:brz-alldocs project.
43
2. Edit plugin-registry.ini and commit the change.
44
3. Submit a merge proposal.
46
A Breezy 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.
51
Information on adding your plugin to this guide is provided later in this
58
To ensure your plugin under development is available to Breezy, set
59
the ``BRZ_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)
62
or put a symbolic link in that area pointing to your plugin under
63
test. Finally you can use ``BRZ_PLUGINS_AT`` to point to a specific
64
directory for a specific plugin (separated by your platform's value of
67
export BRZ_PLUGINS_AT=qbrz@/home/me/qbrz:explorer@/home/me/explorer
69
You can disable loading plugins with ``BRZ_DISABLE_PLUGINS``.
71
If you want to stop loading all but installed plugins you can use:
75
We also encourage plugin developers to provide tests for their plugin.
76
When you run ``brz selftest``, Breezy 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::
87
Plugins in this guide have their documentation automatically
88
generated from the online help provided for a plugin. Sections are
91
1. High level introduction
92
2. Plugin-specific help topics (COMING SOON)
93
3. Commands defined or extended by the plugin.
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::
98
_xxx_tutorial = """XXX Tutorial
100
Welcome to xxx, your new best friend. ...
102
topic_registry.register('xxx-tutorial',
106
Command level help is specified in the docstring for the relevant
107
``cmd_xxx`` Command class.
111
The final documentation needs to be in ReST format. Keep in mind though
112
that the documentation should also be readable via ``brz help xxx`` so
113
it's best to keep markup to a reasonable minimum.
116
Providing custom code via hooks
117
-------------------------------
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>`_.
123
Adding a new hook is done with, for example::
126
breezy.branch.Branch.hooks.install_named_hook('post_push', post_push_hook,
129
For more information on how to write hooks,
130
see http://doc.bazaar-vcs.org/development/en/user-guide/hooks.html.
133
Defining a new command
134
----------------------
136
Breezy commands are defined as subclasses of ``breezy.commands.Command``, the
137
command name is specified by the name of the subclass, and they must be
138
registered into ``brz`` with the ``breezy.commands.register_command`` function
139
at module import time.
141
To define the ``brz foo-bar`` command::
143
from breezy.commands import Command, register_command
145
class cmd_foo_bar(Command):
146
# see breezy/builtins.py for information about what to put here
149
register_command(cmd_foo_bar)
151
If the class name starts with ``cmd_``, the prefix will get dropped
152
and ``_`` will be replaced by ``-`` characters.
158
Plugin data falls into several categories:
160
* Configuration settings.
161
* Data the user can see and version control.
162
* Data behind the scenes.
164
Configuration settings are often stored in ``branch.conf``,
165
``locations.conf`` or ``bazaar.conf``.
167
User-visible data for a plugin called xxx should be stored in
168
``.brzmeta/xxx``. If mutiple files are desirable, make ``.brzmeta/xxx``
169
a directory or give them a common prefix within ``.brzmeta``, e.g.
170
``xxx-foo``, ``xxx-bar``.
172
Data managed behind the scenes should be stored in ``.brz``.
173
Depending on the nature of the data, it may belong in a subdirectory
174
within there, e.g. ``checkout``, ``branch`` or ``repository``.
175
It's your responsibility to ensure behind-the-scenes data is
176
propagated and merged appropriately via custom code. You may want
177
to use existing hooks for this or ask for new hooks to help. The
178
`Branch Baggage <http://wiki.bazaar.canonical.com/DraftSpecs/BranchBaggage>`_
179
feature may assist as well once implemented.
185
It is highly recommended that plugins define a version number. This
186
is displayed by ``brz plugins`` and by the ``qplugins`` GUI dialog.
187
To do this, define ``version_info`` in ``__init__.py`` like this::
189
version_info = (1, 2, 0, 'beta', 1)
191
Plugins can also declare other useful metadata such as a mimimum
192
breezy version, new transports and storage formats. See
193
`Plugin API <plugin-api>`_ for details.
199
When brz starts up, it imports every plugin, so plugins can degrade
200
performance when they're not being used. However, sub-modules are not
201
loaded, only the main name.
203
One way you can avoid this slowdown is by putting most of your code
204
in sub-modules, so that the plugin, itself, is small. All you really
205
need in the ``__init__.py`` is the plugin's Command classes, the
206
commands to register them, and the optional ``test_suite()``.
208
Another way to reduce your plugin's overhead is to use the breezy
209
lazy_import functionality. That looks something like this::
211
from breezy.lazy_import import lazy_import
212
lazy_import(globals(), """
214
branch as _mod_branch,
220
Lazy importing only works for packages and modules, not classes or
221
functions. It defers the import until you actually need it.
227
`Integrating with Breezy <http://wiki.bazaar.canonical.com/Integrating_with_Breezy>`_
228
explains how to do such operations as ``add``, ``commit``, ``log`` and more.
230
Reference documentation on some key APIs is provided below. For a more
231
detailed reference, see the `complete breezy API documentation <api/index>`_.
240
Base class for commands. Commands are the heart of the command-line brz
243
The command object mostly handles the mapping of command-line parameters into
244
one or more breezy operations, and of the results into textual output.
246
Commands normally don't have any state. All their arguments are passed in to
247
the run method. (Subclasses may take a different policy if the behaviour of the
248
instance needs to depend on e.g. a shell plugin and not just its Python class.)
250
The docstring for an actual command should give a single-line summary, then a
251
complete description of the command. A grammar description will be inserted.
254
Other accepted names for this command.
257
List of argument forms, marked with whether they are optional,
260
For example: ``['to_location', 'from_branch?', 'file*']`` means:
262
* 'to_location' is required
263
* 'from_branch' is optional
264
* 'file' can be specified 0 or more times
267
List of options that may be given for this command. These can be either
268
strings, referring to globally-defined options, or option objects.
269
Retrieve through options().
272
If true, this command isn't advertised. This is typically for commands
273
intended for expert users.
276
Actually run the command. This is invoked with the options and arguments
277
bound to keyword parameters.
279
Return 0 or None if the command was successful, or a non-zero shell error
280
code if not. It's OK for this method to allow an exception to raise up.
283
register_command Function
284
~~~~~~~~~~~~~~~~~~~~~~~~~
286
Utility function to help register a command.
289
Command subclass to register
292
If true, allow overriding an existing command of the same name; the old
293
command is returned by this function. Otherwise it is an error to try to
294
override an existing command.