Create Property file inside build.xml - ant

I want to create a .properties file dynamically, and code for the same should be inside build.xml with some values and want to placed it in some directory.
Please Help

You should use the PropertyFile Ant task, for instance:
<propertyfile file="my.properties">
<entry key="prop.1" value="value 1"/>
<entry key="prop.2" value="value 2"/>
</propertyfile>

Related

ant build version with leading zeros

I want my version numbers of the installer files to be like installer-02.
I have the following entry in <entry key="build.number" type="int" value="2" />
How to achieve this.
You can specify pattern for int type when you add entry to property file http://ant.apache.org/manual/Tasks/propertyfile.html.
<propertyfile
file="my.properties"
comment="My properties">
<entry key="build.number" type="int" value="2" pattern="00"/>
</propertyfile>
<property file="my.properties"/>
<echo message="build.number : ${build.number}"/>
Please note with above eg, it will prefix build # with 0 for values from 0-9.

Ant writing property file storing filtered properties

I'm facing a very simple problem with ANT script. I have a script that loads and sets many properties loaded from several property files in file system. This properties are used to preconfigure a new project.
The question is: can I write a new property file persisting all the properties that starts with a given prefix (for example "ref.proj.*")?
The number and the name of the properties is variable and so I cannot use the
<propertyfile file="my.properties">
<entry key="ref.proj.first" value="${ref.first}"/>
...
<entry key="ref.proj.n" value="${ref.n}"/>
</propertyfile>
It's possibile to apply a filter to a propertyfile task?
Thanks in advance!
It's taking too long for me to work out all of the kinks. Sorry...
You should look at the <echoproperties> task. This will let you select the various properties and print them out in property = value format.
You could use that as your properties file itself.
The following example uses the groovy ANT task:
<path id="build.path">
<pathelement location="lib/groovy-all-2.1.0.jar"/>
</path>
<target name="create-properties">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
<groovy>
new File("my.properties").withWriter { writer ->
properties.findAll { it.key.startsWith("ref.proj") }.each {
writer.println it
}
}
</groovy>
</target>

reloading properties after updating a property file

I'm trying to read a property after updating it using propertyfile task. Something like
<property file="test.properties" />
<echo>before :: ${modules}</echo>
<propertyfile file="test.properties" >
<entry key="modules" type="string" operation="+" value="foo" />
</propertyfile>
<property file="${status.path}/test.properties" />
<echo>after :: ${modules}</echo>.
It doesn't seem to load the second time. But the property file is updated.
You can invoke a new ant runtime with the antcall task that ignores the properties of your main target runtime - just make sure to include inheritAll="false"
<target name="main">
<property file="test.properties"/>
<echo>before :: ${modules}</echo>
<propertyfile file="test.properties">
<entry key="modules" type="string" operation="+" value="foo" />
</propertyfile>
<antcall target="second-runtime" inheritAll="false"/>
</target>
<target name="second-runtime">
<property file="${status.path}/test.properties" />
<echo>after :: ${modules}</echo>
</target>
antcall refrence
As sudocode already mentioned, in Core Ant properties are immutable - for good reasons.
With the unset task from Antelope Ant Tasks you're able to unset all properties set in a file with a one liner :
<unset file="test.properties"/>
afterwards
<propertyfile file="test.properties" >
<entry key="modules" type="string" operation="+" value="foo" />
</propertyfile>
will work.
Hint : the task works only for normal properties, not for xmlproperties.
But there's a simple workararound, simply use <echoproperties prefix="..." destfile="foo.properties"/> and afterwards <unset file="foo.properties"/>
If you don't want to use Antelope for that specific task only, you may write a macrodef or own task with similar features.
For this case, when whole properties file is loaded twice, I suggest using different prefixes for the first and second load. First load with aprefix attribute equal to first. Access the properties with this prefix, that is property foo will be accessible as first.foo. Then save the properties file and load again, but this time without a prefix. You will get modified properties in suitable place.
Without using the prefix the second load will do nothing, as ant prevents properties from overriding. Others pointed that already.
Ant properties are immutable - once set, they are fixed. So reloading the properties file will not refresh the value of a property already set.
this macro allow you to change the property value after fixed one
<macrodef name="set" >
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<script language="javascript">
<![CDATA[
project.setProperty("#{name}", "#{value}");
]]>
</script>
</sequential>
</macrodef>
you can create a new properties file and save the property in the new file.
Provide the reference of the file in the next line.
Done :)

Ant propertyset inheritance with nested tasks

