Apache Ant: Unable to call Composer's vendor/bin scripts - ant

I am using Apache Ant for my builds. I have some composer scripts belonging to several vendors in vendor/bin folder. I have added this folder to the system path and if I run the commands on my command window in works but in the build file i get an error.
Is there anything I should be doing differently? Before is an example:
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="build" basedir=".">
<target name="phpcpd" description="Find duplicate code using PHPCPD">
<exec executable="phpcpd">
<arg value="--version" />
</exec>
</target>
</project>'
I get this when I run ant phpcpd
phpcpd:
BUILD FAILED
C:\xxxxxx\xxxxxxx\build.xml:96: Execute failed: java.io.IO Exce
ption: Cannot run program "phpcpd": CreateProcess error=2, The system
cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
at java.lang.Runtime.exec(Runtime.java:617)
at org.apache.tools.ant.taskdefs.launcher.Java13CommandLauncher.exec(Jav
a13CommandLauncher.java:41)
at org.apache.tools.ant.taskdefs.Execute.launch(Execute.java:428)
at org.apache.tools.ant.taskdefs.Execute.execute(Execute.java:442)
at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:628)
at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:669)
at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:495)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
...
But phpcpd --version works on command prompt

ANT is not aware where phpcpd is as it doesn't share path with your Command Promt.
One way around it is to create a .bat file to run phpcpd
Create a phpcpd.bat with the following:
#echo off
phpcpd --version
Your build scripts to be updated from :
<exec executable="phpcpd">
<arg value="--version" />
</exec>
To: <exec executable="phpcpd.bat"/>
Above assumed with Windows Command Promt

My solution was to use the .phar files of the scripts. That way, the build file became platform independent to a large extent. So
<target name="phpcpd" description="Find duplicate code using PHPCPD">
<exec executable="phpcpd">
<arg value="--version" />
</exec>
</target>
Became:
<target name="phpcpd" description="Find duplicate code using PHPCPD">
<exec executable="php">
<arg value="${phpcpd}" />
<arg value="--version" />
</exec>
</target>
Where ${phpcpd} is the path to the phar file

I'm using absolute paths and a configurable executable.properties like this:
build.xml
<project name="build">
<property file="executable.properties" />
<target name="run-phpcd" unless="${phpcpd.skip}">
<exec executable="${phpcpd.executable}"><!-- .. --></exec>
</target>
</project>
executable.dist.properties
phpcpd.skip = no
#phpcpd.executable = C:\path\to\phpcpd.bat
phpcpd.executable = /path/to/phpcpd.sh
Both files can be committed to your VCS, for usage copy the template file (*.dist.properties) and rename it to executable.properties. Add this file to the ignore list of your VCS.

Related

How to generate Avro .avsc files in ANT build

I need to generate files from .avsc file (avro) in ANT build. I'm not sure what plugin should I use for this. I tried with xjc.XJC2Task for generating the files but it seem to not work. Can some one suggest what plugin / class should I use to generate the files from avro schema in ANT ?
Tried with xjc:
<target name="generate" description="generate">
<mkdir dir="generated" />
<taskdef name="xjc" classname="com.sun.tools.xjc.XJC2Task" classpathref="classpath"/>
<xjc destdir="generated">
<schema dir="setup/kafka" includes="*.avsc" />
</xjc>
</target>
Error:
generate:
[xjc] Consider using <depends>/<produces> so that XJC won't do unnecessary compilation
[xjc] Compiling file:/D:/2019/My-workspace/my-project/setup/kafka/Sample.avsc
[xjc] [ERROR] Content is not allowed in prolog.
[xjc] line 1 of file:/D:/2019/My-workspace/my-project/setup/kafka/Sample.avsc
[xjc] failure in the XJC task. Use the Ant -verbose switch for more details
Used java jar command to compile the avro-tools jar . it worked.
<target name="run-avro">
<java jar="lib/avro-tools-1.10.1.jar" fork="true">
<arg line="compile schema"/>
<arg file="avrolocation/Sample.avsc"/>
<arg file="generated/"/>
</java>
</target>

Ant script exec

