Tag Archives: Review-Board

Djblets and Review Board moving to jQuery

When we first began development of Review Board and its Django utility package Djblets almost two years ago, we needed to pick a JavaScript library to use. There were several good ones available at the time, and after evaluating several options we chose the Yahoo! UI Library (YUI) and YUI-Ext, an extension library to YUI. Both were excellent and have served us well over the past two years.

However, YUI-Ext itself is really no more, which means we needed to choose something new. We could have continued to bundle it and YUI with Review Board, but users of Djblets would have to hunt down a copy and load in all of YUI and YUI-Ext just to use such features as datagrids. This was, to say the least, inconvenient.

YUI-Ext and the Licensing Situation

Now I said YUI-Ext is no more, but really it’s still around, just in a new form. It had been renamed to ExtJS and became its own independent library. While compatible with YUI, most of the functionality we needed was really provided by ExtJS, meaning we didn’t really need both. Over time, YUI evolved as well, so we began looking into the differences and figuring out which to go with.

ExtJS, it turns out, was a non-starter for us. Unlike YUI-Ext before it, the ExtJS licensing terms were a bit restrictive and, frankly, confusing. Open source projects could use it under the GPL3, but commercial products required a special license per developer, which is $289 per developer. The GPL3 itself is unclear with regards to our situation. We’re an open source project, but we’re MIT-licensed. What if a company wants to modify something for their own use and not release it to the public? What if down the road someone wants to offer commercial extensions to Review Board? We’d have to choose the commercial license to be safe, but then contributors would also need to pay $289 for a license, wouldn’t they?

Looking Again at YUI

We didn’t want to step down a dangerous road with ExtJS, so we started to look again at YUI. It’s definitely come a long way and I must recommend it for developers looking for a strong toolkit with good UI support. They provide good documentation, many examples, and base functionality for nearly everything.

However, there’s a lot we’d have to rewrite to move to it, and if we had to rewrite the code anyway, I wanted to look around a bit at the current generation of JavaScript toolkits. Especially since our needs have changed over the years and we’re looking for something with a lighter footprint. We’re also moving away from the dialog-centered UI we have on some pages, which is where YUI shines.


We ended up deciding to go with jQuery, partially because of the footprint and partially the clean way in which scripts can be written. As an experiment, I converted our Djblets datagrid code to jQuery. The result is a smaller, much more readable, reusable, cross-browser script. I was impressed by what jQuery let me do, and by the size.

I did some comparisons on the number of files downloaded and the size of the files, using the Review Board dashboard as a test.

With YUI and YUI-Ext, we were loading 7 JavaScript files, excluding our own scripts, at a total size of 376KB (when minified).

With jQuery, we loaded only 2 JavaScript files, at a total size of 128KB.

Our datagrid.js file also went down from 13KB to 9KB largely due to some of the niceties of jQuery’s API.

This is a pretty significant savings, a whole 252KB, which could be a couple of seconds on an average DSL line. And it’s not just the file size but the number of requests, which can make a big difference on a heavily accessed web server.

What This Means for Djblets

Developers using Djblets can now use datagrids without needing to do anything special. Djblets bundles jQuery, which it will use by default unless you choose to override which jQuery script is being used. This means all you need is an install of Djblets set up and you’re ready to use it!

Going Forward

We’re working on migrating the rest of Review Board to jQuery. This will take place over the next few weeks, and is one of the last major things we hope to do for our 1.0 release.

Review Board Roadmap and Donations


With the upcoming release of Django 1.0 in the next few weeks, we decided it was time to formalize a roadmap for Review Board 1.0. The roadmap provides a good overview of what users can expect for our release, and what it will take to get there.

At this point we’re asking for people to contribute wherever possible. The big thing is fixing bugs targeted for the 1.0 release. We’d also like some help in finalizing unit tests.

Quality Control

We’re doing what we can to improve quality control in Review Board. For a lot of people, Review Board works great, though setups often differ and some users hit issues that others never see. For this, we’re trying to improve our unit tests to catch these various cases. When people submit patches, we’d greatly appreciate unit tests to cover the new code, and in some cases will require them for the code submission.


We will soon start using Selenium in our unit test process to simulate user action in various web browsers. Selenium allows for remote-controlling a web browser, simulating clicks, text input, and other user actions and checking the results. Over time, when our Selenium test suite is more complete, we should be able to catch browser-specific problems a lot more easily.

