How to search for a string in files with Ant (make sure certain string isn’t found in source files)

You might consider using fileset selectors to do this. Selectors allow you to choose files based on content, size, editability and so on. You can combine selectors with name-based includes and excludes, or patternsets.

Below is an example. The second fileset is derived from the first, with a selector that simply matches on file content. For more sophisticated matching there is the containsregexp selector. The result is a fileset containing only files matching the string. A fail task with a resourcecount condition is then used to fail the build, unless that fileset is empty.

<property name="src.dir" value="src" />
<property name="search.string" value="BAD" />

<fileset id="existing" dir="${src.dir}">
    <patternset id="files">
        <!-- includes/excludes for your source here -->
    </patternset>
</fileset>

<fileset id="matches" dir="${src.dir}">
    <patternset refid="files" />
    <contains text="${search.string}" />
</fileset>

<fail message="Found '${search.string}' in one or more files in '${src.dir}'">
    <condition>
        <resourcecount when="greater" count="0" refid="matches" />
    </condition>
</fail>

(Old answer): If adjusting or reusing filesets might be problematic, here’s an illustration of a relatively simple alternative.

The idea is to make a copy of the files,
then replace the string you wish to search for
with some flag value in the copied files.
This will update the last modified time on any matching file.
The uptodate task can then be used to look for affected files.
Finally, unless no files matched, you can fail the build.

<property name="src.dir" value="src" />
<property name="work.dir" value="work" />
<property name="search.string" value="BAD" />

<delete dir="${work.dir}" />
<mkdir dir="${work.dir}" />
<fileset dir="${src.dir}" id="src.files">
    <include name="*.txt" />
</fileset>
<copy todir="${work.dir}" preservelastmodified="true">
    <fileset refid="src.files" />
</copy>
<fileset dir="${work.dir}" id="work.files">
    <include name="*.txt" />
</fileset>
<replaceregexp match="${search.string}"
               replace="FOUND_${search.string}">
    <fileset refid="work.files" />
</replaceregexp>
<uptodate property="files.clean">
    <srcfiles refid="work.files" />
    <regexpmapper from="(.*)" to="${basedir}/${src.dir}/\1" />
</uptodate>
<fail message="Found '${search.string}' in one or more files in dir '${src.dir}'"
      unless="files.clean" />

Leave a Comment