You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Shawn Castrianni <Sh...@halliburton.com> on 2010/05/26 17:03:30 UTC

New ANT task coding guideline

I would like to propose a new ANT task coding guideline.  I frequently need to allow my users to customize the ANT build via a build.properties file.  Therefore, a lot of my ANT task usage has placeholders for the various different ant task attributes with variables, ${xxxx}.  The problem is that many ANT tasks are written such that specifying an attribute with an empty string has DIFFERENT behavior than not specifying that attribute at all.  I think this is a problem.  That causes my code to have to use <if> statements to check if ${xxxx} is set so that I can call the ANT task with or without the attribute specified.

Here is an example:

I wrote a macrodef called launchNative that would just call the <exec> task with optional parameters for spawn and resultproperty.  They are optional since I defaulted their values in the macrodef:

<attribute name="spawn" default="false"/>
<attribute name="resultproperty" default=""/>

In the actual call to <exec>, I had to put in the placeholders based on the parameters of the macrodef like:

<exec spawn="@{spawn}" resultproperty="@{resultproperty}"/>

Now if the user passes in a macrodef parameter of spawn="true", the <exec> call will fail even though resultproperty is defaulted to the empty string.  This is because the setter for resultproperty in the <exec> ant task does NOT check the input resultproperty value to detect the empty string and do nothing.  Instead it sets a flag stating it is not compatible with spawn and the <exec> task eventually fails.

In order for me to get around this, I would have to use an <if> to check the value of @{resultproperty} and call a separate invocation of <exec> without resultproperty specified.  This is frustrating.

Therefore, I propose that a new ANT task coding guideline be introduced such that all setters (where applicable) check the incoming values for null or empty strings and behave as if the setter was never called.

---
Shawn Castrianni

----------------------------------------------------------------------
This e-mail, including any attached files, may contain confidential and privileged information for the sole use of the intended recipient.  Any review, use, distribution, or disclosure by others is strictly prohibited.  If you are not the intended recipient (or authorized to receive information for the intended recipient), please contact the sender by reply e-mail and delete all copies of this message.

Re: New ANT task coding guideline

Posted by Bruce Atherton <br...@callenish.com>.
On 30/05/2010 11:27 AM, Bruce Atherton wrote:
> <exec spawn="false" resultproperty="result" failonerror="false" ...>
>
I realized that I screwed up two ways with this answer. First, my 
intention was 'resultproperty="${result}"' rather than as written. But 
this won't work either because the PropertyHelper will just give back 
the literal string when the setter is called. In fact, as far as I know 
there is no way for PropertyHelper to pass a null to a setter. Somebody 
correct me if this is wrong.

So there are two other ways I can see to do this. You could write a 
PropertyHelper delegate that could return a null rather than the 
original string, probably using an additional marker character so you 
still got the original behaviour elsewhere. So you might write 
'resultproperty="${#result}"' and have a property helper interpret that 
and return null if necessary.

Probably a simpler solution is to use Antcall. Then you can go back to 
your original macrodef with both spawn and resultproperty, but do an 
Antcall with parameters for the spawn and the result. Something like this:

   <macrodef name= ...>
       <attribute name="spawn" default="false"/>
       <attribute name="resultproperty" default="false"/>
       <sequential>
           <local name="one-param-set" />
           <local name="use-result" />
           <condition property="use-result">
             <not>
               <or>
                 <equals arg1="@{resultproperty}" arg2="false" casesensitive="false" />
                 <equals arg1="@{resultproperty}" arg2="off" casesensitive="false" />
                 <equals arg1="@{resultproperty}" arg2="no" casesensitive="false" />
               </or>
             </not>
           </condition>
           <condition property="one-param-set">
             <or>
               <istrue value="@{spawn}" />
               <isset property="use-result" />
             </or>
           </condition>
           <antcall target="exec-command" inheritAll="false">
             <param name="spawn" value="@{spawn}" />
             <param name="use-result" value="${use-result}" />
             <param name="resultproperty" value="@{resultproperty}" />
             <param name="one-param-set" value="${one-param-set}" />
           </antcall>
       </sequential>
   </macrodef>

   <target name="exec-spawn-command" if="${spawn}">
     <exec spawn="true" ... />
   </target>

   <target name="exec-result-command" if="${use-result}" unless="${spawn}">
     <exec resultproperty="${resultproperty}" />
   </target>

   <target name="exec-command" depends="exec-spawn-command,exec-result-command"
       unless="${one-param-set}">
     <exec ... />    <!-- with no resultproperty or spawn -->
   </target>



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: New ANT task coding guideline

