Физическое изменение значений Maven pom.xml <properties>

Я строю конвейер развертывания для пары проектов, которые зависят друг от друга. Каждая сборка создает новую версию выпуска с уникальным номером версии, которая развертывается в репозитории Maven. Затем последующие проекты в конвейере запускаются с этой новой версией в качестве зависимости и строятся аналогичным образом.

Что мне нужно, это изменить значение свойства в pom.xml (или всех poms в многомодульном проекте) перед сборкой проекта. Например, в следующем коде "0.1.200" будет изменен на "0.1.345" (или любой другой номер сборки). Использование системных свойств не вариант, потому что обновленный 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>

Есть ли какой-нибудь плагин Maven для этого с одной командой командной строки? В противном случае мне нужно написать короткий скрипт (например, на Ruby), который анализирует и изменяет все файлы pom.xml в проекте.

5 ответов

Да, существует maven-replacer-plugin который способен на это.

Но если вы используете какой-либо инструмент CI (которым вы, очевидно, являетесь), вы можете просто использовать для этой цели собственный скрипт.

Доступные плагины 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
}

У меня было похожее требование. Помимо обновления свойства в узле /project/properties, мне также необходимо обновить свойство в узле /project/profile / properties, поэтому я изменяю скрипт Esko для поддержки обновления обоих случаев. Между тем, он также поддерживает обновление нескольких свойств в одной команде, поэтому вам не нужно запускать его несколько раз, если вам нужно обновить несколько свойств в одном файле 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
}

Вы пробовали это?

Версия Maven Plugin

Flatten Maven Plugin может быть использован для обновления переменных. Позвольте мне объяснить на примере.

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

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

В pom.xml я использую "ServiceVersion", чтобы получить значение во время сборки. Переменная foo.version также будет обновляться во время сборки. Теперь переменная foo.version может использоваться в любой из зависимостей.

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

Итак, наконец, включите плагин Flatten Maven в pom.xml

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

Теперь предоставьте сервисную версию.

clean install -DServiceVersion=0.1.345
Другие вопросы по тегам