Home > Software design >  Replace a dependency version in pom.xml programmatically?
Replace a dependency version in pom.xml programmatically?

Time:02-09

Assuming I have a pom.xml containing a parent dependency like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>some-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
</project>

Is there a way I can replace the 1.0.0-SNAPSHOT version programmatically, maybe via a script?

My use case:

  • I have lots of pom.xml files that I need to change the parent version of
  • I'm using git-xargs to make changes across multiple repos, so I can apply a bash script to each pom.xml to change it.

For example, I can do the following, but this will update all occurrences of 1.0.0-SNAPSHOT in the pom.xml, and I want to limit it to just the some-parent artifact that has a version 1.0.0-SNAPSHOT:

git-xargs \
  --branch-name test-branch \
  --github-org <your-github-org> \
  --commit-message "Update pom.xml" \
  sed -i 's/1.0.0-SNAPSHOT/2.0.1/g' pom.xml

As per the git-xargs docs, I can use any type of script to process the pom.xml, bash, python, ruby etc: https://github.com/gruntwork-io/git-xargs#how-to-supply-commands-or-scripts-to-run

UPDATE: The answer below mentions using xmlstarlet, however, I am running into this issue now because my poms contain xmlns="http://maven.apache.org/POM/4.0.0":

http://xmlstar.sourceforge.net/doc/UG/ch05s01.html

XMLStarlet does not select anything

CodePudding user response:

With :

While you can use --if and --else for xmlstarlet sel (see https://stackoverflow.com/a/35671038/2703456 for example), I don't think you can use them for xmlstarlet ed. I hardly ever use xmlstarlet, so I'm not entirely sure.
That means you'll have to do it in Bash...

$ if [[ $(xmlstarlet sel -t -v 'parent/version' pom.xml) == "1.0.0-SNAPSHOT" ]]
  then xmlstarlet ed -O -u 'parent/version' -v 2.0.1 pom.xml
  fi
<parent>
  <groupId>com.example</groupId>
  <artifactId>some-parent</artifactId>
  <version>2.0.1</version>
</parent>

With :

$ xidel -s pom.xml -e '
  if (parent/version = "1.0.0-SNAPSHOT")
  then x:replace-nodes(parent/version/text(),"2.0.1")
  else ()
' --output-node-format=xml
<parent>
    <groupId>com.example</groupId>
    <artifactId>some-parent</artifactId>
    <version>2.0.1</version>
</parent>

If you want the output to include an XML declaration, for xmlstarlet remove the -O option and for xidel use --output-format=xml instead.

CodePudding user response:

This works for a maven pom.xml:

if [[ $(xmlstarlet sel -N my=http://maven.apache.org/POM/4.0.0 -t -v '//my:project/my:parent/my:artifactId' pom.xml) == "some-parent" && $(xmlstarlet sel -N my=http://maven.apache.org/POM/4.0.0 -t -v '//my:project/my:parent/my:version' pom.xml) == "1.0.0-SNAPSHOT" ]]; then xmlstarlet edit -L -N my=http://maven.apache.org/POM/4.0.0 --update '//my:project/my:parent/my:version' --value '2.0.6' pom.xml; fi
  •  Tags:  
  • Related