Posted by Bruce Atherton <br...@callenish.com>.
On 27/05/2010 2:04 AM, Jan.Materne@rzf.fin-nrw.de wrote:
> Please have a look at https://svn.apache.org/repos/asf/ant/sandbox/autoconf/
> Maybe that could help.
>    

But he still has a call to the setter even if it is autoconfed.

Note that setting spawn and resultproperty are mutually exclusive. If 
you spawn a process you can never get its result. I'd therefore suggest 
you separate this into two macrodefs. The spawning exec macrodef would 
be straightforward, the other might work if you did this:

<macrodef name="call-process">
<attribute name="resultproperty" default="false"/>
<sequential>
<local name="result" />
<condition property="result" value="@{resultproperty}" >
<not>
<or>
<equals arg1="@{resultproperty}" arg2="false" casesensitive="false" />
<equals arg1="@{resultproperty}" arg2="off" casesensitive="false" />
<equals arg1="@{resultproperty}" arg2="no" casesensitive="false" />
</or>
</not>
</condition>
<exec spawn="false" resultproperty="result" failonerror="false" ...>
</sequential>
</macrodef>

Note that you can't use <isfalse> for the condition because it is the 
negation of <istrue> rather than dealing with the false values directly. 
This means that passing "test-property" to resultproperty would leave 
the value unset. Checking for false values with equals solves the problem.

I haven't tested this to be sure it works, but if it works then so far 
as I can see the only side effect should be that you can no longer spawn 
with this macrodef because the setter on resultproperty sets a flag that 
says spawning isn't possible. So long as you can separate spawning 
processes from non-spawning processes in your build, I think this might 
solve your problem.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


AW: New ANT task coding guideline

Posted by Ja...@rzf.fin-nrw.de.
Please have a look at https://svn.apache.org/repos/asf/ant/sandbox/autoconf/
Maybe that could help.
 
Jan

>-----Ursprüngliche Nachricht-----
>Von: Antoine Levy-Lambert [mailto:antoine@gmx.de] 
>Gesendet: Mittwoch, 26. Mai 2010 17:31
>An: Ant Users List
>Betreff: Re: New ANT task coding guideline
>
>Hello Shawn,
>
>I hope some one has a useful answer for this.
>
>-------- Original-Nachricht --------
>> Datum: Wed, 26 May 2010 10:03:30 -0500
>> Von: Shawn Castrianni <Sh...@halliburton.com>
>> An: "\'Ant Users List\'" <us...@ant.apache.org>
>> Betreff: New ANT task coding guideline
>
>> Therefore, I propose that a new ANT task coding guideline be 
>introduced
>> such that all setters (where applicable) check the incoming 
>values for null
>> or empty strings and behave as if the setter was never called.
>> 
>Changing the behavior of ant to skip calling setters when the 
>attributes are empty would not be backward compatible. Maybe 
>something like that could be done based on a magic property, 
>which would be unset by default ?
>
>Regards,
>
>Antoine
>> ---
>> Shawn Castrianni
>> 
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
>For additional commands, e-mail: user-help@ant.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: New ANT task coding guideline

Posted by Antoine Levy-Lambert <an...@gmx.de>.
Hello Shawn,

I hope some one has a useful answer for this.

-------- Original-Nachricht --------
> Datum: Wed, 26 May 2010 10:03:30 -0500
> Von: Shawn Castrianni <Sh...@halliburton.com>
> An: "\'Ant Users List\'" <us...@ant.apache.org>
> Betreff: New ANT task coding guideline

> Therefore, I propose that a new ANT task coding guideline be introduced
> such that all setters (where applicable) check the incoming values for null
> or empty strings and behave as if the setter was never called.
> 
Changing the behavior of ant to skip calling setters when the attributes are empty would not be backward compatible. Maybe something like that could be done based on a magic property, which would be unset by default ?

Regards,

Antoine
> ---
> Shawn Castrianni
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org