Question related to find/replace using propertyregex - ant

In my ant build file, I have a property 'Version' that contains the version. Ex. 2.5.17.230
Now, I am using propertyregex of ant-contrib to replace all '.' (dot) characters with an underscore. I have written the statement as follows:
<propertyregex property="Version" input="${Version}" regexp="." replace="_" global="true" />
However, it does not work. I have even tried these in vain:
regexp="\." and regexp="[.]"
Can someone please help?
Thanks

The PropertyRegex documentation states that unless the override attribute is set to true, the task will not overwrite the property value if it's already set. And since you're trying to overwrite the Version property, your example will do nothing.

Got it! I was passing the same variable as input. I used another variable 'Version2' to get the result from propertyregex. Here is what it should have been:
<propertyregex property="Version2" input="${Version}" regexp="\." replace="_" global="true" />
Cheers!

Related

Ant replace property value by property name in a xml file

I need to replace property value in a xml file using the property name.
Ex:
<property name="test-name" value="default-value"/>
I have a target to replace this value . i.e "default-value". User can run this target several times if he's given a wrong value for property test-name he can try again running target with correct value. Therefore i can not use regular expression to replace "default-value". I can only rely on property name. Is there a way to replace property value using it's name in ant ?
The typical way to do that in Ant is to copy or move the files you want to change, using a FilterSet to define the token-value pairs you want to replace in the files.
So in your "template" version of the file you might have something like this
<document>
<element value="#test-name#"/>
</document>
And in your build file you might have something like this:
<property name="my.value" value="default-value"/>
<copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt" override="true">
<filterset>
<filter token="test-name" value="${my.value}"/>
</filterset>
</copy>
Since I wanted to allow the user to replace value multiple times ( if he/she given a wrong value) i came up with following solution,
<replaceregexp
replace="property name="my.propertyKey"
value="user.value""
byline="true" file="${basedir}/test.xml">
<regexp pattern="property name="my.property"
value="(.*)""/>
</replaceregexp>
This searches property, using property key and replace entire line.

Set Ant project name

I am trying to change the ant.project.name property after the project declaration. I know this is not advisable but it's the only way I can fix a big problem with my project.
I found some interesting posts like this one:
Ant - How to set ${ant.project.name} to project folder name?
Instead of using:
<project basedir="." default="package">
<basename property="ant.project.name"
file="${basedir}"/>
</project>
I'd like to directly set the ant.project.name using a "value" instead of a property "file".
Do you have any ideas or suggestions? Or alternative ways?
Thank you!
As others already mentioned, it's not recommended to change values of standard ant properties.
Also properties once set are immutable in ant by design and for good reasons. Overriding properties should be used wisely and rarely.
The property ant.project.name is usually set via name attribute of project =>
<project name="whatever"> but it's not mandatory, means <project> ... </project> is sufficient to make your xml a valid antscript.
In your case <echo>${ant.project.name}</echo> would echo ${ant.project.name}, as property is not set, so you may create it with property task in your script : <property name="ant.project.name" value="whatever"/>. But using a propertyname that is normally used for 'ant internals' seems not the best choice.
If property is set within project tag it's possible to overwrite the value via script task, using builtin javascript engine and ant api, f.e. :
<project name="foo">
<property name="bla" value="foobar"/>
<echo>1. $${ant.project.name} => ${ant.project.name}</echo>
<script language="javascript">
project.setUserProperty('ant.project.name', project.getProperty('bla'));
</script>
<echo>2. $${ant.project.name} => ${ant.project.name}</echo>
</project>
output :
[echo] 1. ${ant.project.name} => foo
[echo] 2. ${ant.project.name} => foobar
Notice : as ant.project.name is not a 'normal' property (those properties declared via property task within ant script), you have to use the method project.setUserProperty(String, String) instead of project.setProperty(String, String). Userproperties are properties defined via -Dkey=value commandline argument and enjoy a special protection.
Ant also provides a bunch of builtin properties

Store a Value in a Property with Ant or Phing

