Working on IzPack with Git and Subversion

October 23rd, 2008

2008/10/27: I have removed my vendor-svn-trunk branches on Github. Indeed, I realized that I have not been using them properly. In the future, I will always consider master branches as the exact copies of Subversion trunks, i.e., new commits in master will appear after Subversion commits (mines or not) have been fetched locally.

These instructions will be helpful to the IzPack developers, but you can certainly adapt them easily for your own project.

The idea is to use Git, a decentralized SCM tool along with Subversion. This is getting quite common to mix both tools: Subversion hosts the “official” source code while developers and external contributors may collaborate with more flexibility in Git.

Git plays nice with Subversion. One can easily “clone” a Subversion repository into a Git one. This is however a lengthy process if your project has accumulated many revisions. I did that once for the IzPack Subversion trunk, then published it to Github.

Someone that has commit access to the project in Subversion can easily use Git as well. Instead of converting the whole repository again, there is a simpler solution. I use that on other machines too when I want to work on IzPack using both Git and Subversion.

First, clone the trunk with only a few of the latest revisions. Unless you really have to dig far in the past, you won’t need much of those revisions anyway ;-)

git svn clone --username=jponge -r 2300:HEAD -T https://svn.codehaus.org/izpack/izpack-src/trunk izpack.git

It is then easy to check that I have a master branch with a special trunk branch that is handled by git-svn:

jponge:izpack.git julien$ git branch -a
* master
  git-svn

I can then easily add my GitHub remote branches. Use a different clone URL in your case: either the read-only one of my GitHub repository, or your very own fork of it.

git remote add origin git@github.com:jponge/izpack.git
git fetch
warning: no common commits
remote: Counting objects: 17652, done.
remote: Compressing objects: 100% (4214/4214), done.
remote: Total 17652 (delta 11961), reused 17611 (delta 11942)
Receiving objects: 100% (17652/17652), 14.49 MiB | 265 KiB/s, done.
Resolving deltas: 100% (11961/11961), done.
From git@github.com:jponge/izpack
 * [new branch]      master     -> origin/master
 * [new branch]      vendor-svn-trunk -> origin/vendor-svn-trunk
 * [new branch]      with-git-submodules -> origin/with-git-submodules
jponge:izpack.git julien$ git branch -a
* master
  origin/master
  origin/vendor-svn-trunk
  origin/with-git-submodules
  trunk

This fetches more data as my GitHub repository contains the whole IzPack history that I had converted a while back from Subversion.

You can see that I work with a few branches:

  • origin/master is… the master Git branch
  • origin/vendor-svn-trunk is where I push the updates from the trunk branch that git-svn handles
  • origin/with-git-submodules is the same as origin/master, but with submodules that refer to the IzPack utilities and native launcher (rationale: Git is not able to push back to Subversion when there are submodules…).

We need to reset our local master branch to origin/master as git-svn has put it on trunk:

git reset --hard origin/master
HEAD is now at c23f4e5 Merge branch 'local-trunk'

We can now create a few local branches:

git checkout -b local-trunk trunk
git checkout -b with-git-submodules origin/with-git-submodules
git checkout master

which gives:

jponge:izpack.git julien$ git branch -a
  local-trunk
* master
  with-git-submodules
  origin/master
  origin/vendor-svn-trunk
  origin/with-git-submodules
  trunk

That’s it, you can work with Git. Getting updates from SVN is easy (git svn fetch). It is easy to push back those updates from trunk to origin/vendor-svn-trunk. It is also easy to commit using git svn dcommit.

Git + SVN gives a really great flexibility for developing new features and collaborating with non-developers. Indeed, I can ultimately push back the work from Git to Subversion. I still use Subversion directly for many tasks such as committing a patch, but for new features working with Git is really appealing ;-)

JUnit and its clones are dead

October 17th, 2008

If you had been using JUnit, TestNG or any other similar testing framework then you must stop doing so in your next projects. Seriously.

“Behavior driven development” has been in the air for some time now. The very gross idea is that unit tests often suck when you have to read them. Instead, you would prefer expressing how your classes should behave under various scenarios, like: when something is done, this should happen”. In turn those stories become immediately natural to read. You can of course write JUnit tests that are easy to read and understand, but this requires more discipline.

I recently came across Easyb, a BDD framework written in Groovy. It provides a very cool internal DSL for writing such scenarios / specifications.

Let’s have a look at a small example. We write a very stupid calculator class in Java:

package my;
 
public class Calculator {
 
    public int plus(int a, int b) {
        return a + b;
    }
 
    public int times(int a, int b) {
        return a * b;
    }
 
    public int divide(int a, int b) {
        if (b == 0) {
            throw new RuntimeException("Division by zero attempted!");
        }
        return a / b;
    }
 
}

Instead of writing the CalculatorTest class that you would expect in JUnit/TestNG and clones testing frameworks, you can write the following scenario:

import my.Calculator
 
scenario "calculator manipulation", {
 
    given "a calculator", {
        calc = new Calculator()
    }
 
    then "sum should work", {
        calc.plus(1, 2).shouldBe 3
        calc.plus(0, 2).shouldBe 2
    }
 
    and "times should work", {
        calc.times(1, 1).shouldBe 1
        calc.times(1, 0).shouldBe 0
        calc.times(2, 2).shouldBe 4
    }
 
    and "divide should work", {
        calc.divide(4, 2).shouldBe 2
        calc.divide(1, 1).shouldBe 1
    }
 
    and "dividing by zero should fail", {
        ensureThrows(RuntimeException) {
            calc.divide(10, 0)
        }
    }
 
}

Isn’t that way easier to read? :-)

Finally, easyb is able to write various kind of reports in text files or XML such as this one:

 1 scenario executed successfully

  Story: calculator

    scenario calculator manipulation
      given a calculator
      then sum should work
      then times should work
      then divide should work
      then dividing by zero should fail

That’s just too good ;-) What do you think?

Refreshed Groovy installer

October 16th, 2008

Groovy

This is just a quick note to let you know that I have refreshed the installer for Groovy: get it from the downloads page!

If you haven’t yet tried Groovy, I highly suggest that you do so. This language plays nice with Java, embeds lots of Ruby-like constructs and is highly productive.

IPS Wiki

October 15th, 2008

If you are looking into leveraging the Sun IPS technology + Update center tool, I suggest that you check out the nice (Confluence-based) wiki at http://wikis.sun.com/display/IpsBestPractices/Image+Packaging+System+Best+Practices.

One thing I am looking at for IzPack is to provide a deep (yet optional) IPS integration through dedicated panels and the possibility to have some online packages that would be delivered by IPS…

Glassfish alternate community distributions

October 14th, 2008

As mentioned in this recent blog post, IzPack offers another solution to install Glassfish. Especially, the IzPack-based installers works on any Java-enabled operating system, and it provides a smooth initial configuration experience.

The post also mentions alternative packagings for Linux distributions, which is always nice to have (different installation contexts require different solutions).

In the v3 IzPack installer that is mentioned, I’d like to add that we offer a complement to the IPS-based update center in Glassfish: IzPack provides the initial installation / final uninstallation while the update center provides the updates and add-ons, just as Christopher Kampmeier from Sun Microsystems nicely blogged about a few weeks back.