Pad Number With Zeros in Maven - maven

Is there a way to have maven pad a numeric value (ex: build number) within a POM? I've been googling the topic and haven't come up with anything yet.
My use case is as follows. The maven build process is provided a build number via Jenkins which needs to be included as part of the name of the WAR that is generated. So if I provide it 12 as the build number, then I want the WAR file name to be myWar##000012.war. The ##000012 part of the name is the version identifier used by Tomcat.

The simplest solution may be to embed a scripting language in your build. For example, with Groovy, if you have a buildNumber property:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals><goal>execute</goal></goals>
<configuration>
<source>
project.properties['nameSuffix'] = "##" + String.format("%06d", project.properties['buildNumber'].toLong());
</source>
</configuration>
</execution>
</executions>
</plugin>
Afterwards the nameSuffix property is available to define the final name.
Alternatively, as suggested in In Maven, how can I dynamically build a property value at runtime?, use build-helper:regex-property to transform the string.

Have you tried using the maven release plugin?

Based upon #Joe suggestion I looked into the build-helper-maven-plugin and was able to come up with the following which does what I need. I wasn't able to identify how to do it all in one step, so I'm doing it in 2. The first step pads the value on the left with zeros. The second step trims the numeric value so that it is only 7 digits long. Please note that ${build.env.version} is passed in as a parameter to the maven build process and that I have defaulted it to 0 in the POM file for when it isn't passed. If you don't provide a default value then the build fails even though failOnError on set to false.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>stage1--padNumber</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${build.env.version}</value>
<regex>^([\d]{0,})$</regex>
<replacement>000000$1</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
<execution>
<id>stage2--leftTrimToXcharacters</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${build.env.version.padded}</value>
<regex>^([\d]*)([\d]{7})$</regex>
<replacement>$2</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
</executions>
</plugin>

Based upon #jwmajors81 suggestion, I needed to pad the major version for a specific reason...
As we were already using the build-helper-maven-plugin, it is easy enough to get the major version by using the parse-version goal of the build helper. (we only needed 3 chars):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
<execution>
<id>stage1--padNumber</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${parsedVersion.majorVersion}</value>
<regex>^([\d]{0,})$</regex>
<replacement>00$1</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
<execution>
<id>stage2--leftTrimToXcharacters</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${build.env.version.padded}</value>
<regex>^([\d]*)([\d]{3})$</regex>
<replacement>$2</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
</executions>
</plugin>

Yet, in that particular case, if you also need to generate a buildNumber, buildnumber-maven-plugin may be the most straight solution:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<format>{0, number,000000}</format>
<items>
<item>buildNumber</item>
</items>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>myWar##${buildNumber}</finalName>

Related

Get the semantic versioning components within a Maven POM [duplicate]

Is it possible to get the major version (<Major>.<Minor>.<Patch>) of the project.version?
For example if my version is 1.3.4, I'd like to get 1 to later use it in a configuration of the same pom.xml
Something like:
<configuration>
<name>project_name.${project.version:major}</name>
</configuration>
If not, what are the alternatives?
Found it. The build-helper-maven-plugin has the ability to parse-out the components of the version.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>initialize</phase>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>[version] ${project.version}</echo>
<echo>[majorVersion] ${parsedVersion.majorVersion}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
This works on Maven 3.3.9:
${project.artifact.selectedVersion.majorVersion}
Versions don't necessarily come in the structure you describe.
Maven has conventions for trailing numbers, but you don't have to use them.
If you have a convention that you like that you want to disassemble, you can write your own maven plugin that sets several properties to the several pieces as you define them.

How to execute a maven plugin twice with different property

