file-io archivos - Ant:¿Cómo ejecutar un comando para cada archivo en el directorio?




bat ejemplos (8)

ant-contrib es malo; escribe una tarea de hormiga personalizada.

ant-contrib es malo porque trata de convertir a la hormiga de un estilo declarativo a un estilo imperativo. Pero xml hace un lenguaje de programación de mierda.

Por el contrario, una tarea personalizada le permite escribir en un lenguaje real (Java), con un IDE real, donde puede escribir pruebas de unidad para asegurarse de que tiene el comportamiento que desea, y luego hacer una declaración limpia en su script de construcción sobre el comportamiento que quieres.

Esta diatriba solo importa si te preocupa escribir guiones de hormiga mantenibles. Si no te importa la facilidad de mantenimiento, haz lo que funcione. :)

Jtf

Quiero ejecutar un comando desde un archivo de compilación Ant, para cada archivo en un directorio.
Estoy buscando una solución independiente de la plataforma.

¿Cómo hago esto?

Claro, podría escribir un script en algún lenguaje de scripting, pero esto agregaría más dependencias al proyecto.


Haz lo que blak3r sugirió y define tus objetivos classpath como tal

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

donde lib es donde almacenas tu jar


Sé que esta publicación es realmente antigua, pero ahora que pasaron algunas versiones de tiempo y hormiga, hay una manera de hacer esto con las características básicas de la hormiga y pensé que debería compartirlo.

Se realiza mediante un macrodef recursivo que llama a tareas anidadas (incluso se pueden llamar otras macros). La única convención es usar un nombre de variable fijo (elemento aquí).

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

Las características clave necesarias donde:

No logré hacer el delimitador variabel, pero esto puede no ser un inconveniente importante.


Un acercamiento sin ant-contrib es sugerido por Tassilo Horn (el objetivo original está aquí )

Básicamente, como no hay una extensión de <java> (¿todavía?) De la misma manera que <apply> extends <exec> , él sugiere usar <apply> (que por supuesto también puede ejecutar un programa java en una línea de comando)

Aquí algunos ejemplos:

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

Respuesta corta

Utilice <foreach> con un <FileSet> anidado

Foreach requiere ant-contrib .

Ejemplo actualizado para ant-contrib reciente:

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

Esto anulará la "barra" de destino con el $ {theFile} resultante en el archivo actual.


Aquí hay una manera de hacer esto usando javascript y la tarea ant scriptdef, no necesita ant-contrib para que este código funcione, ya que scriptdef es una tarea central.

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

Puede usar la tarea ant-contrib "para" para iterar en la lista de archivos separados por cualquier delímetro, el delímetro predeterminado es ",".

A continuación se muestra el archivo de muestra que muestra esto:

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

Para resolver este problema, usaremos el Complemento de ensamblaje de Maven que creará el JAR junto con sus JAR de dependencia en un solo archivo JAR ejecutable. Solo agregue la siguiente configuración de plugin en su archivo pom.xml.

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>com.your.package.MainClass</mainClass>
                  </manifest>
               </archive>
               <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
               </descriptorRefs>
            </configuration>
            <executions>
               <execution>
                  <id>make-my-jar-with-dependencies</id>
                  <phase>package</phase>
                  <goals>
                     <goal>single</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </pluginManagement>
</build>

Después de hacer esto, no olvide ejecutar la herramienta MAVEN con este comando mvn clean compile assembly: single

http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/







file-io ant build-process build-automation