Использование maven для вывода номера версии в текстовый файл

Я хочу создать zip-файл, который обновит приложение с помощью maven. ZIP-архив будет размещен на сервере, и я использую плагин сборки для его создания. Однако я хотел бы, чтобы maven автоматически создавал текстовый файл, в котором хранится номер текущей версии вне zip. Как это возможно?

РЕДАКТИРОВАТЬ: Я успешно сделал это, используя плагин сборки maven и два дескриптора для создания двух пользовательских сборок. У одного есть единственная цель каталога, и он просто создает папку с обновленным файлом version.txt на основе фильтрации. Затем другой с единственной целью фактически упаковывает zip-файл. Это кажется очень неэлегантным, и я предполагаю, что он не будет должным образом обновлять репозиторий maven со всей обновленной папкой. Если есть лучший способ сделать это, пожалуйста, дайте мне знать.


person sanz    schedule 20.08.2010    source источник


Ответы (12)


Конечно. Создайте текстовый файл где-нибудь в src / main / resources, назовите его version.txt (или как угодно)

Содержание файла:

${project.version}

теперь в вашем pom.xml внутри элемента сборки поместите этот блок:

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

после каждой сборки файл (который вы можете найти в target / classes) будет содержать текущую версию.

Теперь, если вы хотите автоматически переместить файл в другое место, вам, вероятно, потребуется выполнить задачу ant через maven-antrun-plugin.

Что-то вроде этого:

  <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>
person Sean Patrick Floyd    schedule 20.08.2010
comment
По какой-то причине первый блок, похоже, не помещает версию в target / classes. Второй блок кода, кажется, работает, если я создам файл version.txt. - person sanz; 20.08.2010
comment
Ваш проект - это веб-приложение? Тогда фильтрация ресурсов работает немного иначе. Я обновлю свой ответ через несколько часов (сначала ужин) :-) - person Sean Patrick Floyd; 20.08.2010
comment
Нет, но проект, над которым я работаю, - это просто модуль maven с родительским проектом, который содержит все приложение. - person sanz; 20.08.2010
comment
@SeanPatrickFloyd, не могли бы вы объяснить, почему мне нужно filtering = false для исключений и filtering = true для include? Что это значит? - person Karussell; 08.11.2012
comment
@Karussell означает, что если вы не хотите фильтровать каждый ресурс, вам нужны два отдельных прогона, один с фильтрацией, другой без. и то, что включено в один из прогонов, должно быть исключено из другого, очевидно - person Sean Patrick Floyd; 08.11.2012
comment
вам не нужно перемещать файл с помощью целой отдельной операции. Вы можете указать <targetPath>. - person Adam; 06.12.2017
comment
@AbhishekSaini Я отредактировал вопрос - когда он будет одобрен, вы увидите targetPath. Он находится внутри элемента resource. - person Adam; 11.01.2018
comment
Почему вы помещаете туда файл version.txt в два раза больше ресурса? Думаю получу фильтрацию и включу. Но почему без фильтрации и исключения части? - person dingalapadum; 17.07.2018
comment
@dingalapadum эта конфигурация означает, что все, кроме этого файла, должно быть скопировано без фильтрации (второй блок), и только текстовый файл должен быть отфильтрован при копировании (второй блок). - person Sean Patrick Floyd; 17.07.2018
comment
Кроме того, вы можете следовать документации и хранить все отфильтрованные ресурсы в src/main/resources-filtered, затем вы включаете <filtering> только для этого каталога, чтобы избежать _3 _ / _ 4_ дублирования. - person otterrisk; 02.11.2018
comment
Каким-то образом я вижу другую проблему: в targes / classes есть version.txt, но {project.version} не заменяется фактической версией из файла pom. - person Pawan; 11.01.2019
comment
Было бы неплохо, если бы он не использовал плагин ant run. Поскольку он использует плагин ant run, достаточно определить эхо-задачу без фильтрации ресурсов. - person JJ Roman; 19.05.2020

Используйте стандартный META-INF\MANIFEST.MF (тогда вы можете использовать код Java getClass().getPackage().getImplementationVersion() для получения версии)

Для .war используйте эту конфигурацию:

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

Это добавит манифест во время сборки, или вы можете вызвать mvn war:manifest

См. Также Как получить версию пакета при запуске Tomcat?

person Paul Verest    schedule 11.03.2013

То, что вы имеете в виду, называется фильтрацией.

Вам нужно включить фильтрацию для определенного ресурса, а затем использовать ${project.version}, который будет заменен как часть вашей сборки

person Jon Freedman    schedule 20.08.2010

в Maven 3 используйте ответ Шона, чтобы создать свой version.txt файл (мой здесь показан вместе с датой сборки и активным профилем ):

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

добавление свойства profileID в каждый из профилей, например:

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

