如何使用Ant搜索文件中的字符串(确保在源文件中找不到某些字符串)

时间:2010-11-29 08:35:05

标签: search ant build

我想用Ant搜索源文件中的字符串。 (如果在我的源文件中找到某些字符串,我希望我的构建失败。)

因此,我应该能够以递归方式搜索文件集中的某个字符串。

我已经发现我可以使用loadfile task来检查whether a string pattern is found within one file。但这似乎是有效的。只有一个文件才有意义。

另一方面,replace task将提供递归搜索和替换。我想我可以在构建之前做到这一点并用可能破坏构建的东西替换我的字符串,但我想知道是否有更清洁的解决方案?

br,Touko

3 个答案:

答案 0 :(得分:16)

您可以考虑使用fileset selectors来执行此操作。选择器允许您根据内容,大小,可编辑性等选择文件。您可以将选择器与基于名称的包含和排除或模式集组合在一起。

以下是一个例子。第二个文件集派生自第一个文件集,其中一个选择器只匹配文件内容。对于更复杂的匹配,有containsregexp selector。结果是一个文件集只包含与字符串匹配的文件。然后使用resourcecount condition的失败任务来使构建失败,除非该文件集为空。

<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>

旧答案):如果调整或重复使用文件集可能会有问题,这里是相对简单替代方案的说明。

想法是制作文件的副本, 然后替换您要搜索的字符串 在复制的文件中有一些标志值。 这将更新任何匹配文件的上次修改时间。 然后可以使用uptodate任务查找受影响的文件。 最后,除非没有文件匹配,否则您可以fail构建。

<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" />

答案 1 :(得分:1)

作为一个开始,这非常有用,但我有一个字符串列表,应该在文件集中检查

我目前的代码是:

<property name="search4" value="XYZ"/>

<fileset id="existing" dir="../src">
    <patternset id="files">
    <include name="content/**/*.txt"/>
    </patternset>
</fileset>

<resourcecount property="count">
    <fileset id="matches" dir="../src">
    <patternset refid="files" />
    <contains text="${search4}" />
    </fileset>
</resourcecount>
<echo message="Found '${search4}' in files : '${count}'"/>

效果很好,但是如何扩展它以便从列表中读取$ {search4}。实际上,可以从包含每个搜索项的文件中读取列表在单独的行上。

答案 2 :(得分:0)

@ martinclayton答案的第一部分稍微简洁一点:

<property name="log.dir" value="logs" />
<property name="fail.string" value=" FAILED " />

<fileset id="build.failures" dir="${log.dir}" includes="*.log">
    <contains text="${fail.string}"/>
</fileset>
<fail status="1" message="One or more failures detected">
    <condition>
        <resourcecount when="greater" count="0" refid="build.failures" />
    </condition>
</fail>