Buildbot Server

Another issue users have hit lately is breakages due to changes in Django for the 1.0 release. As things calm down there, this will become less of an issue, but we’ve put things in place to catch these problems before users do.

We have just set up a buildbot server that will perform a full build and run the test suite whenever there’s a code check-in to Review Board, Django, Djblets or Django-Evolution. It will then notify us when there’s a new breakage. Users can check the build page before updating just to make sure they won’t hit a major problem. Later on, our buildbot server will generate nightly builds and handle Selenium tests.

We have a limited number of servers to test with. If you have server space and resources to donate and would like to run a BuildBot Slave server, let me know. We’re looking to set up slaves to test various combinations of the following:

  • Python 2.5
  • Python 2.4
  • Django SVN trunk
  • Django 1.0
  • Windows 2000, XP and Vista
  • Internet Explorer 6 and 7 (for Selenium tests)
  • Opera (for Selenium tests)
  • Firefox 2 and 3 (for Selenium tests)


Our BuildBot server is also set up to allow us to test code changes before we submit the code. Running a sandbox build of our pending code will cause all build slaves to run the entire test suite. This ensures that we don’t break things accidentally.

If you’re a contributor working on large patches for Review Board and would like to have access to the sandbox, please post to the mailing list and we can work with you on getting an account set up.

Installation Improvements

We’re working to make the installation experience much easier. I’m in the process of creating Python easy_install packages for Review Board and Djblets. Soon, users will be able to simply easy_install ReviewBoard to get going instead of checking out the development tree. I’m hoping to create both nightly builds and release builds.

Code will soon go in to move the entire project configuration into the administration interface. Modifying settings_local.py and restarting the server will be a thing of the past. All that will be left there will be a few site-specific settings and the database settings. Expect this to go in real soon.

A tool is in development for helping to generate the initial Review Board server tree based on an installed reviewboard Python module (using easy_install) and generating the web server configuration files. This will hopefully take care of a lot of problems people hit when trying to get their server configuration right the first time.

And last but not least, before 1.0 we will have a first-time installation page that handles the creation of the initial settings_local.py and the adding and checking of repositories.

So in the end, the installation process will be something along the lines of:

  1. sudo easy_install ReviewBoard
  2. sudo rb-install-site /var/www/reviews.mycompany.com
  3. Fill out the fields presented.
  4. Hand-tweak the configuration files if needed.
  5. Go to the page for the new Review Board server, fill out the fields and finish the install.

This is the goal, anyway. We’re going to try to get as close to this as possible for 1.0.


Review Board has become a full-time project for us. Though it got its start at VMware, it’s really a personal project developed in our spare time, not a project run by VMware. As the project grows, we’ve been putting more time, energy and money into it.

Hosting fees have started to become large, given that we’re now hosting the main project website, the main Review Board server for our code reviews, the demo server, the Google Summer of Code review server and the BuildBot server and slaves. Down the road, we have many plans that will also require funding.

To help cover our costs, we’re now made it easy to donate to the project. If Review Board has helped you, your company, team, or project and saved you money or time over alternative solutions, maybe you’d like to help give back to keep our project going. Every bit helps.

Happy birthday Review Board!

One whole year…

While attending SuperHappyDevHouse, David and I realized that it was the one year anniversary of Review Board‘s public announcement. (This was the evening of May 17th. I’m just a few hours late in getting this post up.)

It’s been a pretty awesome year for Review Board. What begun as a small project intended for use in our team at VMware and in our personal open source projects turned into a large project with a great community of developers and users. It’s now being used by dozens of companies and projects (some of which have given us permission to list them publicly) and has had code contributions from over 35 users. To everyone who has contributed to the project, we’d like to give our thanks. Review Board wouldn’t be the tool it is today without your help.

I’d like to list some of the major things that have happened in the past year.

  • Review Board has been adopted by one or more teams at around 40 companies (including Yahoo! Search, VMware, and Tripwire).
  • Received contributions from over 35 users.
  • Added support for CVS, Subversion, Perforce, Git, Mercurial, and Bazaar.
  • Added support for useful features such as interdiffs, screenshot commenting, syntax highlighted diffs, customizable dashboard for keeping track of review requests, status reports, a full JSON API, and more.
  • Several presentations were given at various companies and conferences on Review Board by third parties.
  • One public presentation was given by us at LugRadio Live USA 2008 (view the presentation)
  • We’ve started hosting projects for this year’s Google Summer of Code on our Summer of Code server.

