Wednesday, 17 June 2009

Ant Rant - Version filtering deprecated

Filtering is one of those features which Ant makes available which was overused in the initial excitement when Ant was new.

By using version filtering you are tying your codebase into being built by Ant, or at least a build system which has the same filtering mechanism as Ant.

In Melati, WebMacro and now ten years later in Jena there was a feature to filter the code and insert the version number. The uses are so similar I suspect they were in some popular "Introduction to Ant".

We even had tests to ensure that the version variable had been successfully filtered.

assertNotEquals("@version@", Product.VERSION);

When I came to convert to Maven I wanted to keep this handy feature, but of course the test was failing.

I asked how to do filtering on the Maven lists way back. They were very scathing about the notion of a build process modifying production code. It is not the Maven way.

The question that needs a very convincing answer is what is this for? Does it fit with how people use and develop the software.

As a developer, in your IDE, do you want to see

public static final String NAME = "@Name@";

or more sanely

public static final String NAME = "MyProject";

Filtering may work for the users but not for the developers.

Lets look at the actual use cases, taking Jena as a typical project. A sensible place for these strings is Jena.java. Of the static strings in the following references are found.

PATH - 15 references - interestingly hardcoded, not interpolated.
NAME - 0 references
WEBSITE - 0 references
VERSION - 0 references
MAJOR_VERSION - 0 references
MINOR_VERSION - 0 references
REVISION_VERSION - 0 references
VERSION_STATUS - 0 references
BUILD_DATE - 0 references

We can see that after 6 years this facility has not actually been used. It was put in because the coder knew how to do it and thought it might come in useful. It hasn't. YAGNI.

If you REALLY want to use filtering then filter a properties file using Maven Resource Filtering.

However if you do just want to provide, for example, a version command in your application then explicitly add the version string as a static variable in a prominent place in your code and add a step to your release procedure document to update this variable.

Code should not depend upon the build system: rip it out.