he trabajado a cabo una solución que crea un archivo JAR que contiene los scripts de construcción reutilizables en un directorio, por ejemplo com/example/ant/sharedbuild, que puede ser importado en Ant 1.8:
<project>
<import>
<javaresource name="com/example/ant/sharedbuild/java.xml">
<classpath location="../../../../target/ant-shared-build.jar" />
</javaresource>
</import>
</project>
En mi caso, esto define todos los objetivos "públicos" para que el proyecto realice una compilación basada en Java.
La sintaxis es un poco prolija, especialmente a medida que agrego más y más archivos de inclusión (por ejemplo, para agregar la capacidad de crear un archivo OSGi). Al agregar un antlib.xml que contiene una combinación de un macrodef y scriptdef al archivo jar (en el mismo directorio que los scripts compilados), el archivo de compilación ahora puede verse así (y ahora también crea un paquete OSGi jar):
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<taskdef uri="antlib:com.example.ant.sharedbuild"
classpath="../../../../target/ant-shared-build.jar" />
<build:build using="java, jar, bundle" />
</project>
por desgracia, no puedo compartir el código en el macrodef o scriptdef, pero en realidad no es difícil: un poco de javascript para analizar el uso de atributos y lazo sobre cada uno, derivar un nombre de archivo de la misma, e importar
Hago referencia al archivo jar en una ubicación fija (relativa a mi proyecto) en mi disco duro. Pienso que podemos hacerlo mejor. Idealmente, me gustaría obtener un archivo jar (¡versionado!) Desde una ubicación central. Puesto que ya estamos usando Ivy (con un repositorio de HTTP) podemos publicar el archivo jar allí (de nuevo, con una versión) y recogerla directamente desde allí:
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<property name="ant.shared.build.jar.file"
location="${user.home}/ant/ant-shared-build-1.5.3.jar" />
<get src="http://repo.example.com/.../ant-shared-build-1.5.3.jar"
dest="${ant.shared.build.jar.file}"
skipexisting="true" />
<taskdef uri="antlib:com.example.ant.sharedbuild"
classpath="${ant.shared.build.jar.file}" />
<build:build using="java, jar, bundle" />
</project>
Hay algunos problemas con esto:
- Se vuelve detallado de nuevo.
- La verbosidad se repite para cada build.xml.
- Hay una gran repetición repetitiva, especialmente el número de versión.
Para mitigar estos problemas, en cada directorio que contiene un build.xml también tengo un bootstrap.xml (el nombre en realidad no importa). Cada construcción.xml continuación incluye este archivo:
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<include file="bootstrap.xml" />
<build:build using="java, jar, bundle" />
</project>
Cada bootstrap.xml, como mínimo, incluye que es bootstrap.xml de los padres:
<project>
<include file="../bootstrap.xml" />
</project>
El bootstrap.xml de nivel superior (la raíz), luego hace el trabajo de conseguir el archivo jar y la creación de las tareas personalizadas, como el anterior:
<project>
<property name="ant.shared.build.version"
value="1.5.3" />
<property name="ant.shared.build.jar.filename"
value="ant-shared-build-${ant.shared.build.version}.jar" />
<property name="ant.shared.build.jar.file"
location="${user.home}/ant/${ant.shared.build.jar.filename}" />
<get src="http://repo.example.com/.../${ant.shared.build.jar.filename}"
dest="${ant.shared.build.jar.file}"
skipexisting="true" />
<taskdef uri="antlib:com.example.ant.sharedbuild"
classpath="${ant.shared.build.jar.file}" />
</project>
Aunque no directamente relacionado con la cuestión, en realidad estoy reelaboración del macrodef y scriptdef en una tarea personalizada hormiga, porque quiero ser capaz de soportar una sintaxis que tiene este aspecto:
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<include file="bootstrap.xml" />
<build:build>
<using>
<java />
<bundle>
<manifest>
Import-Package: *,org.joda.time;version="[1.6.0,1.6.0]"
Bundle-Activator: com.example.time.impl.Activator
</manifest>
</bundle>
</using>
</build:build>
</project>
Debo señalar que sólo la creación de una acumulación redistribuible no significa que va a ser útil. Todavía necesita dedicar el tiempo y el esfuerzo para crear una implementación cohesiva, modular y consistente en línea con un diseño de características similares. Esto es más importante ya que necesita compartir scripts en proyectos, equipos, fronteras organizacionales, etc.
En conclusión, al crear un archivo jar con un número de versión que se puede distribuir independientemente de la ubicación de un archivo específico o una herramienta SCM podemos obtener compilaciones reales pero reproducibles.
¡Muchas gracias! Estaba buscando en la tarea incorrecta. No es de extrañar que no pudiera encontrarlo. Algunos enlaces a ejemplos también serían de gran ayuda: siéntete libre si tienes algunos buenos. – nrobey
Esta es una mala idea si quieres compilaciones repetibles. –
@Dominic Mitchell - Buen punto. Si common_directive.xml no es estático, sería mejor administrar esa dependencia un poco mejor. –