Ant: jak wykonać polecenie dla każdego pliku w katalogu?

Chcę wykonać polecenie z ant buildfile, dla każdego pliku w katalogu.
Szukam rozwiązania niezależnego od platformy.

Jak to zrobić?

jasne, mógłbym napisać skrypt w jakimś języku skryptowym, ale to dodałoby kolejne zależności do projektu.

Author: Tuxdude, 2009-09-23

8 answers

Krótka Odpowiedź

Użyj <foreach> z zagnieżdżonym <FileSet>

Foreach wymaga ant-contrib .

Zaktualizowany przykład dla ostatniego ant-contrib:

<target name="foo">
  <foreach target="bar" param="theFile">
    <fileset dir="${server.src}" casesensitive="yes">
      <include name="**/*.java"/>
      <exclude name="**/*Test*"/>
    </fileset>
  </foreach>
</target>

<target name="bar">
  <echo message="${theFile}"/>
</target>

Spowoduje to zablokowanie docelowego "paska" z ${theFile}, co spowoduje utworzenie bieżącego pliku.

 61
Author: blak3r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-04 13:37:01

Użyj Zadanie .

Wykonuje polecenie raz dla każdego pliku. Określ pliki za pomocą zestawów plików lub dowolnego innego zasobu. jest wbudowany; nie jest wymagana dodatkowa zależność; nie jest wymagana niestandardowa implementacja zadań.

Możliwe jest również uruchomienie polecenia tylko raz, dołączając wszystkie pliki jako argumenty za jednym zamachem. Użyj atrybutu parallel, aby zmienić zachowanie.

Przepraszam za spóźnienie o rok.

 88
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-26 09:47:25

Podejście Bez ant-contrib jest sugerowane przez Tassilo Horn (oryginalny cel jest tutaj)

Zasadniczo, ponieważ nie ma rozszerzenia (jeszcze?) w ten sam sposób że extends , sugeruje użycie (które oczywiście może również uruchamiać program java w wierszu poleceń)

Oto kilka przykładów:

  <apply executable="java"> 
    <arg value="-cp"/> 
    <arg pathref="classpath"/> 
    <arg value="-f"/> 
    <srcfile/> 
    <arg line="-o ${output.dir}"/> 

    <fileset dir="${input.dir}" includes="*.txt"/> 
  </apply> 
 27
Author: Jmini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-04 00:38:39

Oto sposób, aby to zrobić używając javascript i zadania Ant scriptdef, nie potrzebujesz ant-contrib, aby ten kod działał, ponieważ scriptdef jest podstawowym zadaniem ant.

<scriptdef name="bzip2-files" language="javascript">
<element name="fileset" type="fileset"/>
<![CDATA[
  importClass(java.io.File);
  filesets = elements.get("fileset");

  for (i = 0; i < filesets.size(); ++i) {
    fileset = filesets.get(i);
    scanner = fileset.getDirectoryScanner(project);
    scanner.scan();
    files = scanner.getIncludedFiles();
    for( j=0; j < files.length; j++) {

        var basedir  = fileset.getDir(project);
        var filename = files[j];
        var src = new File(basedir, filename);
        var dest= new File(basedir, filename + ".bz2");

        bzip2 = self.project.createTask("bzip2");        
        bzip2.setSrc( src);
        bzip2.setDestfile(dest ); 
        bzip2.execute();
    }
  }
]]>
</scriptdef>

<bzip2-files>
    <fileset id="test" dir="upstream/classpath/jars/development">
            <include name="**/*.jar" />
    </fileset>
</bzip2-files>
 18
Author: ams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-15 06:48:58

Ant-contrib jest zły; napisz niestandardowe zadanie ant.

Ant-contrib jest zły, ponieważ próbuje przekształcić ant ze stylu deklaratywnego w styl imperatywny. Ale xml to gówniany język programowania.

