Ant global <compilerarg> property - ant

I need to set two global properties to be used with invocation of javac in my ant script.
Currently I have this in each of my javac invocations:
<compilerarg compiler="org.eclipse.jdt.core.JDTCompilerAdapter" line="-1.6 -warn:none"/>
I tried to set a global property like this
<property name="compiler.args" value="-1.6 -warn:none" />
But only the first argument is given to javac, the second is ignored.

As per : http://ant.apache.org/manual/using.html#arg , one can have space for line attribute of compilerarg.
line a space-delimited list of command-line arguments.
Just using is below is resulting in any specific error, after property is set?
<compilerarg compiler="org.eclipse.jdt.core.JDTCompilerAdapter" line="${compiler.args}"/>

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

How to pass nested arguments from one ant target to another

How to pass nested arguments from one ant target to another?
I need to pass a variable number of nested elements from one target to another.
I have a common file with all of my standard build tasks that's included in all of my projects.
I am adding a new custom task that takes a variable number of nested arguments
As a standard, all ant calls are made through the common file to ensure consistency of build style and logging.
Thus the new custom task and its nested child will be defined in the common script.
The project build script looks like this
<target name="projectBuild">
...
<ant target="_newFooTaskWrapper" antfile="commonFile">
<property name="_arg1" value="hello"/>
<property name="_arg2" value="world"/>
<nestedArg value="qux"/>
<nestedArg value="baaz"/>
...
<nestedArg value="AAAAA"/>
</ant>
...
</target>
The common script looks like this:
<target name ="_newFooTaskWrapper">
<echo message="Target _newFooTaskWrapper in project ${ant.project.name} from base directory ${basedir}"/>
<echo message="arg1 = ${_arg1}"/>
<echo message="arg2 = ${_arg2}"/>
<taskdef name="newFooTask" classname="org.foo.NewFooTask"/>
<typedef name="nestedArg" classname="org.foo.NewFooTask$NestedArg"/>
<newFooTask arg1="${_arg1}" arg2="${_arg2}">
<nestedArg value="qux"/>
<nestedArg value="baaz"/>
...
<nestedArg value="AAAAA"/>
</newFooTask>
Obviously, this isn't right. My question is, what's the right way to do this?
I need to pass a variable number of nested elements from one target to another.
For "varible", I assume you mean you don't know the exact number of the nested elements you want to pass to the task, so what you want is something like method(Object param...) in java, is it?
It's not a good idea to try such a way. Ant is not a scripting language but a build tool. It provides limited "scripting" possibilities.
However, you can try it in the following two ways:
1, If your nested element is just in the form of <elementName value="xx" />, you don't need anything complicated. Just pass another property containing a comma seperated list of the values, and process the list in your custom ant task. It's easy for Java to split the property into a list and process it.
2, If your nested element may be more complicated... maybe you can try reference:
Make a type fooTaskParams which can be referenced via an id:
<fooTaskParams id="_foo_task_params">
<nestedArg value="qux"/>
<nestedArg value="baaz"/>
...
<nestedArg value="AAAAA"/>
</fooTaskParams>
and pass the reference to the other build file:
<ant target="_newFooTaskWrapper" antfile="commonFile">
<property name="_arg1" value="hello"/>
<property name="_arg2" value="world"/>
<reference refid="_foo_task_params"/>
</ant>
and then make your task to be able to process the reference:
<newFooTask arg1="${_arg1}" arg2="${_arg2}" paramRefId="_foo_task_params" />
You may need to take care of reference override, or make your task able to process the ref as well as taking nested elements.
Read ant's manual about <ant> and <typedef> for more about this approach, and refer to SO Q&As like this when you encount any problem.

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.

Override the compiler attribute in an Ant javac task

I'm trying to override Ant compiler attributes via the command line so that all 'javac' tasks use my specified compiler.
The problem I've run into is that any target that sets its own value for compiler overrides the one that I set at the commmand line. So, even though I'm entering the following command.
ant -Dbuild.compiler=mycompiler
Any target that has the following is going to use the modern compiler instead of mycompiler because of that compiler="modern" attribute
<javac srcdir="."
destdir="${classes.dir}/core"
compiler="modern"
encoding="UTF-8">
<include name="org/**" />
<include name="com/**" />
<compilerarg line="${config.build.compilerarg}" />
</javac>
Is there any way to override this from the command line, or am I stuck editing the build file?
The Ant javac task documentation says:
It is possible to use different compilers. This can be specified by either setting the global build.compiler property, which will affect all tasks throughout the build, or by setting the compiler attribute, specific to the current task. Valid values for either the build.compiler property or the compiler attribute are:
It sounds as if you can either specify the global build.compiler property or set a specific compiler attribute.
So, it looks like you will need to modify your build file and either:
remove the compiler attribute from the javac calls and allow the
global build.compiler setting to
cascade down
change the values of the compiler
attribute from a hard-coded string
compiler="modern" to be property
compiler="${javac.compiler}"

Resources