Build numbering for Java applications using Git and Ant 2013-08-05

Build numbers allow developers to find exactly what version of the code some build corresponds to. Proper build numbers can speed up bug analysis.

In order to use build numbers correctly each number must correspond to exactly one revision/commit in the Version Control System (VCS). It is also helpful, though not required, if the build numbers can easily be sorted chronologically without extra information such as VCS history. SVN revision numbers fit both criteria but build numbering is trickier for distributed systems such as Git.

Off and on at work I have been porting several Java projects from SVN to Git and while doing this I also looked at improving the version and build numbering for those projects. Roughly concurrently to this I’ve ported a hobby project from Bazaar to Git and improved version numbering and release automation there. Due to all this I’ve slowly been converging on a pattern for doing version/build numbering for Java applications with Ant and Git that I think is fairly simple and usable.

We can’t have linearly increasing revision numbers in Git – for good reasons. Full commit hashes are too long to use as build numbers and even the seven character short form is problematic due to not being easily chronologically sortable.

The solution for Git is to use git describe. This command will give the name of the latest tag in the history for the current branch, and if the latest tag is not the same as the last commit then it also includes the number of commits since the tag and the short commit hash. The output can look something like this:

$ git describe
1.3.4-14-g921aee0

$ git describe 1.3.2
1.3.2

That’s pretty readable and it’s still unique and sortable! As a bonus, the build number is the same as the version number for tagged commits. Hurray!

To get the build number into a Java application requires that the build script updates a source file to include the version information. This can be done several different ways, but the approach I have found to be most useful is to store the version info in a property file before building the application. The version string can then be loaded in the application using a ResourceBundle.

I use Ant to build nearly all my Java projects – at home and at work. If you think Ant is a bad idea then you can safely skip the rest of this article. I use Ant because it is ubiquitous – it comes bundled with eclipse and you’ll be able to run it nearly everywhere.

Here are some targets I use for build number generation:

<!-- this target is only run if the 'version' property is undefined -->
<target name="update-version-string" depends="-timestamp" unless="version">
        <!-- get a new version string using git describe if possible -->
        <echo message="Updating version string..."/>
        <exec executable="git" outputproperty="version"
                failifexecutionfails="false">
                <arg value="describe"/>
        </exec>
        <antcall target="-store-version-string"/>
        <!-- ensure version is defined even if git was not available -->
        <property file="${res.dir}/Version.properties"/>
</target>

This is the main target for updating the version string (including build number). This target tries to run git describe but will gracefully continue if the Git command fails (for example when a user compiles the source distribution). If the Git command fails we still need to make sure the version property is set by reading back the version property file (this does not override the current timestamp values).

<target name="-timestamp">
        <tstamp>
                <format property="timestamp" pattern="yyyy-MM-dd'T'HH:mm'Z'"/>
                <format property="build.date" pattern="yyyy-MM-dd"/>
        </tstamp>
</target>

This one is just used to get a timestamp for the build. This should always happen even if the version property has already been defined. Some of my projects embed the timestamp or date in documentation or other generated things – so it’s important that the timestamp is always current.

The minus before the name makes it a private target – it’s not meant to be run separately from the command line.

<target name="-store-version-string" depends="-timestamp" if="version">
        <!-- store the new  version string in the correct property file -->
        <echo message="version=${version}"/>
        <propertyfile file="${res.dir}/Version.properties">
                <entry key="version" value="${version}"/>
                <entry key="timestamp" value="${timestamp}"/>
                <entry key="build.date" value="${build.date}"/>
        </propertyfile>
        <exec executable="git">
                <arg value="update-index"/>
                <arg value="--assume-unchanged"/>
                <arg value="${res.dir}/Version.properties"/>
        </exec>
</target>

This one is not intended to be called standalone – it just updates the version property file in the directory denoted by the res.dir property. The timestamp and version string must be set before it is called. In order to not commit a new version of the version property file for every single build I call git update-index --assume-unchanged – this makes Git ignore changes in the given file despite the file being tracked – it’s sort of like a temporary entry in .gitignore.

Using these targets and by making my main build target depend on update-version-string I can ensure that the version string (including build number) is always correct and that the timestamp properties are set to the current build time. When I do new releases and I really want to commit a new version of Version.properties I call git update-index --no-assume-unchanged this is also done in an Ant target and requires -Dversion=X.Y.Z to be specified on the command line.

