Jason S
Jason S

Reputation: 189746

Getting maven to execute a program and store the output into a property that can be used in a .jar manifest

I would like to execute git describe as part of a maven build and use the resulting output in the manifest for building a .jar package.

I know how to do this in ant via the <exec> task with outputproperty to an ant property variable, but I have very little experience with Maven and don't even know where to look.

Is this possible?


I found this in a sample pom.xml file so adding something to the manifest looks pretty easy:

<project>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>my.class.here.Myclass</mainClass>
                            <classpathLayoutType>custom</classpathLayoutType>
                            <customClasspathLayout>lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Not sure how to capture command execution though.

Upvotes: 6

Views: 3742

Answers (3)

Callan
Callan

Reputation: 475

Building on what @A_Di-Matteo said, you can get the git tag into the properties file like this

In the maven exec plugin.

        <execution>
            <id>set-git-tag</id>
            <phase>validate</phase>
            <goals>
              <goal>exec</goal>
            </goals>
            <configuration>
              <executable>bash</executable>
              <arguments>
                <argument>-c</argument>
                <argument>echo git.tag=`git describe --always --dirty=-modified`</argument>
                <argument>></argument>
                <argument>config.properties</argument>
              </arguments>
              <workingDirectory>${basedir}/src/main/resources/</workingDirectory>
            </configuration>
          </execution>

You can also append to an existing file like so

          <execution>
            <id>set-git-tag</id>
            <phase>validate</phase>
            <goals>
              <goal>exec</goal>
            </goals>
            <configuration>
              <executable>bash</executable>
              <arguments>
                <argument>-c</argument>
                <argument>echo git.tag=`git describe --always --dirty=-modified`</argument>
                <argument>>></argument>
                <argument>${basedir}/src/main/resources/config.properties</argument>
              </arguments>
            </configuration>
          </execution>

The limitation here is that it requires bash.

Upvotes: 0

JJF
JJF

Reputation: 2777

There is a Maven plugin here https://github.com/ktoso/maven-git-commit-id-plugin that will do what you want.

If you hook into your build it will generate a Maven variable named ${git.commit.id.describe} that you can then use Maven's resource filtering to dynamically modify your manifest.

Upvotes: 1

A_Di-Matteo
A_Di-Matteo

Reputation: 27822

Here is a suggested approach:

The configuration loaded can then be used as properties in your POM. We are basically dynamically creating properties of our build. To do so (to use these properties), the steps above must be executed as early as possible in the build flow (i.e. validate or initialize phase).

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.

If you can't get a way of having the result of git describe as name=value pattern, you can (worst case) have two Exec Maven Plugin executions, the first writing to the file the property name and the equals character (i.e. via an echo), the second (git describe) appending to the file the property value.

Upvotes: 7

Related Questions