使用 maven 将版本号输出到文本文件

Posted

技术标签:

【中文标题】使用 maven 将版本号输出到文本文件【英文标题】:Using maven to output the version number to a text file 【发布时间】:2011-04-01 17:18:16 【问题描述】:

我想生成一个 zip 文件,该文件将使用 maven 更新应用程序。 zip 将托管在服务器上,我正在使用程序集插件生成 zip。但是我希望 maven 自动生成一个文本文件,该文件将当前版本号存储在 zip 之外。这怎么可能?

编辑: 我使用 maven 程序集插件和两个描述符成功地创建了两个自定义程序集。一个有一个目录单一目标,它只是根据过滤创建一个包含更新的 version.txt 的文件夹。然后另一个有一个目标的实际上打包了 zip 文件。这似乎很不雅,我猜它不会用整个更新的文件夹正确更新 maven repo。如果有更好的方法,请告诉我。

【问题讨论】:

【参考方案1】:

当然。在 src/main/resources 中的某处创建一个文本文件,将其命名为 version.txt(或其他)

文件内容:

$project.version

现在在你的 pom.xml 中,在 build 元素中,放置这个块:

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

每次构建后,文件(您可以在目标/类中找到)将包含当前版本。

现在,如果您想将文件自动移动到其他位置,您可能需要通过 maven-antrun-plugin 执行 ant 任务。

类似这样的:

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

【讨论】:

@SeanPatrickFloyd 你介意解释一下为什么我需要过滤=false 用于排除和过滤=true 用于包含吗?这是什么意思? @Karussell 这意味着当您不想过滤每个资源时,您需要两次单独运行,一次过滤,一次不过滤。显然,其中一个运行中包含的内容需要排除在另一个运行中 您不必通过一个完整的单独操作来移动文件。您可以指定&lt;targetPath&gt; @dingalapadum 这个配置意味着除了这个文件之外的所有内容都应该被复制而不过滤(第二个块),并且在复制时只应该过滤文本文件(第二个块)。 如果不使用ant run插件就好了。由于它使用的是 ant run 插件,因此无需资源过滤即可定义 echo 任务。【参考方案2】:

使用标准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

另见How to get package version at running Tomcat?

【讨论】:

【参考方案3】:

你指的是filtering

您需要启用对特定资源的过滤,然后使用$project.version,它将被替换为您的构建的一部分

【讨论】:

【参考方案4】:

在 Maven 3 中,使用 Sean's answer 创建您的 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

【讨论】:

我需要添加以下配置,因此这是互补的: $* 如下所示帖子:***.com/questions/5340361/… @darkstar_mx 很好的跟进,这正是我的配置所缺少的【参考方案5】:

对于 Spring Boot 应用程序,请按照上面接受的答案进行替换

$project.version

@project.version@

这里是文档https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.3-Release-Notes#maven-resources-filtering的链接

【讨论】:

【参考方案6】:

您还可以使用 Groovy 脚本来生成版本信息文件。我更喜欢这种方法,因为您不必排除程序集插件描述符中的内容。您还可以使用此方法选择性地包含仅在您从 Jenkins/Hudson 构建时可用的内容(例如检查 oug BUILD_ID 等...)。

所以你会在 pom.xml 中有一个像这样的文件生成 groovy 脚本:

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

【讨论】:

【参考方案7】:

我只是用一个蚂蚁任务来做这个。

<echo file="version.txt">$project.version</echo>

【讨论】:

这将替换整个文件。 没有进一步的上下文,问题是关于 Maven,而不是 Ant...?!? 使用@sean-patrick-floyd 的答案中的antrun-plugin 示例和这个答案对我来说非常有用。我专门写了&lt;echo file="$project.build.resources[0].directory/version.txt"&gt;$project.version&lt;/echo&gt;,它将版本文件放在资源目录中以包含在生成的 JAR 文件中。【参考方案8】:

您可以使用 maven-antrun-plugin 和 regex 表达式将版本输入到文件中。 PS:version.txt文件内容为任意字符串ex:version。

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

【讨论】:

或者只使用 echo 任务,例如:&lt;echo message="$project.version" file="resources/version.txt"/&gt;【参考方案9】:

一种可能性是使用maven-properties-plugin 将所有项目属性存储到构建的.jar。 然后您可以使用标准(虽然不太实用)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

【讨论】:

【参考方案10】:

要添加到 Sean 的答案,您可以使用资源中的 targetpath 参数将版本文件移动到 jar 中的文件夹位置。以下代码在 jar 中创建了一个名为“resources”的文件夹,并在该文件夹中找到了文本文件 (version.number)。

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

【讨论】:

【参考方案11】:

我更喜欢write-properties-file-maven-plugin,因为我不希望所有 maven-project-properties 在一个文件中:

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

【讨论】:

【参考方案12】:

在 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>
  [...]

【讨论】:

以上是关于使用 maven 将版本号输出到文本文件的主要内容,如果未能解决你的问题,请参考以下文章

maven - 从属性文件中读取版本号

将 Maven 输出发送到文件

增加文本文件中包含的版本号

易语言 错误(10044): 不能将“文本型 数组”数据转换到“通用型”数据。

如何将excel的数据输出到文本文件中并设定长

使用文本文件 C# 进行线性搜索 [重复]