2010-08-20 20 views
42

Quiero generar un archivo zip que actualice una aplicación con maven. El zip se alojará en un servidor y estoy usando el plugin de ensamblaje para generar el zip. Sin embargo, me gustaría que maven genere automáticamente un archivo de texto que almacene el número de versión actual fuera del zip. es posible?Usando maven para dar salida al número de versión a un archivo de texto

EDIT: Lo logré utilizando el plugin Assembly de maven y dos descriptores para crear dos ensamblajes personalizados. Uno tiene un objetivo de directorio único y simplemente crea una carpeta con el archivo version.txt actualizado basado en el filtrado. Luego, otro con un solo objetivo realmente empaqueta el archivo zip. Esto parece ser muy poco elegante y supongo que no actualizará adecuadamente el repositorio maven con toda la carpeta actualizada. Si hay una mejor manera de hacerlo, por favor avíseme.

Respuesta

73

Claro. Crear un archivo de texto en algún lugar de src/main/resources, llamarlo version.txt (o lo que sea)

contenido

del archivo:

${project.version} 

ahora en su pom.xml, dentro del elemento de construcción, poner este bloque:

<build> 
    <resources> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>true</filtering> 
     <includes> 
     <include>**/version.txt</include> 
     </includes> 
    </resource> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>false</filtering> 
     <excludes> 
     <exclude>**/version.txt</exclude> 
     </excludes> 
    </resource> 
    ... 
    </resources> 
</build> 

Después de cada compilación, el archivo (que puede encontrar en el destino/clases) contendrá la versión actual.

Ahora, si desea mover el archivo a otro lugar de forma automática, es probable que deba ejecutar una tarea ant a través del maven-antrun-plugin.

Algo como esto:

<build> 
    ... 
    <plugins> 
     <plugin> 
     <artifactId>maven-antrun-plugin</artifactId> 
     <version>1.4</version> 
     <executions> 
      <execution> 
      <phase>process-resources</phase> 
      <configuration> 
       <tasks> 
       <copy file="${project.build.outputDirectory}/version.txt" 
        toFile="..." overwrite="true" /> 
       </tasks> 
      </configuration> 
      <goals> 
       <goal>run</goal> 
      </goals> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
</build> 
+0

Por alguna razón, el primer bloque no parece poner la versión en el destino/clases. El segundo bloque de código parece funcionar si creo el version.txt. – sanz

+0

¿Su proyecto es una aplicación web? Entonces el filtrado de recursos funciona de manera un poco diferente. Actualizaré mi respuesta en unas pocas horas (la cena primero) :-) –

+0

No, pero el proyecto en el que estoy trabajando es solo un módulo maven con un proyecto principal que contiene toda la aplicación. – sanz

10

Lo que se está refiriendo a la que se llama filtering

necesita habilitar el filtrado en un recurso en particular, y luego usar ${project.version} que será sustituido como parte de su construcción

7

También podría usar un guión maravilloso para producir un archivo de información de la versión. Me gusta más este método porque no tiene que excluir cosas en el descriptor del plugin de ensamblaje. También puede usar este método para incluir opcionalmente cosas solo disponibles si está compilando desde Jenkins/Hudson (por ejemplo, revise BUILD_ID, etc.).

Así que tendría que generar una secuencia de comandos de archivos maravilloso en pom.xml así:

<plugin> 
    <groupId>org.codehaus.mojo.groovy</groupId> 
    <artifactId>groovy-maven-plugin</artifactId> 
    <version>1.0-beta-3</version> 
    <executions> 
     <execution> 
     <phase>test</phase> 
     <goals> 
      <goal>execute</goal> 
     </goals> 
     <configuration> 
      <source> 
     <![CDATA[ 
     println("==== Creating version.txt ===="); 
     File mainDir = new File("src/main"); 
     if(mainDir.exists() && !mainDir.isDirectory()) { 
      println("Main dir does not exist, wont create version.txt!"); 
      return; 
     } 
     File confDir = new File("src/main/conf"); 
     if(confDir.exists() && !confDir.isDirectory()) { 
      println("Conf dir is not a directory, wont create version.txt!"); 
      return; 
     } 
     if(!confDir.exists()) { 
      confDir.mkdir(); 
     } 
     File versionFile = new File("src/main/conf/version.txt"); 
     if(versionFile.exists() && versionFile.isDirectory()) { 
      println("Version file exists and is directory! Wont overwrite"); 
      return; 
     } 
     if(versionFile.exists() && !versionFile.isDirectory()) { 
      println("Version file already exists, overwriting!"); 
     } 
     println("Creating Version File"); 
     BufferedWriter writer = new BufferedWriter(new FileWriter(versionFile)); 

     writer.write("groupId = ${project.groupId}"); 
     writer.newLine(); 
     writer.write("artifactId = ${project.artifactId}"); 
     writer.newLine(); 
     writer.write("version = ${project.version}"); 
     writer.newLine(); 
     writer.write("timestamp = ${maven.build.timestamp}"); 

     String buildTag = ""; 
     String buildNumber = ""; 
     String buildId = ""; 
     try { 
      buildTag = "${BUILD_TAG}"; 
      buildNumber = "${BUILD_NUMBER}"; 
      buildId = "${BUILD_ID}"; 

      writer.write("BUILD_TAG = " + buildTag + "\n"); 
      writer.write("BUILD_NUMBER = " + buildNumber + "\n"); 
      writer.write("BUILD_ID = " + buildId + "\n"); 

     } catch (Exception e) { 
      println("============= Could not find BUILD_TAG probably this is not a Jenkins/Hudson build ==========="); 
     } 

     writer.close(); 
     ]]> 
      </source> 
     </configuration> 
     </execution> 
    </executions> 
    </plugin> 

