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.
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.
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.
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.
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
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>
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>
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
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:
- http://ant.apache.org/manual/ifunless.html wprowadzony w ant 1.9.1 (napisy do ant conditional if wewnątrz makrodef )
- substraty, wiele dzięki Jak wyciągnąć substraty w mrówce
- Element inline macrodef.
Nie udało mi się stworzyć wariatora ogranicznika, ale może to nie być poważny minus.
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>
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
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