Client-side extension

This is the most common setup for this extension, being enabled on the client-side at the developer desk to allow him to indicate alongside with his changeset on which issue he is busy.

This is nothing fancier than enabling a general mercurial extension. No weird dependencies are needed, as the comunication with the database is done from the server-side.

After cloning the BugLink repository, the following lines have to be added to your user specific mercurial configuration file (Mercurial.ini on windows or .hgrc):

buglink = path/to/buglink/client/

Server-side extension

This one has to be enabled on each repository that may receive changesets from developpers. This extension will care about updating the database with the issue ID the developpers have been busy with. This can be a server-wide setting, a repository specific setting, or a setting reserved for the web instance of mercurial (hgweb.conf for instance).

This extension needs to talk to the database, and thus has dependency on SQLAlchemy.

As any other mercurial extensions, it is enabled through modification of the mercurial configuration file (Mercurial.ini on windows or .hgrc), where the following lines have to be added:

buglink_srv = path/to/buglink/server/

The location of the database has to be configured in the same configuration file. This has to be a sqlalchemy database url. For instance:

db_uri = sqlite:////tmp/dblink.db

Web Interface

We are talking here about a WSGI application. there are plenty of guide on the internet on how to attach a WSGI application to your favorite web server. It looks like the last trendy one is to have a Gunicorn instance behind a nginx proxy. Apache and mod_wsgi also works fine.

The web interface has a bit more dependencies as the rest, as it needs to talk to the database, and deliver content for a web browser. The needed dependencies can be found in srv-requirements.txt. This file follows the pip requirements file format. So that within your virtualenv you just need to run:

pip -r srv-requirements.txt

The web app is located in the following file:


Flask having its own integrated web server, it can be tested as follow (the optional parameter is the name of the configuration file):

python server/ [config.yaml]

A sample WSGI script is given in server/buglink.wsgi. This file is reproduced here:


The web server is configured through the usage of a configuration dictionary. This one can be given in the WSGI script or through a config file in the YAML format.

the following configuration values are understood:


This is the url to the database in the sqlalchemy format. For instance:

This is a random string used to encrypt the cookies used by the web application.

This configuration key is used to configure cross links between buglink and other web instances (for instance the mercurial server, or the bug tracker.)

The links key support the following sub-keys:

This is used to link a repository name to a web page, usually, the mercurial server.
This configuration key is used to link a changeset to a web-page usually on the mercurial server.
This is used to link an issue to a web page (the bug tracker for instance).

All the sub-keys follow the same format. They are a list of settings, each setting can have three sub-keys: re, default and url. At least the url sub-key should be filled to generate a link.

The following mechanism is used for each setting of each sub-keys in the order they are defined, later values being only used if the previous one did not matched:

  1. The value (repository path, changeset hash, or issue reference) is matched against the content of the re value.
  2. If the regular expression matches, we go on to the next step, else the next setting is tried.
  3. A dictionary is created with each matched variable of the regular expression (in the form (?P<id>...)). Optional variables get their values from the default setting. This setting is a dictionary associating variable name to default-values.
  4. The url is generated from the content of the url setting, by replacing each format string (in the form %(name)s) with its matched value during the regular expression matching.

As an example, tortoisehg, a project stored on should use the following setting:

      re: #(?P<id>\d+)