I have a set of nested Ant build files, and I need to control which properties are inherited by each "sub" task. I'm trying to define these as propertysets (to keep the code manageable) but these are not inherited by subtasks, unlike properties.
The example below demonstrates the problem, foo.* get copied into the middle project but not to the bottom project. If I define each property to be inherited explicitly, like bar.*, they get inherited by the bottom project too.
Is there any way to get a group of properties to inherit all the way down, in the same way individual properties do? Without rewriting the sub-processes, is there something else I could try?
[top.xml]
<?xml version="1.0"?>
<project name="test-top">
<property name="foo.1" value="1"/>
<property name="foo.2" value="2"/>
<property name="bar.1" value="1"/>
<property name="bar.2" value="2"/>
<ant antfile="middle.xml" inheritall="false">
<propertyset>
<propertyref prefix="foo."/>
</propertyset>
<property name="bar.1" value="${bar.1}"/>
<property name="bar.2" value="${bar.2}"/>
</ant>
</project>
[middle.xml]
<?xml version="1.0"?>
<project name="test-middle">
<echo>foo ${foo.1} ${foo.2}</echo>
<echo>bar ${bar.1} ${bar.2}</echo>
<ant antfile="bottom.xml" inheritall="false"/>
</project>
[bottom.xml]
<?xml version="1.0"?>
<project name="test-bottom">
<echo>foo ${foo.1} ${foo.2}</echo>
<echo>bar ${bar.1} ${bar.2}</echo>
</project>
[OUTPUT OF ant -f top.xml]
[echo] foo 1 2
[echo] bar 1 2
[echo] foo ${foo.1} ${foo.2}
[echo] bar 1 2
I think Alexander's solution is close. How about this though, doesn't need any change in middle.xml or bottom.xml.
The idea is to use the echoproperties task to 'unroll' the propertyset to individual properties, then to use that in the ant task call.
Before calling middle.xml, write the property set out using something like this:
<echoproperties destfile="myproperties.txt">
<propertyset>
<propertyref prefix="foo."/>
<propertyref prefix="bar."/>
</propertyset>
</echoproperties>
Then make the call to middle.xml:
<ant antfile="middle.xml" inheritall="false">
<property file="myproperties.txt" />
</ant>
Properties supplied to the ant task inherit all the way down as you say, so you only need to change top.xml:
These properties become equivalent to
properties you define on the command
line. These are special properties and
they will always get passed down, even
through additional <ant> tasks with
inheritall set to false (see above).
In top.xml you can create a file with inheritable properties using <propertyfile> task.
Then you can load this file with <property file="..."/>in each of your submodules.

Use ANT to update build number and inject into source code

In my build.xml file I am incrementing a build version number in a property file like so:
<target name="minor">
<propertyfile file="build_info.properties">
<entry key="build.minor.number" type="int" operation="+" value="1" pattern="00" />
<entry key="build.revision.number" type="int" value="0" pattern="00" />
</propertyfile>
</target>
I also have similar entries for the major and revision. (from Build numbers: major.minor.revision)
This works great. Now I would like to take this incremented build number and inject it into my source code:
//Main.as
public static const VERSION:String = "#(#)00.00.00)#";
By using:
<target name="documentVersion">
<replaceregexp file="${referer}" match="#\(#\).*#" replace="#(#)${build.major.number}.${build.minor.number}.${build.revision.number})#" />
</target>
Now this sorta works. It does indeed replace the version but with the outdated version number. So whenever I run the ANT script the build_info.properties is updated to the correct version but my source code file is using the pre updated value.
I have echoed to check that indeed I am incrementing the build number before I call the replace and I have noticed that echoing:
<echo>${build.minor.number}</echo>
//After updating it still shows old non updated value here but the new value in the property file.
So is there a way to retrieve the updated value in the property file so I can use it to inject into my source code?
Cheers
So after spending hours not being able to solve this, I post this question and then figure it out 20 minutes later.
The problem was I had this at the top of my build file:
<property file="build_info.properties"/>
I guess it was due to scoping and that properties are immutable thus I was never able to update the value. Removing that line and then adding the following got it working perfectly:
<target name="injectVersion">
<property file="build_info.properties"/>
<replaceregexp file="${referer}" match="#\(#\).*#" replace="#(#)${build.major.number}.${build.minor.number}.${build.revision.number})#" />
</target>
Why not just use <buildnumber/>?
Project used to increment build number in build.properties file
file parameters:
version.number=
build.number=
if changes version.number then build.number starts from 1
====================================================================== -->
<property name="versionFileName" value="build.properties" />
<property file="${versionFileName}" />
<property name="currentVersion" value="0.1.37"/>
<target name="calculate.version.build">
<script language="javascript">
<![CDATA[
var currentVersion = project.getProperty("currentVersion");
var oldVersion = project.getProperty("version.number");
var buildNumber = project.getProperty("build.number");
if (!currentVersion.equals(oldVersion)){
project.setProperty("currentBuild", 1);
} else {
var newBuildNumber = ++buildNumber;
project.setProperty("currentBuild", newBuildNumber);
}
]]>
</script>
</target>
<target name="update.version.build" depends="calculate.version.build">
<propertyfile file="${versionFileName}">
<entry key="build.number" type="int" operation="=" value="${currentBuild}" />
<entry key="version.number" type="string" operation="=" value="${currentVersion}" />
</propertyfile>
<echo message="New version: ${currentVersion}.${currentBuild}" />
</target>

Resources