Search code examples
windowsantwildcardfileset

Apache Ant: Resolve path with wildcards to FileSet


Given an absolute path containing wildcards, such as C:\Program Files\VC\Redist\x64\Microsoft.*.CRT\*.dll, how can this path be resolved to a FileSet?

Consider that the path is stored in property myPath, was supplied by the user, may contain spaces and could be anywhere on the filesystem. I would require something along the lines of:

<fileset>
  <include name="${myPath}" />
</fileset>

Which is of course not working, as fileset requires the dir parameter - however, I don't have a base dir I could supply. How could this be solved?

The available ant version is 1.10.5.


Solution

  • I have solved the problem by splitting the absolute path into a base path part and the part containing the wildcards using a regex. Usable macro:

    <macrodef name="resolveWildcardPath">
        <!-- resolves a wildcard path to a fileset -->
        <attribute name="path" /> <!-- input path -->
        <attribute name="filesetID" /> <!-- output fileset ID -->
        <sequential>
            <local name="normalizedPath" />
            <local name="basePath" />
            <local name="wildcardPath" />
            <pathconvert property="normalizedPath">
                <path location="@{path}" />
            </pathconvert>
            <regexp id="pathWildcardRegex" pattern="([^\*]+)\${file.separator}([^\${file.separator}]*\*.*)" />
            <propertyregex input="${normalizedPath}" select="\1" property="basePath">
                <regexp refid="pathWildcardRegex"/>
            </propertyregex>
            <propertyregex input="${normalizedPath}" select="\2" property="wildcardPath">
                <regexp refid="pathWildcardRegex"/>
            </propertyregex>
            <fileset id="@{filesetID}" dir="${basePath}" if:set="wildcardPath">
                <include name="${wildcardPath}" />
            </fileset>
            <fileset id="@{filesetID}" file="${normalizedPath}" unless:set="wildcardPath" />
        </sequential>
    </macrodef>
    

    Note that this solution additionally requires ant-contrib, and if/unless (xmlns:if="ant:if" xmlns:unless="ant:unless" as project parameters).