I'm trying to automate build for my IBM Integration Bus applications. I'm using Jenkins and Ant to do this.
<?xml version="1.0"?>
<project name="project" default="run">
<target name="run" description="">
<property name="toolkit.home" value="C:\Program Files\IBM\IIB\10.0.0.10\server\bin" />
<property name="cmd.home" value="C:\Windows\System32" />
<property name="cmd.file" value="${cmd.home}\cmd.exe"/>
<property name="iib.cmd" value="C:\Program Files\IBM\IIB\10.0.0.10\iib.cmd"/>
<antcall target="build" />
</target>
<target name="build">
<exec executable="${cmd.file}">
<arg value="/k"/>
<arg value="${iib.cmd}"/>
</exec>
<exec executable="mqsilist" newenvironment="false"/>
</target>
</project>
The first exec will set up the IIB build environment. The next exec will list all the Integration nodes installed on the machine. When the script is run, the second exec throws an error. "System can't find the specified file".
When I run the above commands in Powershell or cmd they work fine.
F:\Ant>C:\Windows\System32\cmd.exe /k "C:\Program Files\IBM\IIB\10.0.0.10\iib.cmd"
F:\Ant>mqsilist
What I exactly mean to say is the build environment which the first exec sets is lost. I don't want ant to loose the build environment set by first exec. Tried using newenvironment="false". It didn't work.
Any help would be appreciated.

CMake commands in Ant Script

I have a CMakeLists.txt file which I want to make by using ant script. Is there a way to give commands for cmake . and make through ant? I used to have a MakeFile and I had the following command to make it:
<?xml version="1.0" encoding="UTF-8"?>
<project name="sampleProject" default="make">
<target name="make">
<exec executable="make" failonerror="true">
<arg line="-f Makefile"/>
</exec>
</target>
</project>
Is it somehow similar to this? Does anyone know how to do it? I am looking for an alternative to cmakeant
Invoking CMake from Ant should be analogical. Something like this:
<target name="cmake">
<mkdir dir="build" />
<exec executable="cmake" dir="build" failonerror="true">
<arg line="../" />
</exec>
</target>
Basically, it creates build subdirectory and invokes CMake from it. Passing some other CMake arguments should be trivial aswell.
Also, You might check projects like cmakeant, for more sophisticated CMake wrapper.
NOTE: invoking CMake in source directory is considered to be a bad practice which causes pollution of source subdirectory.

JSCover - Excluding coverage files

Currently trying to get JSCover to exclude js files that are used as libraries. I have a set of ant scripts below which will
start the JSCover server
Run & Generate Json report
Stop the server
Finally, i have a shell command to convert the Json file to LCov so that i can use it with sonarqube. I also get coverage in jscoverage.html but it includes every file under web/ which is something i do not want. Image below
Ant scripts below:
<target name="jstest-start">
<java jar=".../JSCover.jar" fork="true" spawn="true">
<arg value="-ws"/>
<arg value="--report-dir=coverage"/>
<arg value="--document-root=web"/>
<arg value="--port=8082"/>
<!-- Aim is to exclude folder js under web/ as it contains libraries, not source code. Currently does not work -->
<arg value="--no-instrument=web/js/"/>
<arg value="--no-instrument=js/"/>
</java>
<waitfor maxwait="5" maxwaitunit="second" checkevery="250" checkeveryunit="millisecond" timeoutproperty="failed">
<http url="http://localhost:8082/jscoverage.html"/>
</waitfor>
<fail if="failed"/>
</target>
<target name="jstest-run">
<exec dir="/usr/local/CI/phantomjs/bin/" executable="phantomjs" failonerror="true">
<arg line=".../run-jscover-qunit.js http://localhost:8082/index.html"/>
</exec>
</target>
<target name="jstest-stop">
<get src="http://localhost:8082/stop" dest="stop.txt" />
</target>
<target name="jstest" description="Run javascript tests">
<antcall target="jstest-start"/>
<antcall target="jstest-run"/>
<antcall target="jstest-stop"/>
</target>
My folder structure is:
And finally, my sonar standalone analysis settings:
So, what seems to be happening is that JSCover is recursively reading for all js files and i cannot prevent that from sonar or ant.
Can anyone shed some light?
<arg value="--no-instrument=/js/"/>
should work, and to remove the test itself,
<arg value="--no-instrument=/test/"/>
The paths are as seen by the web-server, so the 'web' prefix in:
<arg value="--no-instrument=web/js/"/>
has no effect.
i have resolved my own issue by correcting the shell command which generates an LCOV report.
java -cp JSCover.jar jscover.report.Main --format=LCOV /usr/local/CI/jenkins/workspace/PhantomJS/coverage/phantom/ /usr/local/CI/jenkins/workspace/PhantomJS/web/
Prior to this, the SRC-DIR and REPORT-DIR were the same which was an error on my part. As far as i can understand, SRC-DIR should point to the source folder and REPORT-DIR should point to where the lcov file exists.
I hope this helps someone