That’s just a small sampling. There have been many changes made to stabilize the codebase, improve usability, and generally make the product more awesome.

And of course there’s a number of things happening in the near future:

  • Monotone support.
  • A new, improved administration UI.
  • Extensions support, allowing Review Board to be extended in a variety of ways and integrated into other products.
  • A new set of command-line tools and a Python library for working with Review Board servers.
  • Support for P4V (for Windows Perforce users).

Database Migration and Parent Diffs

Today, a change went in that improves Review Board in two fundamental ways.

First, we now have a fast, powerful way of doing database migrations in-place, without dumping and loading the database. While this should make life easier for users and allow us to modify the database without fear of breaking people’s installs as often, it will also save administrators of large Review Board servers a lot of time. Before this change, the VMware database (of over 25,000 review requests) took at least 30 minutes to do a full migration. Now it shouldn’t take more than a minute.

Second, we’ve just landed the initial support for diffs based on parent diffs. If you’re a user of a distributed version control system (such as Git or Mercurial) you’ll appreciate this. Before, your change had to apply against revisions in the master repository, making it impossible to put up a review request for a change on a sub-branch of a branch when the parent branch didn’t exist on the server. Now, a diff of the parent branch can be uploaded along with your sub-branch’s diff.

Confused? Maybe an example will help. Say you’re working on a large restructuring change in your “code-restructure” branch in your local Git checkout. You have a topic branch off of your “code-restructure” branch with changes you want to put up for review. This used to be impossible without including the whole “code-restructure” branch’s changes in your diff as well, but now, you can put up a diff of the topic branch along with a diff of the “code-restructure” branch, and the topic branch’s diff will appear on Review Board, ready for review.

The backend code for this is now in Subversion. We’ll be adding support to the post-review tool shortly, making this accessible to anyone. Review Board will become fully usable for distributed version control systems.

Are you using Review Board?

Review Board is gaining popularity, and more companies are beginning to use it. If you work for a company or an open source project that’s using Review Board and can give us permission to list you on our Happy Users page, please let us know!

And here’s to an even better year for Review Board.

Free Review Board Hosting for Summer of Code

Google Summer of Code 2008 is on, and soon students will begin coding, which means mentors will be reviewing code. While the Review Board project is not a participating project in this year’s Summer of Code, we felt Review Board could help with the whole process, improving things for both the students and the mentors.

Starting today, and for the duration of this year’s Summer of Code, we at the Review Board project would like to supply up to 30 projects with free Review Board hosting at gsoc.review-board.org. We’ll handle maintenance of the server, support, and provide assistance to get students and mentors set up.

Doing code reviews with Review Board is simple and saves time over reviewing standard raw diffs, with features such as a powerful diff viewer with syntax highlighting and inline commenting, interdiffs, status reports, and support for a wide variety of revision control systems. We believe it can be as effective a tool for open source development as Bugzilla and Trac have become.

Th Summer of Code server is intended for Summer of Code-related changes only. While we’d love to provide hosting for projects in general, we have limited resources. However, should your project decide to set up its own Review Board server in the future, we’ll be able to assist in migrating your Review Board history to your new server.

If you’re interested in trying out Review Board for your Summer of Code project, you can find out how to apply on our Summer of Code Hosting page.

To learn more about Review Board and how it works, you can look at our project website or watch our presentation from this year’s LugRadio Live USA.

Review Board presentation at LugRadio Live 2008

This year’s LugRadio Live USA conference was a blast. There were some great talks, interesting booths, and fun swag.

The Review Board presentation went pretty well. I think in my next presentation I’ll demo more often instead of just at the end, but all in all people seemed to find it interesting. The presentation focused on what Review Board is, how it works, and how it could benefit open source. With luck, it will encourage projects to begin using a real code review system, making life easier for all involved.

For those that missed it, the slides and the presentation video are now available. Enjoy!

Django Development with Djblets: Unrooting your URLs

Typically, Django sites are designed with the assumption that they’ll have a domain or subdomain to themselves. Often times this is fine, but if you’re developing a web application designed for redistribution, sometimes you can’t make that assumption.

