Bash script to update text between tags in a pom file?
Since the question was tagged sed, I suppose awk
would be a valid alternative.
In this case you could process the pom file in awk
, save the result in a tmpfile and overwrite the original file with the modified version:
#!/bin/sh
# error function
error(){
echo -e >&2 "error: $@"
exit 1
}
update_rpm_release_in_pom()
{
#################
# set constants #
#################
POM_FILE="./template/iptools/pom.xml"
USAGE="usage: update_rpm_release_in_pom <build num>"
#################
# sanity checks #
#################
# argument given?
[[ $# -eq 1 ]] || \
error "wrong number of parameters\n$USAGE"
# pom file exists?
[[ -e "$POM_FILE" ]] || \
error "pom file $POM_FILE does not exist"
# pom file readable?
[[ -r "$POM_FILE" ]] || \
error "pom file $POM_FILE is not readable"
# pom file writeable?
[[ -w "$POM_FILE" ]] || \
error "pom file $POM_FILE is not writeable"
##################
# set parameters #
##################
BUILD_NUM=$1
###############################
# create temporal output file #
# and ensure its removal #
###############################
# cleanup function
cleanup(){
[[ -e "$TMP_FILE" ]] && rm -- "$TMP_FILE"
}
# ensure cleanup on exit
trap 'cleanup' EXIT
# create temporal output file or exit with error
TMP_FILE=`mktemp` || \
error "could not create temporal output file"
#############################
# process pom file with awk #
# and save modified version #
# in temporal output file #
#############################
awk \
-F "rpm.release>" \
-v OFS="rpm.release>" \
-v BUILD_NUM="$BUILD_NUM" \
'
/<properties>/{
properties=1
}
/<\/properties>/{
properties=0
}
properties&&$1~/<$/&&$2~/<\/$/{
$2=BUILD_NUM"</"
}
1
' "$POM_FILE" > "$TMP_FILE" || \
error "processing pom file $POM_FILE with awk failed"
#########################
# move modified version #
# back to original path #
#########################
mv -- "$TMP_FILE" "$POM_FILE" || \
error "could not mv temporal output file $TMP_FILE to pom file $POM_FILE"
}
# Call above function
update_rpm_release_in_pom 11
Note that this should work with all versions of awk
since there are no GNUisms in there.
There might be a way to do this in sed
and get around the tmpfile stuff by using sed
's inplace (-i
) option, but a) I am not sure how to do this in a safe way in sed
and b) I do not even know if you run a version of sed
that supports the -i
option.
In case you need further help, adjustments and/or explanations, feel free to add a comment.
Addendum:
In case you really need to do this without any script language, I modified your code and substituted my awk
code with that:
#!/bin/bash
# error function
error(){
echo -e >&2 "error: $@"
exit 1
}
update_rpm_release_in_pom()
{
#################
# set constants #
#################
POM_FILE="./template/iptools/pom.xml"
USAGE="usage: update_rpm_release_in_pom <build num>"
#################
# sanity checks #
#################
# argument given?
[[ $# -eq 1 ]] || \
error "wrong number of parameters\n$USAGE"
# pom file exists?
[[ -e "$POM_FILE" ]] || \
error "pom file $POM_FILE does not exist"
# pom file readable?
[[ -r "$POM_FILE" ]] || \
error "pom file $POM_FILE is not readable"
# pom file writeable?
[[ -w "$POM_FILE" ]] || \
error "pom file $POM_FILE is not writeable"
##################
# set parameters #
##################
BUILD_NUM=$1
###############################
# create temporal output file #
# and ensure its removal #
###############################
# cleanup function
cleanup(){
[[ -e "$TMP_FILE" ]] && rm -- "$TMP_FILE"
}
# ensure cleanup on exit
trap 'cleanup' EXIT
# create temporal output file or exit with error
TMP_FILE=`mktemp` || \
error "could not create temporal output file"
##############################
# process pom file with bash #
# and save modified version #
# in temporal output file #
##############################
BEGIN_PROPERTIES="n"
while read LINE
do
case $BEGIN_PROPERTIES in
n) # <property> tag not found yet
[[ "$LINE" == *\<properties\>* ]] && BEGIN_PROPERTIES="y"
echo "$LINE"
continue
;;
y) # <property> tag found
[[ "$LINE" == *\</properties\>* ]] && BEGIN_PROPERTIES="n"
if [[ "$LINE" == *rpm.release* ]]; then
# Update value
echo "${LINE/<rpm\.release>*<\/rpm\.release>/<rpm.release>$BUILD_NUM<\\rpm.release>}"
continue
fi
echo "$LINE"
;;
esac
done < "$POM_FILE" > "$TMP_FILE" || \
error "processing pom file $POM_FILE with bash failed"
#########################
# move modified version #
# back to original path #
#########################
mv -- "$TMP_FILE" "$POM_FILE" || \
error "could not mv temporal output file $TMP_FILE to pom file $POM_FILE"
}
# Call above function
update_rpm_release_in_pom 11
However, this is not as stable as the above solution.
For example, on my machine this removes the leading whitespace from the pom file.
I do not know whether this is due to some quoting problem or if you'd need to adjust parameters of read
or echo
.
Since I would never use such a soultion I will not further investigate on this but maybe this helps you in case you insist on a bash
-only solution.
How to variablize shell script output on maven pom.xml to use
Here is a suggested approach:
- Use the Exec Maven Plugin for launching your script or commands
- Use the Properties Maven Plugin to load the configuration
Requirements for this approach:
- The curl response you expect (or the output or your script) should have a name=value format (that is, a properties file)
- The Exec Maven Plugin execution must be declared in your POM before the Properties Maven Plugin execution and they must be attached to the same Maven phase or to two consecutive Maven phases in order to provide the desired flow
- The Properties Maven Plugin execution must be attached to an early phase of Maven (initialize or validate) in order to make the configuration available to other Maven phases and plugins
For a complete list of Maven phases, official documentation here
Update: below an example of flow, just tested and work perfectly (on Windows machine):
<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>
<groupId>com.sample</groupId>
<artifactId>generation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>retrieve-config</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>echo</executable>
<arguments>
<argument>jar.name=from-exec</argument>
<argument>></argument>
<argument>config.properties</argument>
</arguments>
<workingDirectory>${basedir}/src/main/resources/</workingDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<id>read-properties</id>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${basedir}/src/main/resources/config.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>${jar.name}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Basically, the exec plugin attached to the validate
phase will be executed at the beginning of the build, writing to a config.properties file (via the echo command) the content jar.name=from-exec
.
Then the properties plugin attached to the initialize
phase will read that config.properties file and load the properties to be used as part of the build.
Then, as an example, the jar plugin will use that property as part of its configuration (the <finalName>${jar.name}</finalName>
part).
Running mvn clean package
, you will find the from-exec.jar
file in the target folder.
Update: Above is an example of how to load dynamically from a script a set of properties which can then be injected into a Maven build (hence used as part of the POM configuration).
However, if you need to load this dynamic configuration into your application, you can even skip the second step (the Propeprties Maven Plugin) and load the properties from the config.properties
file in your code, as long as the file is part of the application classpath (like in the example above, placed under src/main/resources
).
Since the creation of the properties file happens on early Maven phase (validate
or initialize
), the test
(for your tests) and package
(for your final artefact) phases could then use it as required.
In Java, you would use the java.util.Properties
class, in Groovy you can follow the explanation here, from another question in stackoverflow.
Update a Maven project version from script
I was wondering if there is any maven plugin that would be able to modify the pom.xml directly from the command line.
The Versions Maven Plugin can do this. Check the following goal:
versions:set
can be used to set the project version from the command line, updating the details of any child modules as necessary.
maven update pom property
mvn versions:update-properties -Dproperties=[XYZ] -DincludeProperties={abc.def}
Read more here.
and here.
In short:
In versions-maven-plugin, the update-properties
goal sets properties to the latest versions of specific artifacts.
includeProperties
is a comma separated list of properties to update.
properties
are any restrictions that apply to specific properties.
How to get Maven project version to the bash command line
The Maven Help Plugin is somehow already proposing something for this:
help:evaluate
evaluates Maven expressions given by the user in an interactive mode.
Here is how you would invoke it on the command line to get the ${project.version}
:
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
-Dexpression=project.version
As noted in the comments by Seb T, to only print the version without the maven INFO logs, additionally use -q -DforceStdout
:
mvn help:evaluate -Dexpression=project.version -q -DforceStdout
How can I update a property in a Maven POM?
Is there a simple way to rewrite a Maven property entry to a specific value
Since version 2.5
we can use set-property
(documentation):
mvn versions:set-property -Dproperty=your.property -DnewVersion=arbitrary_value
As documented, the set-property
goal does not perform any 'sanity checks' on the value you specify, so it should always work, but you should use with care.
Related Topics
Possibly Undefined MACro: Ac_Prog_Libtool
Dlopen Failed: Cannot Open Shared Object File: No Such File or Directory
How to Avoid the Prompts While Using Azcopy on Linux in a Script
Getmodulehandle(Null) on Linux
Analyzing CPU Registers During Kernel Crash Dump
Ignore Case When Trying to Match File Names Using Find Command in Linux
How to Copy a File with '$' in Name in Linux
Using Xargs with Special Characters
How to Install Poppler for Python 3 in Linux
Padding Empty Field in Unix Join Operation
How to Prevent Matlab Printing False Space and Use Wrong Fonts
Extract Text Between Two Strings Repeatedly Using Sed or Awk
How to Retrieve Advertising Payload from Ibeacon/Ble
Docker Container Accessible Only via Cloudflare Cdn (Selected Ip Ranges)
How to Get Environment Variables of Remote Host