Setup for Alexandria Development: Part I

This is the first in a series of brain-dumps of my knowledge about Alexandria and related development issues. Be warned, the approach I will take in these posts will be to discuss boring and perhaps obvious details as they occur to me. You are advised to skim.

Getting the code

First things first, you should be able to checkout a copy of Alexandria from subversion. You can find instructions here, but unless you want to pull down the entire tree this is the actual URL you want:

svn co svn+ssh://

Btw, this is worth looking at if you want to play around with code without committing to a central repository.

Initial setup

Let’s look at the directory structure of the checked out copy (called the working directory).

(alexandria root) (Used to add Alexandria to the Gnome menu)
Rakefile                         (The `rake` command looks for this)
/spec                            (Specs go in here)
alexandria.xcodeproj        (MacOS XCode project file)
/data                            (Configuration files go here)
/lib                               (Alexandria code libraries are here)
tasks.rb                        (Rakefile uses this file)
/bin                              (Actual system-wide alexandria command goes here)
/debian                         (Contains templates needed to create debs)
/tests                           (For old 'test/unit' tests)
/doc                             (Docs go here)
/po                               (Language files go here)
/schemas                       (Used in gconf, configuration file like Windows registry)

You will need to get a copy of rubygems. For some reason, the Ubuntu packaged rubygem never seems to actually work, so you should just compile and install rubygems from here. On Ubuntu or Debian, you should run sudo apt-get install build-essential ruby1.8-dev because some gems will need to build “extensions”. You can use either your distro’s rake or install rake from gem. You install gems with:

sudo gem install (package)

You should install rake, rspec, rcov and zentest (autotest):

sudo gem install rake rspec rcov zentest

To work on the website you will also need staticmatic.

Rake and Testing

In the root of your working directory you should now be able to type rake -T and you will see a long list of rake “tasks” defined in the Rakefile and tasks.rb. The most important tasks for development purposes are sudo rake install to install to your system (it installs in /usr/lib/ so be careful) and rake spec, for running the test suite.

Rspec is super cool, but you’ll have to study the tutorials to learn how to use it. A great way to learn Ruby and Rspec at the same time is to ‘spec out’ basic Ruby types! For example, if you’re unsure about how an array method works, you can do this:

describe Array do
   it "should sort strings alphabetically" do
      ["b", "a", "c"].sort.first.should == "a"

Just don’t get confused by the pattern of writing specs to cover code that’s already been written. The basic idea behind Behavior-Driven Development is that you write tests that show how your code will behave before writing the code. The only way to really learn how to do this is to force yourself to write some code this way.

Because BDD is supposed to happen before you write code, Alexandria has very poor test “coverage” at the moment, and its not easy to add specs to the code the way it is now. Still, it’s good practice to try and understand the behavior of a method on a class and write a spec for it. Take a look at the files in specs/alexandria for examples.

When a project has good test coverage it’s possible to work according to a very fast “red-to-green” development cycle. Autotest is a tool that will run ‘rake spec’ every time you change a file that’s being monitored. This is great because, again if the test suite is good, you can know the second you break the code! It’s even better if you use desktop notifications with Autotest. This is the version I use with Ubuntu Gutsy. One note: the file he links to is only good for Gentoo, you want this one.

That’s all for now. I’ll do another one tomorrow.