-->

ant-contrib: get count result in 'resourcecoun

2019-09-06 00:53发布

问题:

To search for multiple 'searchStrings' in a fileset the following ANT seems to do the job.

  <taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
      <pathelement location="/usr/share/java/ant-contrib.jar"/>
    </classpath>
  </taskdef>

  <loadfile property="list"  srcFile="searchStrings.txt"/>
  <echo>.:${list}:.</echo>

  <target name="main">
    <for list="${list}" param="search4"  delimiter="${line.separator}">

      <sequential>

        <fileset id="existing" dir="../src">
          <patternset id="files">
            <include name="**/*.xul"/>
          </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}'"/>
      </sequential>

    </for>
  </target>

But for each individual searchString I need the number of occurrences. The echo message "Found ..." only gives the very first result and more worse, it repeats that number for all files.

Tried to add an echo inside the resourcecount block, but that fails.

How can this be modified to get a list for all searchStrings?

回答1:

ANT is not a scripting language, I would recommend embedding something like groovy

Example

This example counts the occurances of search terms, stored in the "searchStrings.txt" file, contained files stored under the "src" directory.

├── build.xml
├── searchStrings.txt
└── src
    ├── test1.xul
    ├── test2.xul
    └── test3.xul

Run as follows

$ ant

search:
   [groovy] Found hello in files : 3
   [groovy] Found world in files : 2
   [groovy] Found test in files : 1

build.xml

<project name="demo" default="search">

   <target name="bootstrap" description="Used to install the ivy task jar">
      <mkdir dir="${user.home}/.ant/lib"/>
      <get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.9/groovy-all-2.1.9.jar"/>
   </target>

   <target name="search">
      <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>

      <fileset id="existing" dir="src" includes="**/*.xul"/>

      <groovy>
         new File("searchStrings.txt").eachLine { term ->
            def files = project.references.existing.findAll{
               new File(it.toString()).text.contains(term)
            } 
            println "Found ${term} in files : ${files.size}"
         }
      </groovy>
   </target>

</project>

searchStrings.txt

hello
world
test

src/test*.xul

Dummy data files:

$ cat src/test1.xul
hello world test

$ cat src/test2.xul
hello world

$ cat src/test3.xul
hello

Update 1

To make this work with Eclipse, alter the taskdef to include the path to the downloaded "groovy-all.jar".

  <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
     <classpath>
        <fileset dir="${user.home}/.ant/lib" includes="*.jar"/>
     </classpath>
  </taskdef>

Note:

  • This solution does not need "ant-contrib". With embedded groovy you'll have more flexibility.

Update 2:

The solution can be easily enhanced to write the search results to a file:

<groovy>
  new File("searchResults.txt").withWriter { writer ->
    new File("searchStrings.txt").eachLine { term ->
      def files = project.references.existing.findAll{
        new File(it.toString()).text.contains(term)
      }
      writer.println "Found ${term} in files : ${files.size}"
    }
  }
</groovy>

Groovy is powerful.