Dla kontrastu niestandardowe zadanie ant pozwala na pisanie w prawdziwym języku (Java), z prawdziwym IDE, gdzie możesz pisać testy jednostkowe, aby upewnić się, że masz pożądane zachowanie, a następnie dokonać czystej deklaracji w skrypcie budowania o pożądanym zachowaniu.

Tylko ten rant ma znaczenie, jeśli zależy ci na pisaniu skryptów ant. Jeśli nie dbasz o konserwację za wszelką cenę, rób wszystko, co działa. :)

Jtf

 16
Author: Jeffrey Fredrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-25 15:56:35

Wiem, że ten post jest naprawdę stary, ale teraz, gdy minęło trochę czasu i wersje ant, istnieje sposób, aby to zrobić z podstawowymi funkcjami ant i pomyślałem, że powinienem się nim podzielić.

Odbywa się to za pomocą rekurencyjnego makrodefa, który wywołuje zagnieżdżone zadania (mogą być wywoływane nawet inne makra). Jedyną konwencją jest użycie stałej nazwy zmiennej (element tutaj).

<project name="iteration-test" default="execute" xmlns="antlib:org.apache.tools.ant" xmlns:if="ant:if" xmlns:unless="ant:unless">

    <macrodef name="iterate">
        <attribute name="list" />
        <element name="call" implicit="yes" />
        <sequential>
            <local name="element" />
            <local name="tail" />
            <local name="hasMoreElements" />
            <!-- unless to not get a error on empty lists -->
            <loadresource property="element" unless:blank="@{list}" >
                <concat>@{list}</concat>
                <filterchain>
                    <replaceregex pattern="([^;]*).*" replace="\1" />
                </filterchain>
            </loadresource>
            <!-- call the tasks that handle the element -->
            <call />

            <!-- recursion -->
            <condition property="hasMoreElements">
                <contains string="@{list}" substring=";" />
            </condition>

            <loadresource property="tail" if:true="${hasMoreElements}">
                <concat>@{list}</concat>
                <filterchain>
                    <replaceregex pattern="[^;]*;(.*)" replace="\1" />
                </filterchain>
            </loadresource>

            <iterate list="${tail}" if:true="${hasMoreElements}">
                <call />
            </iterate>
        </sequential>
    </macrodef>

    <target name="execute">
        <fileset id="artifacts.fs" dir="build/lib">
            <include name="*.jar" />
            <include name="*.war" />
        </fileset>

        <pathconvert refid="artifacts.fs" property="artifacts.str" />

        <echo message="$${artifacts.str}: ${artifacts.str}" />
        <!-- unless is required for empty lists to not call the enclosed tasks -->
        <iterate list="${artifacts.str}" unless:blank="${artifacts.str}">
            <echo message="I see:" />
            <echo message="${element}" />
        </iterate>
        <!-- local variable is now empty -->
        <echo message="${element}" />
    </target>
</project>

Kluczowe cechy potrzebne gdzie:

Nie udało mi się stworzyć wariatora ogranicznika, ale może to nie być poważny minus.

 7
Author: dag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:20

Możesz użyć zadania ant-contrib" for "do iteracji na liście plików oddzielonych dowolnym delimetrem, domyślnym delimetrem jest",".

Poniżej znajduje się przykładowy plik, który to pokazuje:

<project name="modify-files" default="main" basedir=".">
    <taskdef resource="net/sf/antcontrib/antlib.xml"/>
    <target name="main">
        <for list="FileA,FileB,FileC,FileD,FileE" param="file">
          <sequential>
            <echo>Updating file: @{file}</echo>
            <!-- Do something with file here -->
          </sequential>
        </for>                         
    </target>
</project>
 0
Author: Hemant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-07 20:18:11

Zrób to, co zasugerował blak3r i zdefiniuj swoje cele classpath w ten sposób

<taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
        <fileset dir="lib">
          <include name="**/*.jar"/>
        </fileset>
    </classpath>        
</taskdef>

Gdzie przechowujesz swój słoik

 0
Author: bungee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-09 17:59:59