Is it possible to run a Bash script from Maven? - bash

For creating configuration of my application I need to run bash script.
Is it possible to integrate execution of Bash scripts in Maven, maybe there are some plugins?

Could the Bash Maven Plugin help you? (Disclaimer: I initiated it, so please send me feedback)
<build>
<plugins>
<plugin>
<!-- Run with:
mvn bash:run
mvn install
-->
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>bash-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<script>
# Here you can execute shell commands
echo "Tomcat will start"
/opt/apache-tomcat/bin/startup.sh
</script>
</configuration>
</plugin>
</plugins>
</build>
You will need to install this maven plugin in your own Maven repo.
Like Konstantin: When you execute a shell script, you're not portable anymore.

You can do this, see answer:
I want to execute shell commands from maven's pom.xml
But it is not advisable, as this produces not so portable builds. Why do you need this in first place? Using this plugin usually indicates some weird necessity in project build

Would look more like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generateSources</id>
<phase>generate-sources</phase>
<configuration>
<tasks>
<exec executable="/bin/bash">
<arg value="myFirst.sh" />
<arg value="inputOne" />
</exec>
<exec executable="/bin/bash">
<arg value="src/mySecond.sh" />
<arg value="inputTwo" />
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
With myFirst.sh:
echo "call to myFirst.sh, message ${1}"

Solved. The problem is, executable is working in a different way for bash. This code is working. Write it in pom.xml
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution><!-- Run our version calculation script -->
<id>Renaming build artifacts</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>bash</executable>
<commandlineArgs>handleResultJars.sh</commandlineArgs>
</configuration>
</execution>
</executions>
</plugin>

If at all possible, I'd recommend using a scripting language that runs inside the JVM with dependencies that are captured either in your project or in the maven repository. That way your builds are platform independent and your dependencies are captured (i.e. you don't loose the build machine and realize your bash script was specific to that box). I showed an example in this post of using jacl. There are also good examples of using javascript and groovy inside antrun (though there may be more straightforward ways of calling them directly).

Use the maven-antrun-plugin artifact. This way, you can execute several executables sequentially more easily than exec-maven-plugin. Example:
* The <exec> tag is the important one here.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<exec executable="my1.sh">
<arg value="input1"/>
</exec>
<exec executable="my2.sh">
<arg value="input2"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

To experiment with commands you can use exec:exec:
$ mvn exec:exec -q -Dexec.executable=echo -Dexec.args="your arguments"
your arguments
$ mvn exec:exec -q -Dexec.executable=echo -Dexec.args="'your arguments'"
your arguments
This demonstrates:
passing arguments: if you need to pass several arguments: just split them with space
if you need to pass an argument with spaces: enclose it in quotes, as you would do in bash script/terminal
-q to shut up the mvn log

Related

How to run powershell script in maven

I currently dealing with a problem using maven. I try to update a file when building the software using maven. For some reason, I have to use a powershell script and run it when building using mvn. Here is my code:
<exec executable="powershell.exe"
spawn="true">
<arg value="/c"/>
<arg value="myReplace.ps1"/>
<arg value="../../the/path/to/the/directory/" />
<arg value ="filename"/>
<arg value="value1" />
<arg value="value2" />
<arg value="value3" />
</exec>
It does not work as expected, can someone help me?
This message dates from a while but I went through the exercise in the last days. The key is to use the exec plugin as stated. Here is an example in a project's pom.xml:
The code below launches the code-signing on a PowerShell module script. Note that the command string must begin, for calling PowerShell functions from the command line, with & which is not properly digested by Maven. Escaping it does the trick. For more complex operations, call a PS script.
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>scripts-package</id>
<goals>
<goal>exec</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<!-- optional -->
<workingDirectory>/Temp</workingDirectory>
<arguments>
<argument>-command</argument>
<argument>"& { Set-AuthenticodeSignature '${project.build.directory}/Logging_Functions/*.psm1' #(Get-ChildItem ${project.build.certificate.path} -codesigning)[0]"}</argument>
</arguments>
</configuration>
</execution>
This avoids a bug with PowerShell hanging on StdIn.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<useMavenLogger>true</useMavenLogger>
</configuration>
<executions>
<execution>
<id>run-my-script</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>powershell.exe</executable>
<arguments>
<argument>-InputFormat</argument>
<argument>None</argument>
<argument>-File</argument>
<argument>${basedir}/my_script.ps1</argument>
</arguments>
</configuration>
</execution>
<executions>
<plugin>

Running adb.exe command from maven 3.0.5

