3

I have an ant property ${src.dirs} that contains a list of dirs separated by a semi colon. Now i need to specify fileset (for replaceregexp) and that fileset has to contain all java files from all dirs listed in ${src.dirs}. How can i do it (I don't use any ant-contrib funcky stuff, I use plain vanilla ant).

The src.dirs have this form: /usr/work/dir1/src;/usr/work/java/dir2/src;/usr/libabc/src There's is an example on how to use propertyregex, but when I try to use it I get this error: build.xml:98: Problem: failed to create task or type propertyregex

Edit: Here's what was my final solution:

<loadresource property="source.dir.javafiles">
  <propertyresource name="source.dir"/>
  <filterchain>
    <tokenfilter>
      <replaceregex pattern="\s*([;,]\s*)*$" replace="/**/*.java"/>
      <replaceregex pattern="\s*([;,]\s*)+"  replace="/**/*.java," flags="g"/>
   </tokenfilter>
  </filterchain>
</loadresource>

<fileset dir="" includes="${source.dir.javafiles}"/>

These regexes ensure that trailing commas or semicolons don't produce wrong fileselectors.

Community
  • 1
  • 1
Pavel P
  • 15,789
  • 11
  • 79
  • 128

3 Answers3

2

You might be able to do this without using ant-contrib. Here's a possibility:

<property
     name="dirlist"
     value="/usr/work/dir1/src;/usr/work/java/dir2/src;/usr/libabc/src" />

<property name="file.wildcard" value="*.java" />    
<loadresource property="dirs.include">
  <propertyresource name="dirlist"/>
  <filterchain>
    <tokenfilter>
      <replaceregex pattern="^/" replace="" />
      <replaceregex pattern=";/" replace="/**/${file.wildcard}," flags="g"/>
      <replaceregex pattern="$"  replace="/**/${file.wildcard}" />
   </tokenfilter>
  </filterchain>
</loadresource>

<fileset id="files" dir="/" includes="${dirs.include}" />

The work is split into two: first string processing to convert the semicolon-separated list into patterns suitable for use in a fileset includes attribute; second make a fileset from the pattern.

The loadresource task here is simply being used as a wrapper around a sequence of simple regular expression replacements. The three replacements deal with the leading root directory \, expanding the intra-string semicolons into Ant patterns and commas (which are used in includes attributes to separate entries), and adding a pattern at the end of the string.

In your case you might consider tuning this to not use the root directory in the dir attribute of the fileset.

martin clayton
  • 76,436
  • 32
  • 213
  • 198
  • on windows, `dir="/"` maps to the `C:` drive (or whatever has been configured as the main drive) and it will fail for files on another drive. Change it to `` and it will work as intended. – Tom Howard May 07 '13 at 22:01
  • I included my solution in the original question. I used your suggestion, but I used different regexes to make sure that trailing commas or windows' paths don't produce wrong fileselectors. – Pavel P May 08 '13 at 16:31
  • @TomHoward: I think it shall be ``. – Chau Chee Yang Dec 25 '14 at 21:08
2

propertyregex is from ant-contrib, which is why the example is not working for you.

Here is one way to achieve what you want.

<pathconvert property="src.dirs.includes" pathsep="/**/*.java,">
    <path path="${src.dirs}" />
</pathconvert>
<replaceregexp match="\s+" replace=" " flags="g" byline="true">
    <files id="files" includes="${src.dirs.includes}/**/*.java" />
</replaceregexp>

However spaces in any of the filenames (including their path) will stuff you up.

Tom Howard
  • 6,516
  • 35
  • 58
0

Do you simply have to go through these directories and do your compile, or must these directories be compiled together because of dependencies?

If there are no dependencies, you could try the <for/> task in Ant-Contrib. This lets you loop through a list like the one you have:

<for list="${src.dirs}"
    param="my.src.dir"
    delimiter=";">
    <sequential>
        <javac destdir="${javac.destdir}"
             srcdir="@{my.src.dir}"
             classpathref="main.classpath"/>
    </sequential>
</for>

Of course, you might have to munge things for your correct destdir. You may find the <var/> task convenient when you use the <for/> task. The <var/> task allows you to reset variable names. When you repeat the <sequential/> set of tasks, you may find you want to reset certain properties.

By the way, if you have Ant 1.8 or higher, you can use the <local/> task instead of <var/>.

David W.
  • 105,218
  • 39
  • 216
  • 337