I would like to build from a maven pom running two sequential executions of the same plugin, in the same phase differing only by a single property, which will result in two different archives being created. Since the configuration is rather complicated, I'd rather NOT copy it just to change one value, which would create a maintenance nightmare. If it was somehow possible to define such a property in the <executions> section of the plugin config, I could avoid this headache.
Question: Is this possible and if so how?
Update: Two answers have mentioned using multiple executions and one of them mentions that you can have separate configurations in each execution. But given that the majority of my configuration is constant between the two executions, can I have one configuration on the plugin level and also have configuration sections in each execution for the parts that are different?
Given the simple Maven Source Plugin configuration (as an example) you have a shared configuration across all of its executions (outside the executions element) and then a custom configuration per each execution, for the same phase, as requested by your question:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<configuration>
<includePom>true</includePom>
</configuration>
<executions>
<execution>
<id>test-id1</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<finalName>aaa</finalName>
</configuration>
</execution>
<execution>
<id>test-id2</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<finalName>bbb</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The configuration entry <includePom>true</includePom> will in this case be merged with the custom configurations of each execution and as such centralize the common configuration as plugin generic configuration.
For more details on the different level of configurations, you can check official Maven documentation, here, in particular the example "Configuring compile to run twice". Further details are also available on the official POM documentation, here, Plugins section.
You need to create a different execution (still bound to the same phase)
To avoid duplication of the config, you can put the <configuration> outside the <execution> element and then in the 2 executions, you only define the property that is different.
Taken from the maven docs:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-myquery-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>execution1</id>
<phase>test</phase>
<configuration>
<url>http://www.foo.com/query</url>
<timeout>10</timeout>
<options>
<option>one</option>
<option>two</option>
<option>three</option>
</options>
</configuration>
<goals>
<goal>query</goal>
</goals>
</execution>
<execution>
<id>execution2</id>
<configuration>
<url>http://www.bar.com/query</url>
<timeout>15</timeout>
<options>
<option>four</option>
<option>five</option>
<option>six</option>
</options>
</configuration>
<goals>
<goal>query</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
You create two <execution> elements within the <plugin> declaration. Each <execution> element can have it's own <configuration> section.
I wanted to create a jar and a put in in a zip file with other config files
This worked for me
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>build-jar-with_dep1</id>
<phase>package</phase>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${buildversion}</finalName>
<finalName>finalname</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<goals>
<goal>assembly</goal>
</goals>
</execution>
<execution>
<id>build_zip1</id>
<phase>package</phase>
<configuration>
<descriptor>src/assembly/bin.xml</descriptor>
<finalName>${buildversion}</finalName>
<finalName>finalname</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

change version number dynamically when build with maven

Instead of changing the version manually, is there any way to update it with the build number?
<version>1.2.132-SNAPSHOT</version>
In the above code, I need the build number instead of 132.
I've used the following code to generate the build number.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<format>{0,number}.{1,number}.{2,number}</format>
<items>
<item>buildNumber0</item>
<item>buildNumber1</item>
<item>buildNumber2</item>
</items>
</configuration>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
And I need the build number just before -SNAPSHOT. Any ideas ?
I think you can just append your buildNumber variables to your version property:
<version>1.2.${buildNumber0}${buildNumber1}${buildNumber2}-SNAPSHOT</version>

Property autocapitalization in maven

I have a maven project that requires a property to be set at the command line(-Dmy.property=val).
What I need to do is to convert that string into all caps since that property is
used for string replacement in a number of files through the maven-resources-plugin.
What's the simplest way to do this?
The groovy plugin could be used. The following configures it to run at the beginning of the Maven build process:
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
import org.apache.commons.lang.StringUtils
project.properties["my.property"] = StringUtils.upperCase(project.properties["my.property"])
</source>
</configuration>
</execution>
</executions>
</plugin>
With following code, MY_PROPERTIES equals to uppercased value of my.properties:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>properties-to-uppercase</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>MY_PROPERTY</name>
<regex>.*</regex>
<value>${my.property}</value>
<replacement>$0</replacement>
<failIfNoMatch>false</failIfNoMatch>
<toUpperCase>true</toUpperCase>
</configuration>
</execution>
</executions>
</plugin>

How to get the semver Major part of a Maven version?

Is it possible to get the major version (<Major>.<Minor>.<Patch>) of the project.version?
For example if my version is 1.3.4, I'd like to get 1 to later use it in a configuration of the same pom.xml
Something like:
<configuration>
<name>project_name.${project.version:major}</name>
</configuration>
If not, what are the alternatives?
Found it. The build-helper-maven-plugin has the ability to parse-out the components of the version.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>initialize</phase>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>[version] ${project.version}</echo>
<echo>[majorVersion] ${parsedVersion.majorVersion}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
This works on Maven 3.3.9:
${project.artifact.selectedVersion.majorVersion}
Versions don't necessarily come in the structure you describe.
Maven has conventions for trailing numbers, but you don't have to use them.
If you have a convention that you like that you want to disassemble, you can write your own maven plugin that sets several properties to the several pieces as you define them.

Resources