bzrlib has a very flexible internal structure allowing plugins for many
operations. Plugins can add commands, new storage formats, diff and merge
features and more. This document provides an overview of the API and
conventions for plugin authors.

If you’re writing a plugin and have questions not addressed by this
document, please ask us.

Plugins can export a summary of what they provide, and what versions of bzrlib
they are compatible with. This allows tools to be written to work with plugins,
such as to generate a directory of plugins, or install them via a
symlink/checkout to ~/.bazaar/plugins.

This interface allows bzr to interrogate a plugin without actually loading
it. This is useful because loading a plugin may have side effects such
as registering or overriding commands, or the plugin may raise an error,
if for example a prerequisite is not present.

A plugin that supports the bzr plugin metadata protocol will do two
things. Firstly, the setup.py for the plugin will guard the call to
setup():

if__name__=='main':setup(...)

Secondly, the setup module will have one or more of the following variables
present at module scope. Any variables that are missing will be given the
defaults from the table. An example of every variable is provided after
the full list.

Variable

Default

Definition

bzr_plugin_name

None

The name the plugin package should be
given on disk. The plugin is then
available to python at
bzrlib.plugins.NAME

bzr_commands

[]

A list of the commands that the plugin
provides. Commands that already exist
in bzr and are decorated by the plugin
do not need to be listed (but it is not
harmful if you do list them).

bzr_plugin_version

None

A version_info 5-tuple with the plugins
version.

bzr_minimum_version

None

A version_info 3-tuple for comparison
with the bzrlib minimum and current
version, for determining likely
compatibility.

bzr_maximum_version

None

A version_info 3-tuple like
bzr_minimum_version but checking the
upper limits supported.

bzr_control_formats

{}

A dictionary of descriptions of version
control directories. See
Control Formats below.

bzr_checkout_formats

{}

A dictionary of tree_format_string ->
human description strings, for tree
formats that drop into the
.bzr/checkout metadir system.

Because disk format detection for formats that bzr does not understand at
all can be useful, we allow a declarative description of the shape of a
control directory. Each description has a name for showing to users, and a
dictonary of relative paths, and the content needed at each path. Paths
that end in ‘/’ are required to be directories and the value for that key
is ignored. Other paths are required to be regular files, and the value
for that key is either None, in which case the file is statted but the
content is ignored, or a literal string which is compared against for
the content of the file. Thus:

# (look for a .hg directory)bzr_control_formats={"Mercurial":{'.hg/':None}}# (look for a file called .svn/format with contents 4\n).bzr_control_formats={"Subversion":{'.svn/format':'4\n'}}

The module docstring is used as the plugin description shown by bzrplugins. As with all Python docstrings, the first line should be a
short complete sentence summarizing the plugin. The full docstring is
shown by bzrhelpPLUGIN_NAME.

This is a user-visible docstring so should be prefixed with __doc__=
to ensure help works under python-OO with docstrings stripped.

The plugin should expose a version tuple to describe its own version.
Some plugins use a version number that corresponds to the version of bzr
they’re released against, but you can use whatever you want. For example:

Plugins should avoid doing work or loading code from the plugin or
external libraries, if they’re just installed but not actually active,
because this slows down every invocation of bzr. The bzrlib APIs
generally allow the plugin to ‘lazily’ register methods to invoke if a
particular disk format or seen or a particular command is run.

The plugin __init__.py runs when the plugin is loaded during bzr
startup. Generally the plugin won’t want to actually do anything at this
time other than register or override functions to be called later.

The plugin can import bzrlib and call any function.
Some interesting APIs are described in Bazaar Plugins Guide.