How to run powershell script in maven - 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>

Related

How can a maven property be used in a maven attribute?

For a previously defined property <scala.js.opt> I'd like to be able to include it like so in a pom.xml file:
<arg value="${scala.js.opt}"/>
However, this doesn't seem to work. Is it even possible, or are there any workarounds?
The particulars of my specific case is that these are arguments to an executable in the maven-antrun-plugin, should this be easier with my specific case.
Detailed example follows
In master pom file:
<properties>
<scala.js.opt>fastOptJS</scala.js.opt>
</properties>
Then in child pom file
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<target>
<exec executable="cmd.exe"
spawn="true">
<arg value="/c"/>
<arg value="C:\Program Files (x86)\sbt\bin\sbt.bat"/>
<arg>${scala.js.opt}</arg>
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
When run using e.g., mvn install, this produces:
org.apache.tools.ant.types.Commandline$Argument doesn't support nested text data ("fastOptJS")

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.

Is it possible to run a Bash script from Maven?

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

Maven and Exec: forking a process?

I'm trying to use Maven to start an application prior to running some integration tests on it. I'm on Windows. My Maven plugin configuration looks like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>start-my-application</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>start_application.bat</executable>
<workingDirectory>./path/to/application</workingDirectory>
</configuration>
</execution>
<executions>
<plugin>
and my batch file looks like this:
start myApplication.exe
When run in isolation, the batch file spawns a separate window to run the application and immediately returns control.
However, when run from Maven, the build waits for the process in the separate window to finish before continuing. This somewhat defeats the point of the integration testing phase...
Any ideas how I can start a truly separate process in Maven to allow the build to continue alongside it?
For the record, a rather hackish solution is to use maven-antrun-plugin to call Ant, which is capable of spawning separate processes:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<configuration>
<target>
<exec executable="cmd"
dir="./path/to/application"
spawn="true">
<arg value="/c"/>
<arg value="start_application.bat"/>
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Try this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>start-my-application</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>call</executable>
<arguments>
<argument>start_application.bat</argument>
</arguments>
<workingDirectory>./path/to/application</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>

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