set-file-versions

This task changes version information in source file headers. It runs Apache ANT using a simple build script, which in turn calls a macro that changes the version line. The default build and macro files change java files and all relevant framework files. These files can be used as template for writing other substitutions, if required.

-b | --build-file FILE   ANT build file
-d | --directory DIR     start directory with source files
-h | --help              print help screen and exit
-m | --macro-file FILE   ANT macro file
-v | --version VERSION   new version string

Examples

The following example will change the version in all files in the directory src to 0.1.0. It will use the default build and macro file.

set-file-versions --version 0.1.0 --directory ./src

Requirements

The task requires Apache ANT (dependency ant). It also needs the parameters VERSIONS_BUILD_FILE and VERSIONS_MACRO_FILE to be set. Both parameters come with default values (the build and macro file provided by the framework). Settings these parameters will make the task using different build or macro files.

The Build File

The build file is a file called build.xml with information for ANT on what to build, and how. The default build file provided by the framework should be sufficient for all use cases. The XML below shows the default build file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<project name="pm" default="skb-set-versions">
    <!-- ant -f ant/build.xml -DmoduleVersion=VERSION_STRING -DmoduleDir=../ -DmacroFile=SOME_FILE -->
    <property name="module.version" value="${moduleVersion}"/>
    <condition property="macroFile" value="macro.xml">
        <not>
            <isset property="macroFile"/>
        </not>
    </condition>
    <import file="${macroFile}"/>
    <target name="skb-set-versions">
        <push-version module.dir="${moduleDir}" sourceEncoding="UTF-8" />
    </target>
</project>

The build file is kept very simple. The version string is provided by the setting moduleVersion, which is translated into the property module.version. The macro file is either provided by a setting macroFile or as the default value macro.xml. If the default value is used, the macro file must be in the same directory as the build file.

The build file then define its only target skb-set-versions. For the actual substitution of strings, the build file calls a macro push-version The start directory is provided by the setting moduleDir, which is translated into a property module.dir for the macro.

Line 3 shows an example use of the build file from the command line.

The Macro File

The macro file is called macro.xml (default) or defined in the build file (see above). The actual macro then must be called push-version. The following source block shows the default macro file provided by the framework.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<project name="skb-set-versions">
    <macrodef name="push-version" description="Updates the internal version string of all SKB-Framework source files.">
        <attribute name="module.dir"/>
        <sequential>
            <replaceregexp byline="false" encoding="UTF-8">
                <!-- sed "s/^ \* @version.*$/ \* @version    ${version}/" -->
                <regexp pattern=" \* @version(.*)"/>
                <substitution expression=" \* \@version    ${module.version}"/>
                <fileset dir="@{module.dir}" >
                    <include name="src/**/*.java" />
                </fileset>
            </replaceregexp>

            <replaceregexp byline="false" encoding="UTF-8">
                <!-- sed "s/^## @version.*$/ \*## @version    ${version}/" -->
                <regexp pattern="## @version(.*)"/>
                <substitution expression="## @version    ${module.version}"/>
                <fileset dir="@{module.dir}" >
                    <include name="src/main/bash/**/*.sh" />
                    <include name="src/main/bash/**/*.id" />
                    <include name="src/main/bash/scenarios/**/*.scn" />
                    <include name="src/main/bash/bin/skb-framework" />
                    <include name="src/main/bash/bin/**/_include" />
                    <exclude name="**/set-file-versions.sh" />
                </fileset>
            </replaceregexp>
        </sequential>
    </macrodef>
</project>

The main functionality is a sequential execution of a regular expression replacement (replaceregexp), for all files satisfying the given filters. Replacements are done en block (i.e. not by line). The encoding is always UTF-8, For each replacement:

  • regexp - defines the search pattern. This pattern is essentially a comment (in the respective source file language), followed by the string ` @version` and the rest of the actual line.

  • substitution - defines the replacement string This string starts with the same comment, ` @version ` string, then followed by the new version ${module.version}.

  • fileset - defines which files should be processed. Files are taken from the start directory. include defines include patterns. exclude defines exclude patterns. Globbing is used to catch all files recursively. For instance src/*/.java will process all files with the extension .java in the folder @{module.dir}/src.

The following examples show a number of standard patterns and substitution expressions.

JDOC style comments
sed "s/^ \* @version.*$/ \* @version    ${version}/"
regexp pattern=" \* @version(.*)"
substitution expression=" \* \@version    ${module.version}"
files: **/*.java
C/C++/Java single line comment style
sed "s/^ \/\/ @version.*$/ \* @version    ${version}/"
regexp pattern="// @version(.*)"
substitution expression="// \@version    ${module.version}"
files: **/*.java, files: **/*.cpp
BASH single hash comment style
sed "s/^# @version.*$/ \*# @version    ${version}/"
regexp pattern=" # @version(.*)"
substitution expression=" # \@version    ${module.version}"
files: **/*.sh
BASH double hash comment style
sed "s/^## @version.*$/ \*## @version    ${version}/"
regexp pattern="## @version(.*)"
substitution expression="## @version    ${module.version}"
files: **/*.sh