Y entonces su montaje plug-in plug-in en pom.xml que se vería así:

<plugin> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <version>2.2.1</version> 
    <!-- Produce the all-dependencies-included jar for java classloaders --> 
    <executions> 
     <execution> 
     <id>all</id> 
     <phase>package</phase> 
     <goals> 
      <goal>single</goal> 
     </goals> 
     <configuration> 
      <finalName>${project.artifactId}</finalName> 
      <descriptors> 
      <descriptor>dist-all.xml</descriptor> 
      </descriptors> 
     </configuration> 
     </execution> 
    </executions> 
    </plugin> 
Y, por último

su montaje descriptor dist-all.xml se vería así:

<?xml version="1.0" encoding="UTF-8"?> 
<assembly> 
    <id>all</id> 
    <formats> 
    <format>dir</format> 
    <format>zip</format> 
    </formats> 
    <includeBaseDirectory>false</includeBaseDirectory> 
    <fileSets> 
    <fileSet> 
     <directory>target</directory> 
     <outputDirectory></outputDirectory> 
     <includes> 
     <include>*.jar</include> 
     </includes> 
    </fileSet> 
    <fileSet> 
     <directory>src/main/conf</directory> 
     <outputDirectory></outputDirectory> 
     <includes> 
     <include>**</include> 
     </includes> 
    </fileSet> 
    </fileSets> 
</assembly> 
11

uso sta ndard META-INF\MANIFEST.MF (Luego puede usar el código Java getClass().getPackage().getImplementationVersion() para obtener la versión)

For.utilización guerra esta configuración:

<plugin> 
    <artifactId>maven-war-plugin</artifactId> 
    <version>2.1</version> 
    <configuration> 
     <archive>     
      <manifest> 
       <addDefaultImplementationEntries>true</addDefaultImplementationEntries> 
       <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> 
      </manifest> 
     </archive> 
    </configuration> 
</plugin> 

que añadirá manifiesta durante la construcción, o puede llamar mvn war:manifest

Véase también How to get package version at running Tomcat?

6

en Maven 3, Uso Sean's answer para crear el archivo version.txt, (el mío es se muestra aquí, junto con la fecha de compilación y el perfil activo):

${project.version}-${profileID} 
${buildDate} 

sumando la propiedad profileID a cada uno de los perfiles, por ejemplo:

<properties> 
    <profileID>profileName</profileID> 
</properties> 

uso de Maven copia de recursos para copiar el archivo a un más fácil de alcanzar directorio como ${basedir} o ${basedir}/target:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-resources-plugin</artifactId> 
    <version>3.0.2</version> 
    <executions> 
     <execution> 
      <id>copy-resources</id> 
      <phase>validate</phase> 
      <goals> 
       <goal>copy-resources</goal> 
      </goals> 
      <configuration> 
       <outputDirectory>${basedir}</outputDirectory> 
       <resources> 
        <resource> 
         <directory>${basedir}/target/.../[version.txt dir]/version.txt</directory> 
         <includes> 
          <include>version.txt</include> 
         </includes> 
         <filtering>true</filtering> 
        </resource> 
       </resources> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

de salida es el siguiente:

1.2.3-profileName 
yymmdd_hhmm 
+0

que tenía que agregar la siguiente configuración, por lo tanto esta es complementaria: $ {*} Como se indica en los siguientes mensaje: https://stackoverflow.com/questions/5340361/replace-task-in-maven-antrun-plugin? Answertab = active # tab-top –

0

Una posibilidad es almacenar todas las propiedades del proyecto en el .jar construido usando maven-properties-plugin.
Luego puede leer estas propiedades usando el estándar (aunque no demasiado práctico) Java Properties API.

 <!-- Build properties to a file --> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>properties-maven-plugin</artifactId> 
      <version>1.0.0</version> 
      <executions> 
       <execution> 
        <phase>generate-resources</phase> 
        <goals> <goal>write-project-properties</goal> </goals> 
        <configuration> 
         <outputFile> ${project.build.outputDirectory}/build.properties </outputFile> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 

tener cuidado con este enfoque, ya que puede perder propiedades que no se supone que terminan publicada, también de settings.xml.

0

Para agregar a la respuesta de Sean, puede mover el archivo de versión a una ubicación de carpeta dentro del contenedor utilizando el parámetro targetpath dentro del recurso. El siguiente código crea una carpeta llamada 'resources' dentro del jar y el archivo de texto (version.number) se encuentra en esa carpeta.

<resource> 
    <directory>resources</directory> 
    <targetPath>resources</targetPath> 
    <filtering>true</filtering> 
    <includes> 
     <include>version.number</include> 
    </includes> 
</resource> 
<resource> 
    <directory>resources</directory> 
    <filtering>false</filtering> 
    <excludes> 
     <exclude>version.number</exclude> 
    </excludes> 
</resource> 
0

Acabo de hacer esto con una tarea de hormiga.

<echo file="version.txt">${project.version}</echo> 
+0

Esto reemplazará el archivo completo. –

Cuestiones relacionadas