Wednesday 11 March 2009

lp:mad

One of the things that I have spent quite a lot of time on recently is the code review stuff in Launchpad. Recently, as of the 2.2.2 release, new merge proposals get a review diff created for them automagically. This review diff is based on the changes that have been done in the branch relative to the least common ancestor (LCA) of the target branch. Since the review diff only has changes that have been added, there is no way for this diff to ever have conflicts.

There is another diff that is useful to see however. This is the diff of what changes would happen if the source branch was merged into the target branch right now. Sometimes this might conflict. Sometimes this might be a smaller diff as some other dependent functionality has landed. This diff isn't generated automatically by Launchpad. However this is something that you can run to add it.

The Merge Analysis Daemon

Alright, it isn't exactly a daemon (yet), but the name was cool.

What this script does, using the launchpadlib API, is to get all of the current merge proposals for a project and works out the diff that would be — what we call the preview diff.

What do you need

Firstly you need branches of wadllib, launchpadlib, and mad.

$ bzr branch lp:wadllib
$ bzr branch lp:launchpadlib
$ bzr branch lp:mad

Inside the mad directory, there is the LICENSE file (GPL v3), and the script.

The script has many parameters.

$ ./mad.py --help
Usage: mad.py [options]

Options:
-h, --help show this help message and exit
-v, --verbose Display extra information
-q, --quiet Display less information
-p PROJECT, --project=PROJECT
The name of the Launchpad project.
-r DIR, --repo=DIR The location of a local repository to use.
--dry-run Don't upload the diffs
--force Force an update of the diff.
--staging Update the proposals on staging.launchpad.net.
-c FILE, --credentials=FILE
The credentials file. Defaults to ~/.launchpad/mad
--cachedir=DIR The location of the cache directory. Defaults to
~/.launchpadlib/cache.
--no-op Don't get the proposals for the project.
--new-credentials Get a new OAuth token and save in the credentials
file.

I have the following in the server's crontab listing:


20 * * * * PYTHONPATH=/home/tim/launchpadlib:/home/tim/wadllib /home/tim/mad/mad.py -p storm -r /home/tim/sandbox/mad-playground -c /home/tim/.launchpad/mad -v >> /home/tim/mad-storm.log 2>&1


Basically this says:

  • At 20 minutes past every hour

  • Run the mad.py script using a PYTHONPATH that knows about wadllib and launchpadlib.

  • Use the credentials file ~/.launchpad/mad

  • Use the respository at ~/sandbox/mad-playground

  • Be verbose

  • Make all output go to a log file.


If the specified repository directory does not exist, a new shared repository with no working trees is created. If there is an existing repository, it will use that.

Each of the source and target branches are pulled into the repository. MAD won't create branches for them, it just grabs all the necessary revisions. MAD then calculates the diff that would be if the source was merged into the target, and sends that to Launchpad to have it annotate the proposals. As an example, see the storm ones.

You will also need to have permission to edit the proposals that you are wanting to update. If you are the person that is running the project, and are in the team that owns the target branches, then you should be able to update them.

There is a --staging option to test the script against what is in staging.

The script also walks you through the necessary OAuth token acquisition the first time you run the script.

Report bugs on Launchpad.