ant script not expanding property value in exec arguments

i have an ant script as shown below:
<project name="nightly_build" default="main" basedir="checkout">
<target name="init">
<exec executable="C:/Work/Searchversion.exe"/>
<property file="initial.properties"/>
<property file="C:/Work/lastestbuild.properties"/>
<tstamp>
<format property="suffix" pattern="yyyyMMddHHmmss"/>
</tstamp>
</target>
<target name="main" depends="init">
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg line='-h sinsscm01.sin.ds.net -S"/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}" /'/>
</exec>
</target>
</project>
i created the above script to replicate a command: wco -h sinsscm01.sin.ds.net -S"/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_6.70.102.014" /
and 6.70.102.014 is found inside latestbuild.properties file in the form of:
Version_Number = 6.70.102.014
and this latestbuild.properties file is obtained when i execute C:/Work/Searchversion.exe
but when i execute this ant script using cruisecontrol, in my log file,
[Thread-24] INFO ScriptRunner - [exec] Cannot open snapshot 'sinsscm01.sin.ds.jdsu.net:/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}': No such snapshot
where ${Version_Number} should have been 6.70.102.014
How do i tackle this issue?
EDIT 1:
after trial and error and substituting with a built in property ${ant.version}, i realise that my property file could be loaded in correctly over here. can anyone point out my mistake? i dont see anything wrong though
EDIT 2:
Just additional infomation... This is actually a delegate ant script for cruisecontrol(used to perform nightly build). Here is my config.xml file for per minute build:
<cruisecontrol>
<project name="dms" buildafterfailed="true">
<listeners>
<currentbuildstatuslistener file = "logs/dms/status.txt"/>
</listeners>
<bootstrappers>
</bootstrappers>
<modificationset quietperiod="60">
<alwaysbuild/>
</modificationset>
<schedule interval="60">
<ant buildfile="nightly_build.xml" target="main"/>
</schedule>
<log dir="logs/dms">
<merge dir="checkout/dms/build/test-results" />
</log>
<publishers>
</publishers>
</project>
</cruisecontrol>
should properties file be loaded in config.xml?
Try breaking your arguments to wco.exe into separate child elements like this:
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg value="-h" />
<arg value="sinsscm01.sin.ds.net" />
<arg value="-S" />
<arg value="/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}" />
<arg value="/" />
</exec>
I think ant isn't expanding ${Version_Number} because it is inside ' "..." ' in the version you posted.
As mentioned in the docs for <exec> you should avoid use of the <arg line=...> form.
You could add assertions in your init target that the required properties file exists and that the property is defined. For example:
<property name="version.file" value="C:/Work/lastestbuild.properties"/>
<available file="${version.file}" property="version.file.available"/>
<fail unless="version.file.available" message="file [${version.file}] is not available"/>
<property file="${version.file}"/>
<fail unless="version" message="property [version] is not defined"/>
<echo message="version: ${version}"/>
I think that will help you spot that the file does not exist.
I took a look at your other question about this script you're putting together. In the code which writes the version number to file, you use filename latestbuild.properties:
TextWriter latest = new StreamWriter("C:\\Work\\latestbuild.properties");
In your Ant script, you are loading a different filename lastestbuild.properties.
Unless you've fixed it since then, that will be your problem. (If you modified your external script to take the filename as a parameter, and defined the filename once as an Ant property - as in my sample above - it would help you avoid this kind of problem.)
Regarding your discovery that you need to wait for your external script before continuing in Ant, take a look at the Sleep task.

Resources