With Ant or Phing, I need to load a file's contents into a property, run a regular expression on the value of that property, and then store the result of that regular expression in another property. What's the best way to do this?
I can load the file into a property easily (with Phing) like so:
<loadfile file="myfile.txt" property="my.file" />
And I know how to update the file, but I can't seem to figure out how to run a regex on that property, and store the result in a new property for future use.
Any help would be greatly appreciated!
Update
I've been tinkering with it, and this will work. Let me know if there's a streamlined way though! The code below loads a file into a property, then reduces it to only the line that contains the title tag. And then, it runs a regular expression on that line, and stores the contents of that tag in my.prop.
<loadfile file="../index.html" property="my.prop">
<filterchain>
<linecontainsregexp>
<regexp pattern="<title>" />
</linecontainsregexp>
<replaceregexp>
<regexp pattern="[\s\S]+<title>(.+?)</title>" replace="$1" />
</replaceregexp>
</filterchain>
</loadfile>
Update 2
Actually, I ended up using an adhoc task to create my own. Worked perfectly!
You can run an arbitrary command from an ant target like this:
<exec executable="bash">
<arg line="script.sh"/>
</exec>
You can for example store the result of the regexp in a tmp file and then load it into another property the same way as the initial one.
In Phing you could process the content of the property where you loaded the file using the "php" task. See: http://www.phing.info/docs/guide/stable/chapters/appendixes/AppendixB-CoreTasks.html#PhpEvalTask

How to reset a property in ANT?

I'm writing a velocity macro within which I have some ant tasks. Within a #foreach loop in the velocity macro, I have a pathconvert task:
#foreach(<iterate through something>)
<pathconvert property='filename' refid='swf.file'>
<mapper>
<chainedmapper>
<flattenmapper/>
<globmapper from='*-d.swf' to='*'/>
</chainedmapper>
</mapper>
</pathconvert>
#end
The problem I have is that the 'filename' property gets set only once, during the first iteration, since properties in ANT are immutable.
But I need the filename to be set during each iteration. Is there a way to get this done?
If there was a way to reset the property, I could do that at the end of each iteration. Or is there a better way to do this?
Any help would be highly appreciated!
Thanks in advance,
Anand
You could use ant-contrib's variables. They act like mutable properties.
http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html
Use the new lexically scoped properties in Ant 1.8:
"Lexically scoped local properties, i.e. properties that are only defined inside a target, sequential block or similar environment."
Annoucement.
Properties in Ant were designed to be immuatable, but they gave in to popular demand and gave us variables. Your alternative is to write a custom task ( in Java or a Dynamic Language) but this seems like a good compromise.
The following snippet illustrates an ant property which I guess is not documented. Properties are immutable, but references are mutable. So any data type which has no name, but a reference, is mutable. For example a fileset. But today I found a way to have a kind of mutable property. Connected with local task or some other tricks it may be a way of having variables in ant.
<property name="a" value="aaa" id="refa" />
<property name="b" refid="refa" />
<echo>${b}</echo>
<property name="c" value="ccc" id="refa" />
<property name="d" refid="refa" />
<echo>${d}</echo>
The output is:
aaa
ccc
Although in both cases a reference refa is printed.
Here is a post about it. And another one.
Use a combination of for + let task from Ant Plugin Flaka to overwrite existing properties.
See some snippets here.

Valid <property> names in Ant

I'd like to set some properties in my ant build file, the names of which, are based on ant's build in properties. In particular, I'd like to set a property like:
<property name="${ant.project.name}.compiled" value="true" />
However, when I tried this the ${ant.project.home} portion was not expanded.
Is it possible to use the value of properties as the names of other properties, and if so, how?
<property name="name.holder" value="iamholder" />
<property name="${name.holder}.flag" value="true" />
<echoproperties></echoproperties>
result:
[echoproperties] iamholder.flag=true
this is definitely valid ant code and the property iamholder.flag gets the value of true.
If ${name.holder} does not get expanded, it means it has not been set yet (like if the first line in my sample was missing).
Anyways, this still does not quite solve your problem, as you have pretty much no means of getting the value of this property as you don't know it's name and you can't do a nested resolve in pure ant. Depending on what you are trying to do it could still be useful to you though. This one would work (keep in mind, that until 1.8 the value is irrelevant as long as the property is set):
<target name="compile_stuff" unless="${name.holder}.flag">
<echo>compiling...</echo>
</target>
To really get the value of such a property you have to use ant-contrib's propertycopy as suggested in one of the answers. That way you can get the value in a property whose name you know. Just make sure to do the trick just before use and set the override parameter to true (your post implies that you would be setting more properties like these, but without override your final property could not be changed). Another option for working with such properties is to use ant macros.
I think the only way is to echo your values to a .properties file and then load them back.
However, you should ask yourself if you really need it; when I last used ant I tried to do the same thing but concluded I didn't really need to.
Is
$ant.project.home.compiled
not just as useful?
It can be done, a bit ugly, though. You need the < propertycopy > task from ant-contrib for this. The following shows an example
<property name="projectNameCompiled" value="${ant.project.name}.compiled" />
<property name="${projectNameCompiled}" value="true" />
<propertycopy property="final" from="${ant.project.name}.compiled" />
The property final contains the value true.
There are several ways to achieve that, see Ant FAQ
One possible solution via macrodef simulates the antcontrib / propertycopy task but doesn't need any external library.

Resources