简体   繁体   English

物理上更改Maven pom.xml <properties>值

[英]Changing Maven pom.xml <properties> values physically

I'm building a deployment pipeline for a couple of projects that depend on each other. 我正在为几个相互依赖的项目构建一个部署管道。 Each build produces a new release build with a unique version number, which is deployed to a Maven repository. 每个构建都会生成一个具有唯一版本号的新版本,该版本号部署到Maven存储库。 The downstream projects in the pipeline are then triggered with that new version as a dependency and built in like manner. 然后,使用该新版本作为依赖项触发管道中的下游项目,并以类似方式构建。

What I need is to change a property value in the pom.xml (or all poms in a multi module project) before building the project. 我需要的是在构建项目之前更改pom.xml(或多模块项目中的所有poms)中的属性值。 For example in the following code the "0.1.200" would be changed to "0.1.345" (or whatever the latest build number is). 例如,在下面的代码中,“0.1.200”将更改为“0.1.345”(或者无论最新的内部版本号是什么)。 Using system properties is not an option, because the updated pom will be deployed in a Maven repository, so the change must be persistent. 使用系统属性不是一种选择,因为更新的pom将部署在Maven存储库中,因此更改必须是持久的。

<properties>
    <foo.version>0.1.200</foo.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>foo</artifactId>
        <version>${foo.version}</version>
    </dependency>
</dependencies>

Is there some Maven plugin for doing this with one command line instruction? 是否有一些Maven插件使用一个命令行指令执行此操作? Else I will need to write a short script (eg in Ruby) which parses and changes all the pom.xml files in the project. 否则我需要编写一个简短的脚本(例如在Ruby中),它解析并更改项目中的所有pom.xml文件。

Yes, there exists a maven-replacer-plugin which is capable of this. 是的,有一个maven-replacer-plugin就可以了。

But if you're using some CI tool (which apparently you are) you could as well just stick with a custom script for this purpose. 但是如果你正在使用一些CI工具(显然你是),你也可以为此目的坚持使用自定义脚本。

The available Maven plugins didn't fit my purpose, so I ended up writing the following Ruby script that does exactly what I need: 可用的Maven插件不适合我的目的,所以我最终编写了以下Ruby脚本,它完全符合我的需要:

#!/usr/bin/env ruby
require 'rexml/document'

def change_property(pom, key, value)
  property = pom.elements["/project/properties/#{key}"]
  if property != nil
    puts "    #{key}: #{property.text} -> #{value}"
    property.text = value
  end
end

unless ARGV.length == 2
  puts "Usage: #{$0} KEY VALUE"
  exit 1
end
KEY = ARGV.shift
VALUE = ARGV.shift

Dir.glob("**/pom.xml") { |pom_path|
  puts pom_path

  pom = REXML::Document.new(File.new(pom_path))
  pom.context[:attribute_quote] = :quote
  change_property(pom, KEY, VALUE)

  File.open(pom_path, 'wb') { |file|
    pom.write(file)
  }
  puts
}

Did you try this one? 你试过这个吗?

Version Maven Plugin 版本Maven插件

I had a similar requirement. 我有类似的要求。 Besides updating the property under the /project/properties node, I also need to update the property under /project/profiles/properties node, so I modify Esko's script to support updating both cases. 除了更新/ project / properties节点下的属性外,我还需要更新/ project / profiles / properties节点下的属性,因此我修改了Esko的脚本以支持更新这两种情况。 Meanwhile, it also supports updating multiple properties in one command so you don't have to run it multiple time if you need to update multiple properties in the same pom.xml. 同时,它还支持在一个命令中更新多个属性,因此如果需要在同一个pom.xml中更新多个属性,则不必多次运行它。

#!/usr/bin/env ruby
require 'rexml/document'

def change_profile_property(pom, profile_id, key, value)
  property = pom.elements["/project/profiles/profile[id='#{profile_id}']/properties/#{key}"]
  if property != nil
    puts "    #{profile_id}-#{key}: #{property.text} -> #{value}"
    property.text = value
  end
end

def change_property(pom, key, value)
  property = pom.elements["/project/properties/#{key}"]
  if property != nil
    puts "    #{key}: #{property.text} -> #{value}"
    property.text = value
  end
end

if ARGV.length == 0
  puts "Usage: #{$0} KEY=VALUE [-profile <profile id>] KEY=VALUE"
  exit 1
end

# parse the command line argument to get the key/value
global_properties = Array.new
profile_properties= Array.new

profile = nil
loop { case ARGV[0]
  when '-profile' then  ARGV.shift; profile=ARGV.shift
  when nil then break
  else 
    kv_str = ARGV.shift
    if profile == nil
      global_properties.push(kv_str)
    else
      profile_properties.push(kv_str)
    end
  end; 
}

Dir.glob("**/pom.xml") { |pom_path|
  puts pom_path

  pom = REXML::Document.new(File.new(pom_path))
  pom.context[:attribute_quote] = :quote

  # updating the global properties
  if global_properties.length != 0
    for kv in global_properties
      kv_array = kv.split('=')
        if kv_array.length == 2
          change_property(pom, kv_array[0], kv_array[1])
        end
    end
  end

  # updating the properties in profile
  if profile_properties.length != 0
    for kv in profile_properties
      kv_array = kv.split('=')
      if kv_array.length == 2
        if profile != nil
          change_profile_property(pom, profile, kv_array[0], kv_array[1])
        end
    end
    end
  end

  File.open(pom_path, 'wb') { |file|
    pom.write(file)
  }
  puts
}

Flatten Maven Plugin can be used to update the variables. Flatten Maven插件可用于更新变量。 Let me explain with an example. 让我举个例子来解释一下。

<groupId>groupid</groupId>
<artifactId>artifactid</artifactId>
<version>${ServiceVersion}</version>
<packaging>pom</packaging>

<properties>
    <foo.version>${ServiceVersion}</foo.version>
</properties>

In pom.xml, I'm using "ServiceVersion" to get the value during the build. 在pom.xml中,我使用“ServiceVersion”来获取构建期间的值。 The foo.version variable will be updated too during the build. 在构建期间,foo.version变量也将更新。 Now, the foo.version variable can be used in any of the dependencies. 现在,foo.version变量可以用在任何依赖项中。

<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>foo</artifactId>
        <version>${foo.version}</version>
    </dependency>
</dependencies>

So, finally include the Flatten Maven Plugin in the pom.xml 所以,最后在pom.xml中包含Flatten Maven插件

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
    <updatePomFile>true</updatePomFile>
</configuration>
 <executions>
    <execution>
        <id>flatten</id>
        <phase>process-resources</phase>
        <goals>
            <goal>flatten</goal>
        </goals>
    </execution>
    <execution>
      <id>flatten.clean</id>
      <phase>clean</phase>
      <goals>
        <goal>clean</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Now provide the service version. 现在提供服务版本。

clean install -DServiceVersion=0.1.345

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM