Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

search

build

ant

I'd like to search for a string within my source files with Ant. (I'd like my build to fail in case certain string is found within my source files).

So, I should be able to recursively search for a certain string within a file set.

I already found that I can use loadfile task to check whether a string pattern is found within one file. But that seems to be working & sensible only with a single file.

On the other hand, replace task would provide recursively search-and-replace. I guess I could do that before build and replace my string with something that would break the build but I wonder if there is some cleaner solution?

br, Touko

like image 546
Touko Avatar asked Nov 29 '10 08:11

Touko


1 Answers

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" />
like image 164
martin clayton Avatar answered Nov 03 '22 10:11

martin clayton