Is it possible to run adb.exe commands from maven. For example I want to run adb shell instrument -e classname#testcasename -w packagename/instrumenation. I need to run this command in maven is it possible?? Do i need to specify it in the pom.xml file or it can be run directly by specifying the command-line argument.
You can use the Maven Exec Plugin to execute cmd commands.
In the snippet below (add it to a pom.xml), the command ping with the argument 8.8.8.8 will be executed every time you do a mvn install:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.2.1</version>
<executions>
<execution>
<id>My Command Runner</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>ping</executable>
<arguments>
<argument>8.8.8.8</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
In your case, the inner configuration would be something around:
<configuration>
<executable>adb </executable>
<arguments>
<argument>shell</argument>
<argument>instrument</argument>
<argument>-e</argument>
<argument>classname#testcasename</argument>
<argument>-w</argument>
<argument>packagename/instrumenation</argument>
</arguments>
</configuration>
Make sure you bind it to the phase you really need. The example above, as said, is bound to the mvn install - meaning the command will be executed when someone runs that (install) phase.

Using sbt from maven

I have a maven project and an SBT project as a module of the maven project. I need to create a single command maven build, which executes SBT package task too.
Is there any plugin which I can use to integrate SBT with maven?
Thanks.
One option is using "Exec Maven Plugin", and here is an example to do a "play compile"
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>${path.to.play}</executable>
<workingDirectory>${path.to.project.root}</workingDirectory>
<arguments>
<argument>compile</argument>
</arguments>
</configuration>
</plugin>
Use the maven antrun plugin (my example is for building a Scala.js app).
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<configuration>
<target>
<exec executable="cmd.exe"
spawn="true">
<arg value="/c"/>
<arg value="C:\Program Files (x86)\sbt\bin\sbt.bat"/>
<arg value="fullOptJS"/>
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Credit due to #checat for suggesting this in his comment and the discussion at Launching a windows batch script using Maven exec plugin blocks the build even though the script uses "start"
Other thoughts; it might still be worth using mvn-exec on non Windows systems, perhaps using maven profiles. If I go this route, I'll try to remember to update the answer.

How to call maven-antrun-plugin target without attach execution to a maven phase ?

I use maven-antrun-plugin for init config files for my project. But i need to init config files just once, when i first start to init my dev environment, not each time i launch jetty:run.
If I attach phase to process-resouces for example, each time I launch jetty, my config files are reseted.
So i configured antrun like this :
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="init_config_files">
<!-- init files -->
</target>
</configuration>
</execution>
</executions>
</plugin>
If I launch mvn antrun:run, it just return me this error : "[INFO] No ant target defined - SKIPPED". And it is the same thing, if I specify target : "mvn antrun:run -Dtarget=init_config_files".
Try this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<target>
<property name="compile_classpath" refid="maven.compile.classpath" />
<echo message="compile classpath: ${compile_classpath}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
and run this:
mvn antrun:run
Best solution I have found so far:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>go-live</id>
<configuration>
<target>
<!-- go live! -->
<exec executable="${basedir}/deploy2server.sh" failonerror="true" dir="${basedir}">
<arg value="deploy" />
<arg value="${deploy.to.server}" />
<arg value="${jetty.port.live}" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
and run this:
mvn antrun:run#go-live
This solution avoids the target being run by accident, ie. it does not run just by typing "mvn antrun:run" and it also does not run during regular maven runs. I'm using this for qa auto-deployment in my jenkins instance after all modules incl integration done against the final distribution package have been successfully executed.
I just ran into the same problem and finally figured it out: If you want to run the ant tasks only once, you can set the plugin up like this:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<target name="init_config_files">
<!-- init files -->
</target>
</configuration>
</plugin>
and use mvn antrun:run to execute it. That way, the ant stuff is not bound to any phase.
If you need to run some part of build on special conditions (e.g. once), you can put those parts into a Maven profile and then invoke Maven specifying profile name, e.g. mvn -p init_config_files package

How to use maven-antrun-plugin for phase exec

Is it possible to use maven-antrun-plugin for the exec phase/goal.
currently I use the following but it does not work:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>exec</id>
<phase>exec</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target
name='Exec'
>
<exec
executable='${env.COMSPEC}'
osfamily='winnt'
>
<arg
value='/c'
></arg>
<arg
value='src\\main\\scripts\\Exec.cmd'
></arg>
</exec>
<exec
executable='src/main/scripts/Exec.command'
osfamily='unix'
></exec>
</target>
</configuration>
</execution>
</executions>
</plugin>
Of course if anybody knows a way around the ${env.COMSPEC} hack on windows that would be welcome as well.
It looks like the plugin is used to run an arbitrary executable and not an ant task which should ideally not have OS-specific check.
Perhaps you should look at Exec Maven Plugin?

Resources