views:

586

answers:

5

given a CSV ant property,

<property name="module.list" value="mod1,mod2,mod3,mod4,mod5"/>

how can I just get the first element (ie "mod1" here)? I want to execute a command that will take in "mod1" as one of the arguments.

Moreover.. I cannot modify this original "module.list" property to a list or anything else.. although I can create another list,property,etc from this..

Any help is appreciated.. Thanks

A: 

Use the script task. You can write a script in Javascript or Beanshell and use the Ant API to set a property which you can access from other ant tasks.

tdavies
A: 

This is one way to accomplish what you described.

  1. Write the CSV to a temporary file
  2. parse it with replaceregexp
  3. read the contents of the scrubbed file into a new property
  4. Remove the temporary file

<target name="parse" description="Example of how to parse the module.list property to extract the first value in the CSV"> 
    <property name="module.list" value="mod1,mod2,mod3,mod4,mod5"/>

    <tempfile description="Generate a unique temporary filename for processing"  
    prefix="module.list" suffix="csv" destdir="${basedir}" property="tmpFile" />

    <concat description="Write the value of module.list to the temporary file" 
        destfile="${tmpFile}">${module.list}</concat>

    <replaceregexp description="filter the temporary file using the regex expression to find the first occurance of a , and all characters afer and replace with nothing"
        file="${tmpFile}"
        match=",.*"
        replace=""
        byline="true"/>

    <loadresource description="read the contents of the scrubbed temporary file into the mod1 property"
        property="mod1">
        <file file="${tmpFile}"/>
    </loadresource>

    <delete description="remove the temporary file" 
    file="${tmpFile}" />

    <!--Now you have the parsed value in the mod1 property -->
    <echo message="mod1=${mod1}" />

</target>

Mads Hansen
+1  A: 

Depending on the actual contents of module.list, you might be able to use pathconvert:

<project>
  <property name="module.list" value="mod1,mod2,mod3,mod4,mod5"/>

  <pathconvert property="module.1">
    <path path="${module.list}"/>
    <chainedmapper>
      <flattenmapper/>
      <mapper type="regexp" from="(.*?),.*" to="\1"/>
    </chainedmapper>
  </pathconvert>

  <echo>${module.1}</echo>
</project>

That task does a large amount of string manipulation, so if the contents of module.list can contain special path characters, this approach won't work. In that case, I'd go with one of the more generic answers.

bkail
Nice solution. Easy way to implement regex for string manipulation. I'll have to remember that.
Mads Hansen
A: 

Ant-Contrib to the rescue.

You can use the propertyregex task from Ant-Contrib to extract the first part of a comma-separated string like this:

<propertyregex property="module.first"
               input="${module.list}"
               regexp="^([^,]*),"
               select="\1"/>


For your second question: Ant properties are immutable on purpose, so I would generally recommend against designs which rely on changing values of properties. But if that is what you need, the var task from Ant-Contrib allows you to do just that. In addition, some of the property tasks in Ant-Contrib, like propertyregex mentioned above, have an optional override attribute which allow them to change the value of the target property.

Jukka Matilainen
A: 

First question

with script task it's as easy as =

<project>
 <property name="module.list" value="mod1,mod2,mod3,mod4,mod5"/>
 <target name="main">
  <script language="ruby">
   $project.setProperty 'module.1', $project.getProperty('module.list').split(',')[0]
  </script>
  <echo>${module.1}</echo>
 </target>  
</project>

main: [echo] mod1 BUILD SUCCESSFUL

all you need for script task with jruby is = bsf.jar,commons-logging-1.1.1.jar,jruby-complete-1.3.1.jar

Second question

normally properties are immutable once set in ant, but you can over it, with script task and use of the ant api, f.e. =

  <property name="foo" value="bar"/>
  <script language="ruby">
   $project.setProperty 'foo', 'baz'
  </script>

would overwrite the existing property foo with new value baz, simply use method project.setProperty from ant api with on existing property

Rebse