I'm banging my head against a brick wall playing with ant filesets/ regexpmapper to try and simply rename a directory (in the middle of a path)...
The situation is really simple:
component/DB/
that I'm copying to DB/api/src/main/distribution/component
.api
(or "API" or "Api"). This "api" directory contains additional sql and will be copied wholesale into the target DB/api/component
(so creating DB/api/src/main/distribution/component/api
).Sounds simple and I've been playing with filesets and regexpmapper
(or mapper type=regexp
) to achieve this. However, I've had mixed results... notably that it doesn't work as soon as I put a '/' in (or '\\' or '/' or ${file.separator}
, even if using regexpmapper.handledirsep=yes
).
Here is obfuscated source path structure (from find
):
component/DB/
component/DB/API
component/DB/API/file1.sql
component/DB/API/file2.sql
component/DB/xyz.sql
component/DB/Install_API.sql
component/DB/excludes1/...
My basic copy is as below:
<copy todir="${my.db.api.dir}/src/main/distribution/component" verbose="true">
<fileset dir="${component.src.dir}/DB">
<exclude name="exclude1"/>
<exclude name="exclude1/**/*"/>
</fileset>
<regexpmapper handledirsep="yes"
from="(.*)/API(.*)" to="\1/api\2"/>
<!--mapper type="regexp" from="(.*)/API(.*)" to="\1/api\2"/-->
</copy>
I've left plain '/' in for clarity. You can see the basic premise is to spot "API", grab the surrounding text and replay it with "api" instead. If I omit the '/' in the from
then this does actually work but as soon as I put the '/' (or it's friends) in, the directory is not copied at all. Note that I want the preceding '/' as I only want to rename that dir, not the Install_API.sql file contained within it.
There are a lot of examples on-line but no-one seems to have had this issue as the supposedly working examples all seem to use plain '/', '\' or claim to be handled by the handledirset
attribute.
ant 1.8.4 on RH6.3
Many thanks.
Your fileset's base directory is the DB
dir which means that the paths your mapper will be mapping are of the form
API/file1.sql
Install_API.sql
excludes1/...
relative to that directory. Thus there is no slash in front of the API
directory name and your from
pattern never matches. But there's a deeper problem, which is that a regexpmapper completely ignores any file names that do not match the from
pattern. This is not what you want, as you need to change API
to api
but leave non-API file names unchanged. So rather than a regexpmapper
you need a filtermapper
with a replaceregex
filter:
<copy todir="${my.db.api.dir}/src/main/distribution/component" verbose="true">
<fileset dir="${component.src.dir}/DB">
<exclude name="exclude1"/>
<exclude name="exclude1/**/*"/>
</fileset>
<filtermapper>
<!-- look for either just "API" with no trailer, or API followed by
a slash, in any combination of case -->
<replaceregex pattern="^API(?=${file.separator}|$$)" replace="api"
flags="i"/><!-- case-insensitive search, finds API, Api, ... -->
</filtermapper>
</copy>