Macros para modificación POM

Sometimes Maven pom.xml files need to be patched before they are used to build packages. One could use traditional patches to maintain changes, but package maintainers should use %pom_* macros developed specially to ease this task. Using %pom_* macros not only increases readability of the spec file, but also improves maintainability of the package as there are no patches that would need to be rebased with each upstream release.

Hay dos categorías de macros:

  • POM-specific macros - used to manipulate dependencies, modules, etc. Some of them also work on ivy.xml files.

  • Generic XML manipulation macros - used to add / remove / replace XML nodes.

The macros are designed to be called from %prep section of spec files. All the macros also have their own manual page. This document provides an overview of how they are used. For the technical details, refer to their respective manpages.

Especificación de archivo

By default, a macro acts on a pom.xml file (or ivy.xml file) in the current directory. Different path can be explicitly specified via an argument (the last one, unless stated otherwise). Multiple paths can be specified as multiple arguments. If a path is a directory, it looks for a pom.xml file in that directory. For example:

# Las siguientes funciona sobre archivo pom.xml en el directorio actual
%pom_remove_parent

# Los siguiente funciona en submodule/pom.xml
%pom_remove_parent submodule

# Lo siguiente también funciona en submodule/pom.xml
%pom_remove_parent submodule/pom.xml

# Los siguiente funciona en submodule2/pom.xml y submodule2/pom.xml
%pom_remove_parent submodule1 submodule2
Modo recursivo

Most macros also support recursive mode, where the change is applied to the pom.xml and all its modules recursively. This can be used, for example, to remove a dependency from the whole project. It is activated by -r switch.

Macros de manipulación de dependencia

Retirando dependencias

Often dependencies specified in Maven pom.xml files need to be removed because of different reasons. %pom_remove_dep macro can be used to ease this task:

# Elimina la dependencia con groupId "foo" y artifactId "bar" desde pom.xml
%pom_remove_dep foo:bar

# Elimina la dependencia de todos los artefactos con groupId "foo" desde pom.xml
%pom_remove_dep foo:

# Elimina la dependencia de todos los artefactos con artifactId "bar" de pom.xml
%pom_remove_dep :bar

# Elimina la dependencia de todos los artefactos con artifactId "bar" de submodule1/pom.xml
%pom_remove_dep :bar submodule1

# Retira dependencia en todos los artefactos con artifactId "bar" desde pom.xml
# y todos sus submódulos
%pom_remove_dep -r :bar

# Retira todas las dependencias de pom.xml
%pom_remove_dep :
Añadiendo dependencias

Dependencies can also be added to pom.xml with %pom_add_dep macro. Usage is very similar to %pom_remove_dep, see $ man pom_add_dep for more information.

Cambiar dependencias

Sometimes the artifact coordinates used in upstream pom.xml do not correspond to ones used in Fedora and you need to modify them. %pom_change_dep macro will modify all dependencies matching the first argument to artifact coordinates specified by the second argument. Note this macro also works in recursive mode.

# Para todos los artefactos en pom.xml que tengan groupId 'ejemplo' cambiarlo a
# 'com.example' mientras dejando artifactId y otras partes intactas
%pom_change_dep example: com.example:

Adding / removing plugins

%pom_remove_plugin macro works exactly as %pom_remove_dep, except it removes Maven plugin invocations. Some examples:

Retirar complementos Maven de archivos pom.xml
# Inhabilita maven-jar-plugin tal que classpath no está incluido en manifests
%pom_remove_plugin :maven-jar-plugin

# Inutilizar un complemento propietario que no está empaquetado para Fedora
%pom_remove_plugin com.example.mammon:useless-proprietary-plugin submodule

Like in previous case, there is also a macro for adding plugins to pom.xml. See its manual page for more information.

Inhabilita módulos innecesarios

Sometimes some submodules of upstream project cannot be built for various reasons and there is a need to disable them. This can be achieved by using %pom_disable_module, for example:

Inhabilitando módulos de proyecto específico
# Deshabilita child-module-1, un submódulo del archivo pom.xml principal
%pom_disable_module child-module-1

# Deshabilita grandchild-module, un submódulo de child-module-2/pom.xml
%pom_disable_module grandchild-module child-module-2

Trabajar con referencias POM antecesoras

Macro %pom_remove_parent removes reference to a parent POM from Maven POM files. This can be useful when parent POM is not yet packaged (e.g. because of licensing issues) and at the same time it is not really needed for building of the project. There are also macros for adding parent POM reference (%pom_add_parent) and replacing existing reference with new one (%pom_set_parent).

Manipular referencias POM antecesoras
# Retira referencia a un antecesor POM desde ./pom.xml
%pom_remove_parent

# Retira referencia a un POM antecesor desde ./submodule/pom.xml
%pom_remove_parent submodule

# Añade referencia antecesora de POM a ./pom.xml
%pom_add_parent groupId:artifactId

# Sustituye referencia antecesora existente POM en ./pom.xml
%pom_set_parent groupId:artifactId:version

Macros para realizar modificaciones genéricas

El por encima de macros portada los casos más comunes de modificar archivos pom.xml, aun así si hay una necesidad de aplicar algunos parches menos comunes allí también son tres macros genéricas para modificar el archivo pom.xml. Estas macros genéricas también pueden ser aplicadas a otros archivos #XML, como los archivos de build.xml de Ant.

They all take a XPath 1.0 expression that selects XML nodes to be acted on (removed, replaced, etc.).

Manipular espacio de nombre XML

POM files use a specific namespace - http://maven.apache.org/POM/4.0.0. The easiest way to respect this namespace in XPath expressions is prefixing all node names with pom:. For example, pom:environment/pom:os will work because it selects nodes from pom namespace, but environment/os won’t find anything because it looks for nodes that do not belong to any XML namespace. It is needed even if the original POM file didn’t contain proper POM namespace, since it will be added automatically. Note that this requirement is due to limitation of XPath 1.0 and we cannot work it around.

Retirar nodos

%pom_xpath_remove puede ser utilizado para retirar nodos arbitrarios de XML.

# Retira extensiones desde la creación
%pom_xpath_remove "pom:build/pom:extensions" module/pom.xml
Inyectar nodos

%pom_xpath_inject macro is capable of injecting arbitrary XML code to any pom.xml file. The injected code is the last argument - optional file paths go before it (unlike most other macros). To pass a multiline snippet, quote the argument as in the following example.

# Add additional exclusion into maven-wagon dependency
%pom_xpath_inject "pom:dependency[pom:artifactId='maven-wagon']/pom:exclusions" "
<exclusion>
  <groupId>antlr</groupId>
  <artifactId>antlr</artifactId>
</exclusion>"
# The same thing, but with explicit file path
%pom_xpath_inject "pom:dependency[pom:artifactId='maven-wagon']/pom:exclusions" pom.xml "
<exclusion>
  <groupId>antlr</groupId>
  <artifactId>antlr</artifactId>
</exclusion>"
Cambiar el contenido de los nodos

%pom_xpath_set sustituye el contenido de los nodos XML arbitrarios con valores especificados (puede contener nodos XML).

# Cambia groupid de un antecesor
%pom_xpath_set "pom:parent/pom:groupId" "org.apache"
Sustitución de nodos

%pom_xpath_replace sustituye un nodo XML con código específico en XML.

# Cambia groupId de un antecesor (note la diferencia desde %pom_xpath_set)
%pom_xpath_replace "pom:parent/pom:groupId" "<groupId>org.apache</groupId>"