3

I have an ant task that uses an apply task to run a script on a group of files.

I have a directory structure resultant of something like this: mkdir -p a/{b,c,d,e}/f

Normally (if I pass no arguments), I would like ant to run on all fs. That is, if I called ant mytask, it should process: a/b/f, a/c/f, a/d/f, a/e/f. This already works using apply and patternsets.

However, when I pass it an optional argument called foo, it should only call the script on a/foo/f.

So if I called ant mytask -foo b, it should process a/b/f only, and not the others.

I have read this SO post, which explains ways of passing arguments, and I have looked at the ant documentation regarding properties, and conditionals. But I am still unable to piece them together in a way that works.

Also, I do not want to use one of the suggestions from the SO above which called for arguments like this:

<arg value="${arg0}"/>
<arg value="${arg1}"/>

I want to be able to call it as ant mytask -foo valueoffoo for any arbitrary foo.

Thanks.


I tried martin clayton's suggestion below and have code like:

<target name="mytask">
  <property name="foo" value="*" />
  <apply executable="perl">
    <arg value="somescript"/>
    <dirset id="them" dir="a">
      <include name="${foo}/*/f" />
    </dirset>
  </apply>
</target>

The above does what I want.

Note 1: In my actual code I use a patternset instead of dirset but it should work the same.

Note 2: In my original question I said the directory structure was a/{b,c,d,e}/f. It is in fact a bit more complicated, hence the * in the include above. I omitted that the first time around because it did not seem relevant.

Community
  • 1
  • 1
yarian
  • 5,922
  • 3
  • 34
  • 48
  • I'm not sure I'm following this - your example Ant command line mentions a target `mytask` and an arbitrary `foo`, but your sample buildfile is for a target called foo? Do you need to pass in an arbitrary sub-path perhaps? Or is it just one arbitrary directory level? – martin clayton Jul 25 '11 at 17:58
  • @martin clayton : Oh sorry, you're right that is confusing. I fixed my question. – yarian Jul 26 '11 at 13:38
  • So, by default, the include pattern is `*/*/f` - which parts of that do you want to be able to override from the command line? The `${foo}` part, or the middle `*` - or both perhaps? – martin clayton Jul 26 '11 at 14:31
  • Well, presumably if I learn to do the ${foo} part I could adapt it if I were to later need the middle as well. For now though it's just the ${foo}. I am guessing if I needed both the property could be set with value="*/*" or I could have two properties set to *. (If this sentence doesn't make sense ignore it, not too relevant). – yarian Jul 26 '11 at 15:29
  • So what happens when you run something like `ant -Dfoo=d` with the above buildfile? – martin clayton Jul 26 '11 at 15:43
  • Aha, so it works now. Not sure what was wrong earlier but it looks good. Thanks a lot! – yarian Jul 27 '11 at 13:17

1 Answers1

2

You can do this - albeit with a slightly different command-line syntax - using a property 'override'.

First, in the buildfile, construct your fileset or dirset from a property foo, something like this:

<property name="foo" value="*" />
<dirset id="them" dir="a">
    <include name="${foo}/f" />
</dirset>

This will give you your default behaviour - processing all subdirectories of a that themselves have a subdirectory f.

Now, if you run Ant like this:

ant -Dfoo=d

Only directory a/d/f will be processed.

This works because Ant properties are not mutable - well, not normally anyway - so the command-line definition of foo prevents the one within the buildfile from being used.

martin clayton
  • 76,436
  • 32
  • 213
  • 198