During development of Review Board, many of our users wanted the ability to install Review Board into a subdirectory of one of their domains, rather than a subdomain.

There’s a few rules that are important when making your site relocatable:

  • Always use MEDIA_URL when referring to your media directory, so that people can customize where they put their media files.
  • Don’t hard-code URLs in templates. Use the {% url %} tag or get_absolute_url() when possible.

These solve some of the issues, but doesn’t address relocating a Django site to a subdirectory.

Djblets fills in this gap by providing a special URL handler designed to act as a prefix for all your projects’ URLs. To make use of this, you need to modify your settings.py file as follows:



SITE_ROOT_URLCONF = 'yourproject.urls'
ROOT_URLCONF = 'djblets.util.rooturl'


SITE_ROOT specifies where the site is located. By default, this should be “/”, but this can be changed to point to any path. For example, “/myproject/”. Note that it should always have a leading and a trailing slash.

The custom template context processor (djblets.util.context_processors.siteRoot) will make SITE_ROOT accessible to templates.

SITE_ROOT should be used in templates when you need to refer to URLs that aren’t designed to respect SITE_ROOT (such as User.get_absolute_url). Your own custom applications should always respect SITE_ROOT whenever providing a URL.

ROOT_URLCONF is typically what you would set to point to your project’s URL. However, in this case, you’ll be pointing it to djblets.util.rooturl. This in turn will forward all URLs to your project’s handler, defined in SITE_ROOT_URLCONF.

This is all you need to have a fully relocatable Django site!

To sum up:

  1. Add djblets.util.context_processors.siteRoot to your TEMPLATE_CONTEXT_PROCESSORS.
  2. Set SITE_ROOT_URLCONF to your project’s URL handler.
  3. Set ROOT_URLCONF to ‘djblets.util.rooturl’
  4. Prefix any URLs with SITE_ROOT in your templates, unless the URL would already take SITE_ROOT into account.

This is functionality that will hopefully make its way into Django at some point. For now, you have an easy way of unrooting your Django project.

Django Development with Djblets: Custom Tag Helpers

I’m planning to cover all of what Django can do, but for now, let’s start simple with something most Django developers spend way too much time creating: Custom tags.

Django’s nice enough to provide a @register.simple_tag decorator for creating very basic tags that don’t take a context but do take parameters. This is great, but what if you want more? Many Django applications use the same boilerplate time and time again to create their tags, but we make it much easier.

Introducing @basictag and @blocktag.


Ever wanted to use Django’s @register.simple_tag but needed access to the context? I’ve found far too many cases where this would be useful, but Django doesn’t make this easy. Your tag code would end up looking like this:

class MyTagNode(template.Node):
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2

    def render(self, context):
        arg1 = Variable(self.arg1).resolve(context)
        arg2 = Variable(self.arg2).resolve(context)

        return context['user']

def mytag(parser, token):
    bits = token.split_contents()
    return MyTagNode(bits[1], bits[2])

Do this a few times and it’s bound to drive you nuts. How about this instead?

from djblets.util.decorators import basictag

def mytag(context, arg1, arg2):
    return context['user']

Far less code and increased readability. Hooray!


@blocktag aims to do the same thing @basictag does but for block tags. A block tag is a tag that contains nested content, like @spaceless or @for. This usually requires even more boilerplate than the above code fragment, except with the added complexity of having to grab the contents of the block.

We’ve condensed it down to this:

from djblets.util.decorators import blocktag

def blinkblock(context, nodelist, arg1, arg2):
    return "<blink>%s</blink>" % nodelist.render(context)

If you’ve built block tags in the past, you’ll appreciate how simple that was.

Django Development with Djblets

Django is an awesome development platform for web applications. With such features as database abstraction, template/view/url separation, built-in authentication with interchangeable backends, it’s made web development much more enjoyable.

We use Django in Review Board with much success. Over time, as we’ve come to develop new features, we realized that much of our codebase was useful outside of Review Board and, bit by bit, moved pieces into a library we call Djblets.

What does Djblets do?

A bit of everything, really. Any time we have useful functionality that isn’t tied to Review Board, we put it here.

