如何在Maven原型中嵌入原型项目版本?

sam*_*ert 17 java maven maven-archetype

我正在创建一个Maven原型,它生成一个项目框架,其中包含对原型所源自的项目的依赖.

例如,原始项目看起来像:

origin/archetype/... archetype for generating project 
      /core/... core services 
      /extra/... extra services 
Run Code Online (Sandbox Code Playgroud)

并且原型将生成一个包含POM的项目,其中包含依赖关系,如下所示:

<dependencies> 
  <dependency> 
    <groupId>com.foo</groupId> 
    <artifactId>origin-core</artifactId> 
    <version>SOMEVERSION</code> 
  </dependency> 
</dependencies> 
Run Code Online (Sandbox Code Playgroud)

我希望SOMEVERSION在构建原型并安装到存储库时成为原始项目的版本.

因此,如果原始项目是版本1.0-SNAPSHOT并且是mvn installed,那么我希望原型生成依赖 origin-core 1.0-SNAPSHOT.当原始项目发布并自动碰到1.0版时,我希望原型生成依赖 origin-core 1.0.

基本上我想${archetypeVersion}在原型POM中使用Velocity变量,但这似乎不可能.

有没有其他方法可以完成我在这里尝试做的事情?

sam*_*ert 36

几天前我在Maven邮件列表上询问了上述问题并得到了风滚草.幸运的是,我最终自己想出来了.这是至少一种理智的方式来实现这一目标:

src/main/resources/archetype-resources/pom.xml在构建原型时,在文件上使用Maven过滤替换当前项目版本.

这是如何完成的:

修改你的archetype/pom.xml文件以启用对archetype-resources/pom.xml文件的过滤,而不是其他任何东西(因为你的原型文件自然会${variable}遍布整个地方,你不希望在构建时替换它们,你希望它们在原型时被替换被建造).

<resources>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
      <include>archetype-resources/pom.xml</include>
    </includes>
  </resource>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <excludes>
      <exclude>archetype-resources/pom.xml</exclude>
    </excludes>
  </resource>
</resources>
Run Code Online (Sandbox Code Playgroud)

启用转义时使用的转义字符,以便您可以转义原型pom中需要保持原样的所有变量,以便在原型生成时替换它们:

<pluginManagement>
  <plugins>
    ...
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>
      <version>2.5</version>
      <configuration>
        <escapeString>\</escapeString>
      </configuration>
    </plugin>
  </plugins>
</pluginManagement>
Run Code Online (Sandbox Code Playgroud)

(注意上面显示的<resources><pluginManagement>元素应该放在<build>POM 的元素内.)

使用${project.version}在你的原型POM,在那里你要插入你的原型项目的版本,并逃避了应保持取代的,直到原型生成时间的其他变量:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  <modelVersion>4.0.0</modelVersion>

  <groupId>\${groupId}</groupId>
  <artifactId>\${artifactId}</artifactId>
  <version>\${version}</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>com.foo</groupId>
      <artifactId>origin-core</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

</project>
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案。然而,这意味着您必须转义所有原始速度样式变量。即:对于速度 =&gt; `\${groupId}`; 对于 Maven 过滤 =&gt; `${project.version}`。如果您喜欢相反的情况,也是可以的。例如:对于速度 =&gt; `${groupId}`; 对于 Maven 过滤 =&gt; `@project.version@`。为此,您可以在 pom.xml &gt; 插件 &gt; 插件 &gt; maven-resources-plugin &gt; 配置中使用:分隔符。例如只有``&lt;delimiters&gt; &lt;delimiter&gt;@*@&lt;/delimiter&gt; &lt;/delimiters&gt;`` (2认同)

Phi*_*der 14

接受答案的另一种解决方案是过滤原型的描述符/元数据文件中的默认属性

这样做是这样的:

maven过滤仅过滤此文件:

<resources>
<resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
        <include>META-INF/maven/archetype-metadata.xml</include>
    </includes>
</resource>
<resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <excludes>
        <exclude>META-INF/maven/archetype-metadata.xml</exclude>
    </excludes>
</resource>
</resources>
Run Code Online (Sandbox Code Playgroud)

原型元数据文件:

<archetype-descriptor ...>
    <requiredProperties>
        <requiredProperty key="projectVersion">
            <defaultValue>${project.version}</defaultValue>
         </requiredProperty>
    </requiredProperties>

    ...
</archetype-descriptor>
Run Code Online (Sandbox Code Playgroud)

并且原型的POM与之前的类似,只是它将使用projectVersion必需的属性值作为项目版本:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  <modelVersion>4.0.0</modelVersion>

  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>com.foo</groupId>
      <artifactId>origin-core</artifactId>
      <version>${projectVersion}</version>
    </dependency>
  </dependencies>

</project>
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是避免了必须转义原型的POM中的所有属性值以及随之而来的资源插件配置.就个人而言,我发现所有这些都非常丑陋且容易出错.

它确实意味着在生成原型时要求用户确认或更改项目版本.根据情况,我想这可能被视为好事或坏事.