How to pass argument to NAnt exec task conditionally based on the property existence?
Asked Answered
R

3

8

I'd like to call a certain EXE from my NAnt script, and pass a property as an argument in case the property exists, or don't pass anything otherwise.

The below code seems to fit just for this case, but it doesn't work:

<exec program="notepad.exe">
  <arg line="${file}" if="${property::exists('file')}" />
</exec>

It throw Property 'file' has not been set error. Looks like it evaluates the property ignoring the condition. I would expect it to ignore the entire <arg> element in case its condition is false.

If I define the property above this block, it obviously works fine (even if the property is empty). It could be worth a workaround if it's a single case, but I have to pass a number of properties the same way. Besides, <if> is not a valid element under <exec>...

How to achieve this? Any ideas?

Recover answered 20/9, 2012 at 15:19 Comment(0)
R
8

I dag out an old thread at NAnt mailing list, which actually gives the best suggestion for a workaround (to my case). It's based on the fact that <property> task works as expected. The workaround introduces an extra property to set depending on whether the original property is defined or not.

Like this:

<target name="example">
  <property name="arg.value" value="${arg}" if="${property::exists('arg')}" />
  <property name="arg.value" value="" unless="${property::exists('arg')}" />
  <exec program="program.exe">
    <arg value="${arg.value}" />
  </exec>
</target>

In my case it turns out to be easier to always set a property with default value, and even don't introduce an extra property - just pass the original property to <arg/>:

<target name="example">
  <property name="arg.value" value="default value" overwrite="false" />
  <exec program="program.exe">
    <arg value="${arg.value}" />
  </exec>
</target>

It can (and will) be overwritten in other include files.

I have also found another thread where the same question was asked, and a person involved into the NAnt development suggested to indicate whether people are interested in a patch to fix this for <arg> element. As far as I can see, no one demonstrated the interest :), hence the behavior wasn't changed.

I managed to put a little time investigating what a fix could be, and it seems that it's only about adding ExpandProperties=false to the TaskAttribute for e.g. the line property of the <arg> task. The same is done for <property value="..."> attribute where it works as expected. I didn't try it out, though - if I have some more time one of these days, I will and post an update here.

Recover answered 25/9, 2012 at 13:0 Comment(2)
You can optionally set the default of the same variable you're reading. This seems more clear and is a single statement instead. <property name="arg" value="false" unless="${property::exists('arg')}"/>Eadie
Based on your use case, do you mean the following for your second code snippet? <target name="example"> <property name="arg" value="default value" overwrite="false" /> <exec program="program.exe"> <arg value="${arg}" /> </exec> </target>Rudyrudyard
J
0

For that case, you can just use a fileset to pass as the arguments. By default, fileset does not include items that did not match actual files on disk.

Josiahjosias answered 21/9, 2012 at 12:23 Comment(1)
Thanks for your suggestion. Unfortunately, it's not only about files - it was just a sample. I have to pass a big number of arguments, of various nature. I'll shape what I ended up with in an answer.Recover
B
0

I also ran into this issue (to be honest even more than once). The if-attribute in some cases doesn't work as you might expect it to. This is my ugly workaround:

<choose>
  <when test="${property::exists('file')}">
    <exec program="notepad.exe">
      <arg line="${file}" />
    </exec>
  </when>
  <otherwise>
    <exec program="notepad.exe" />
  </otherwise>
</choose>
Barnwell answered 22/9, 2012 at 6:35 Comment(1)
Thanks for your suggestion. Well, that makes sense for 1 argument - but I have to pass a big number of arguments. I'll shape what I ended up with in an answer.Recover

© 2022 - 2024 — McMap. All rights reserved.