Djblet’s feature list currently consists of:

  • Authentication improvements, making it easy to register and login in one step, seamlessly, handle password recovery, and more.
  • Flexible datagrids for displaying data in a paginated list with user-specific column customization, ordering and sorting.
  • Decorators to drastically simplify creation of simple and block template tags.
  • Caching functions for calling a function and caching the result if the data isn’t already in the cache, and a special URL pattern matcher that prevents caching of any contained URLs.
  • Unit testing utility classes.

And of course more little things here and there.

Downloading Djblets

Djblets is not a released app, but it’s pretty stable and well tested. You can check out a copy from our SVN repository, or automatically include it in your own repository through an svn:externals entry.

Djblets is licensed under the MIT license, making it usable in most projects.

Using Djblets

Over time I’ll be writing articles on using the many features of Djblets. See the other posts in the series, or dig around the Djblets source code.

Review Board: The Past 5 Months

It’s been about 5 months since I last gave a Review Board status update. Way too long, given how much has changed. So once again, let’s start off with a few stats.

  • Total bugs open: 25
  • Total bugs fixed: 186
  • Feature requests open: 43
  • Companies known to be using Review Board: at least 23

Review Board has matured in recent months and has a very nice feature set. More and more we’re seeing and hearing about companies using it in one or more teams. I was even lucky enough to talk about it in the official Django Book.

Development shows no sign of stalling. Our feature request list is a mile long, and our personal TODO lists are longer still. We’ve implemented so many new features and fixed so many bugs that I can’t even list them all, but let’s take a look at the highlights.

New Top-Level Features

  • iPhone support. Basic read-only iPhone support was added. It’s more of a proof of concept and to make sure our codebase handles different UIs on top of it, but if your Review Board server is accessible from your iPhone, point Safari to /iphone/ for some fun.
  • Status Reports. Basic support for status reports have been added. While we don’t have a fleshed out UI in place, the /reports/ URL will give you simple reports showing which review requests you’ve reviewed, and other bits of information. This can even be presented in Wiki format!

Revision Control Systems Integration

  • Mercurial support. One of our contributors has written support for doing review requests against Mercurial repositories. This supports local and remote repositories.
  • Git support. Basic Git support was written as well. It only works with local Git repositories (as it has to have access to .git directories).

Diff Viewer

  • Improved diff parser. We no longer require third party tools in order to parse diff files. We can do it ourselves faster and with greater flexibility. This has given us some speed advantages, reduced the hacks needed, and improved diff compatibility.
  • Interdiffs. Review Board can now display the differences between two revisions of a diff. This makes it much easier to review several iterations of large changes spanning many files.
  • Fixed diff line numbers. Line numbers in the diff viewer used to be artificial. They were essentially table row numbers. Now line numbers on the left-hand side of the diff viewer represent the actual line numbers in the original file, and line numbers on the right represent the new file.
  • “Review” link. Added a “Review” link on the diff viewer and screenshot page for bringing up the Review dialog. Previously users had to click a link on the diff viewer regardless of whether they were leaving a comment on the diff.


  • Show commented screenshots on reviews. Portions of a screenshot that the user has commented on will appear in the review body, much like diff fragments do. This greatly improves the review process when it comes to screenshots.
  • Updated diffs create a new draft. Newly updated diffs used to instantly appear and send out an e-mail, which was annoying if you realized you needed to change and re-upload the diff again. Now updating the diff just creates a draft, if one doesn’t already exist. The diff won’t show up or spam users until you’re ready for it to.
  • Auto-completion for reviewers. The reviewer lists now have support for auto-completion of group names and usernames. As you’re typing, a list of choices based on the current text will appear. Navigating with the arrow keys or hitting Tab will auto-complete the selected entry.
  • Default reviewers. Administrators can now specify default reviewers for file paths (as defined by a regular expression). This allows certain groups to “own” files or paths and to be included on the reviewers list any time a diff touching those is uploaded.
  • Improved page banners. The draft banner at the top of the review request page has been improved and is now more clear. No longer do you have to save a draft and then publish it. It’s now one single button on the banner. We also added “discarded” and “submitted” banners.
  • Alpha-numeric bug numbers. Not all bug trackers use numeric-only bug identifiers. We now support alpha-numeric bug numbers.