2 Comments on Build numbering for Java applications using Git and Ant
Categories: Programming

How much have I spent on Steam? 2013-07-30

The 2013 Steam Summer Sale ended a week ago. It left me with a thinner wallet, and a couple new games in my Steam library. It also got me thinking about how much I’ve really spent on Steam.

There are some websites that can calculate the total value of your Steam library – but those calculations are based on the current retail price of each game, not the price you bought them at. I mostly buy games on Steam when they are on sale so those kinds of estimations are nowhere close to what I’ve actually spent on Steam.

Steam does have a page where you can view your transaction history. If you go to https://store.steampowered.com/account/ you’ll see something like this:

By the way, don't buy The Bridge. It's not worth your money or time. Get Antichamber for a good puzzle game!

By the way, don’t buy “The Bridge”. It was boring – too easy puzzles!

Using a calculator you could add up what you’ve spent on Steam purchases, however it’s tedious to manually sum the prices and for me it displays in the wrong currency. I live in Sweden and our currency is Swedish Krona (SEK), not Euro (EUR). If I want to get the right amount in SEK I have to convert EUR to SEK, and additionally I have to use the exchange rate for the actual day of the transaction if I want an accurate result. I could probably get the transaction history in SEK from my bank, but then I wouldn’t know which games were purchased for each transaction.

I decided to make a node.js script to do the summing and currency conversions for me. My script uses Open Exchange Rates to fetch historical exchange rates. I downloaded the Steam account page as an HTML file, and then ran jQuery on that using jsdom to scrape transactions.

This is the first time I’ve coded something non-trivial in node.js so my code is probably shitty. Still, using node.js felt very sophisticated. Here is the part of the code that scrapes transactions from the Steam page:

fs.readFile(account_filename, function (err, html) {
  if (err) {
    throw err;
  }
  jsdom.env({
    html: html,
    encoding: 'binary',
    src: [jquery],
    done: function (errors, window) {
      var $ = window.jQuery;
      var row = $('#store_transactions .transactionRow');
      row.each(function (index) {
        var event = $(this).children('.transactionRowEvent').text();
        if (event == 'Purchase') {
          var date = $(this).children('.transactionRowDate').text();
          var price = $(this).children('.transactionRowPrice').text();
          var title = $(this).find('.transactionRowTitle').text();
          addPrice(title, new Date(date), price);
        }
      });
    }
  });
});

You can look at the rest of the code on GitHub if you feel like it.

No Comments on How much have I spent on Steam?
Categories: Programming

Gravazoid 2013-04-02

gravazoid

Lft and I created a game we call Gravazoid that entered into the Game competition at the demo party Revision 2013. It placed 2nd! Yay! You can see some gameplay of Gravazoid on YouTube.

Lft composed the music and I designed the typeface in Gravazoid but we can both be blamed for the code.

You can get the source code for Gravazoid on GitHub!

Download Gravazoid for Windows here.

7 Comments on Gravazoid
Categories: Programming

Hacking in Minecraft 2013-01-02

In order to figure out exactly how the rotation of lily pads is calculated in Minecraft I downloaded the Minecraft Coder Pack. This handy package includes scripts to decompile Minecraft so that you can edit and run Minecraft directly in Eclipse. It even does a great job of deobfuscating the source code so that most methods and fields have relevant names.

I was really surprised how easy it was to change things in Minecraft. I quickly figured out how the lily pad rotation worked so that I could implement it in Chunky. I also had a bit of fun with changing some things in the game:

Minecraft, llbit edition! (Mojang please don't sue me!)

Minecraft, llbit edition! (Mojang please don’t sue me!)

candyland

2 Comments on Hacking in Minecraft
Categories: Programming

Polyspasm! 2012-12-10

My demo is now finished! Here is a YouTube video I recorded of it yesterday:

You can get the code for Polyspasm at GitHub.

Also, if you are interested, you can read the project report.

1 Comment on Polyspasm!
Categories: Programming

Fire in GLSL 2012-12-04

I’ve implemented a fire shader in GLSL. Looks pretty cool:

Fire effect

Fire effect

4 Comments on Fire in GLSL
Categories: Programming