2013-03-02 8 views
6

Sto costruendo una pipeline di distribuzione per un paio di progetti che dipendono l'uno dall'altro. Ogni build produce una nuova versione di rilascio con un numero di versione univoco, che viene distribuito in un repository Maven. I progetti downstream nella pipeline vengono quindi attivati ​​con tale nuova versione come dipendenza e costruiti allo stesso modo.Modifica dei valori Maven pom.xml <properties> fisicamente

Quello che mi serve è modificare un valore di proprietà in pom.xml (o tutti i poms in un progetto multi-modulo) prima di costruire il progetto. Ad esempio nel seguente codice lo "0.1.200" verrebbe modificato in "0.1.345" (o qualunque sia l'ultimo numero di build). L'utilizzo delle proprietà di sistema non è un'opzione, poiché il pom aggiornato verrà distribuito in un repository Maven, quindi la modifica deve essere persistente.

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

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

C'è qualche plugin di Maven per fare questo con una sola istruzione di riga di comando? Altrimenti dovrò scrivere un breve script (ad esempio in Ruby) che analizzi e cambi tutti i file pom.xml nel progetto.

risposta

1

Hai provato questo?

Version Maven Plugin

+2

Questo plug-in ha operazioni per l'aggiornamento automatico delle dipendenze alle versioni più recenti, ma non ho notato un modo per aggiornare una singola proprietà ad un valore specificato. –

+2

Il [versions-maven-plugin] (http://mojo.codehaus.org/versions-maven-plugin/examples/update-properties.html) è in grado di gestire tali proprietà. Dai un'occhiata ai documenti. – khmarbaise

+2

Il problema con le versioni: update-properties è che tenta automaticamente di rilevare qual è l'ultima versione. In una pipeline di distribuzione che non è buona, perché potrebbe accidentalmente causare a Maven di trovare una versione troppo vecchia o nuova. Per evitare build irripetibili, richiedo esplicitamente quale versione utilizzare. –

3

Sì, esiste un maven-replacer-plugin, che è capace di questo.

Ma se si utilizza uno strumento CI (che a quanto pare si) si potrebbe anche solo attenersi a uno script personalizzato per questo scopo.

2

I plugin Maven disponibili non si adattavano al mio scopo, così ho finito per scrivere il seguente script di Ruby che fa esattamente quello che mi serve:

#!/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 
} 
1

ho avuto un requisito analogo. Oltre ad aggiornare la proprietà sotto il nodo/project/properties, devo anche aggiornare la proprietà sotto/project/profiles/properties node, quindi modifico lo script di Esko per supportare l'aggiornamento di entrambi i casi. Nel frattempo, supporta anche l'aggiornamento di più proprietà in un unico comando in modo da non doverlo eseguire più volte se è necessario aggiornare più proprietà nello stesso 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 
} 
0

Flatten Maven Plugin può essere utilizzato per aggiornare le variabili. Lasciatemi spiegare con un esempio.

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

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

In pom.xml, sto usando "ServiceVersion" per ottenere il valore durante la compilazione. La variabile foo.version verrà aggiornata anche durante la compilazione. Ora, la variabile foo.version può essere utilizzata in qualsiasi dipendenza.

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

Così, finalmente includono il Maven Plugin Flatten nel 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> 

Ora fornire la versione del service.

clean install -DServiceVersion=0.1.345 
Problemi correlati