Dashboard and Review Request Lists

  • Starred review requests and groups. Users can now “star” a review request they wish to keep track of in their dashboard. They’ll be placed on the CC list and see changes in the dashboard. Users can also star a group in order to add it to their “Watched Groups” list in the dashboard.
  • Toggle display of submitted review requests. The “All Review Requests” page can now filter out submitted review requests via a toggleable “Show/Hide Review Requests” link.
  • Customizable columns. The various lists pages and the dashboard now support customizable columns. There are non-default columns that can be added to the view to show extra data, and existing columns can be removed. If you prefer all dates to be relative or absolute, just add the right columns. Furthermore, columns can be reordered simply by dragging them into the desired order.
  • New dashboard column types:
    • New Updates. This column shows a speech bubble icon when new discussions have taken place on a review request since the user last visited it.
    • Ship It. This column makes it easy to see if anybody has marked the review request as “Ship It!”
    • Absolute/relative timestamps. Users wishing to see only relative or absolute timestamps in the dashboard can add the Last Updated/Posted Absolute or Relative timestamp columns.
    • Number of Reviews. Sometimes it’s handy to see how many reviews have been made to a review request. This column provides that number.
    • Starred. Allows users to star/unstar a review request or group. This is like adding yourself to a CC list.


  • Upload diffs from a revision range. --revision-range has been added to allow for uploading diffs from a range of revisions on the server. This is currently only implemented for SVN.
  • Specify a default summary. --summary has been added to provide a default summary for the review request.
  • Open a browser after uploading. --open has been added to open a browser to the new review request.


  • make install. It’s now trivial to create a Review Board tarball or to install it on your system. We integrate with autoconf/automake to generate the Makefiles and sample/default configuration files. This brings us a giant step closer to putting out releases.

What’s Next?

We have several things in the works. A couple of the major highlights would be a search interface and support for 3rd party extensions to Review Board. Stay tuned!

Review Board Status Update

It’s been just over a month since the last Review Board status update. I thought this time I’d start off with a few stats.

  • Bugs open: 19
  • Bugs fixed: 97
  • Feature requests open: 27
  • Contributors: 10
  • Companies using Review Board: at least 13

If you’re part of an open source project or company using Review Board, we’d love to hear from you and your experience. We’d like to make a list of who’s using Review Board, so if you’re able to list your project/company, please let us know!

Now on to the feature updates.

  • Internet Explorer compatibility. Internet Explorer should now work properly with Review Board. A lot of work was recently done to make this happen and it hasn’t been as extensively tested as we’d like just yet, but things do appear to be working. Firefox is still the preferred (and targetted) browser, but do feel free to try IE and let us know if anything breaks.
  • CVS support. Review Board now supports CVS repositories. Right now there’s only :pserver support, though, but patches are welcome.
  • Improved post-review script. post-review, the script of choice for creating and updating review requests from the command line, now supports both Perforce and Subversion, with support for more systems on the way. A single post-review script can now handle a variety of repositories for different projects, and projects can be set up to point post-review to the right Review Board server.
  • Column sorting and list paging. Columns in the dashboard and review request lists can now be sorted by summary, submitter, posted time or last updated time. There’s also an improved pager at the bottom for skipping to other pages in the list.
  • Collapsed diff sections can now be expanded. The brown “n lines hidden” boxes in the diff viewer can be individually expanded without reloading the page by clicking a little “Expand” link on the box. This makes it easy to get more context when needed without expanding the entire diff and having to reload the page.
  • Cross-platform CRLF support. Diffs generated on Windows will now apply correctly on Review Board instances running on Linux, and vice-versa.
  • Improved diff loading times. Large diffs take a while to load, but we’ve improved this slightly by caching much of the resulting diff so that it doesn’t have to be regenerated again. More work is planned in this area to improve loading times, but it’s a lot more usable now.
  • More reliable database migration. The database migration scripts didn’t scale very well due to the existing Django libraries we were making use of being problematic for large database sizes. We’ve now fixed this, and they should be more reliable and hopefully a bit faster as well. There’s now a percentage complete indicator when loading back in.
  • Anonymous access to Review Board. It’s no longer necessary to have an account in order to view review requests and diffs. This is desirable for most open source projects. The old behavior of requiring an account for site-wide access can still be enabled, but is disabled by default.

In the works is a much improved diff parser that won’t require lsdiff on the server hosting Review Board. This should make things a little easier for people installing on Windows, and it also cleans up the code quite nicely. This should be in sometime this week.