Используйте ресурсы копирования Maven, чтобы скопировать файл в более удобный каталог, например ${basedir} или ${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>

вывод выглядит так:

1.2.3-profileName
yymmdd_hhmm
person ekangas    schedule 30.06.2015
comment
Мне нужно было добавить следующую конфигурацию, поэтому она является дополнительной: ‹configuration› ‹delimiters› ‹delimiter› $ {*} ‹/delimiter› ‹/delimiters› ‹/configuration› Как указано в следующем сообщении: stackoverflow.com/questions/5340361/ - person darkstar_mx; 03.03.2018

Вы также можете использовать сценарий Groovy для создания файла информации о версии. Мне этот метод нравится больше, потому что вам не нужно исключать что-то в дескрипторе сборки-плагина. Вы также можете использовать этот метод для необязательного включения вещей, доступных только в том случае, если вы строите из Jenkins / Hudson (например, проверьте oug BUILD_ID и т. Д.).

Итак, у вас будет отличный скрипт для создания файлов в pom.xml, например:

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

И затем ваш плагин сборки в pom.xml, который будет выглядеть так:

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

И, наконец, ваш дескриптор сборки dist-all.xml будет выглядеть так:

<?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>
person DeusAquilus    schedule 12.08.2011

Для приложения Spring Boot следуйте принятому ответу сверху, но заменив

${project.version}

с участием

@project.version@

Вот ссылка на документацию https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.3-Release-Notes#maven-resources-filtering

person Vuong Ly    schedule 15.11.2018

Я только что сделал это с помощью муравьиной задачи.

<echo file="version.txt">${project.version}</echo>
person Dr.Octoboz    schedule 10.07.2017
comment
Это заменит полный файл. - person Jerad Rutnam; 08.03.2018
comment
Без дальнейшего контекста вопрос был о Maven, а не о Ant ...?!? - person Betlista; 03.07.2019
comment
Используя пример antrun-plugin из ответа @ sean-patrick-floyd, и этот ответ отлично сработал для меня. Я специально написал <echo file="${project.build.resources[0].directory}/version.txt">${project.version}</echo>, который помещает файл версии в каталог ресурсов для включения в итоговый файл JAR. - person Guss; 17.11.2019

вы можете использовать maven-antrun-plugin и выражения регулярного выражения для ввода версии в файл. PS: содержимое файла version.txt - это любая строка, например: версия.

 ...
    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
         <version>1.4</version>
         <executions>
          <execution>
            <phase>process-resources</phase>
            <goals>
             <goal>run</goal>
            </goals>
            <configuration>
               <target>
                 <replaceregexp file="resources/version.txt" match=".*" replace="${project.version}" byline="true" />
              </target>
            </configuration>
          </execution>
        </executions>
      </plugin>
   </plugins>
person chashikajw    schedule 13.03.2020
comment
или просто используйте эхо-задачу, например: <echo message="${project.version}" file="resources/version.txt"/> - person JJ Roman; 19.05.2020

Одна из возможностей - сохранить все свойства проекта во встроенном .jar с помощью maven-properties-plugin.
Затем вы можете прочитать эти свойства, используя стандартный (хотя и не слишком практичный) 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>

Будьте осторожны с этим подходом, так как это может привести к утечке свойств, которые не должны быть опубликованы, в том числе из settings.xml.

person Ondra Žižka    schedule 23.04.2017

Чтобы добавить к ответу Шона, вы можете переместить файл версии в папку в банке, используя параметр targetpath в ресурсе. Следующий код создает в банке папку с именем «ресурсы», и в этой папке находится текстовый файл (номер версии).

<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>
person learmo    schedule 04.07.2017

Я предпочитаю write-properties-file-maven-plugin, потому что Я не хочу, чтобы все свойства проекта maven были в одном файле:

  <plugin>
    <groupId>com.internetitem</groupId>
    <artifactId>write-properties-file-maven-plugin</artifactId>
    <version>1.0.1</version>
    <executions>
      <execution>
        <id>one</id>
        <phase>compile</phase>
        <goals>
            <goal>write-properties-file</goal>
        </goals>
        <configuration>
          <filename>test.properties</filename>
          <properties>
            <property>
              <name>one</name>
              <value>1</value>
            </property>
            <property>
              <name>artifactId</name>
              <value>My Artifact ID is ${project.artifactId}</value>
            </property>
          </properties>
        </configuration>
      </execution>
    </executions>
  </plugin>
person Gambotic    schedule 12.11.2018

Добавление ниже плагина в pom.xml сработало для меня. Это только комбинация приведенных выше ответов: -

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <configuration>
              <target><echo file="version.txt">${project.version}</echo> </target>
            </configuration>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
person AlphaBetaGamma    schedule 28.12.2020