How to pass an argument to a dependency in Ant Build Tool - ant

I'm creating a target in the build.xml file which depends on three other targets:
<target name="test" depends="target1,target2,target3">
<echo message="Build Successful!"/>
</target>
What I'm trying to do here is to pass some argument to 'target2'. Can this be done in Ant? If so, how can I do it?
Any help is truly appreciated!!

Do you understand how depends works?
When you call target test, it will run the following targets:
target1
target2
target3
test
In that order. There's no way for target test to pass any arguments to target2.
You can pass properties to your build.xml script using the -D parameter:
$ ant -Dsource.version="1.5" compile
When your build script is executed, the property source.version will be set to 1.5.
Otherwise, look at macrodef task as a way of passing arguments to particular routines.
By the way, if I had more information what you want, I could give you a better answer.

Related

Ant inline exec arguments

I have tasks running in Ant, which I'm quite new to, as part of a CI chain of build events. I used a tutorial to create the file for testing/linting/etc a PHP application.
The first important directives in the build.xml are:
<property name="phpmd" value="phpmd"/>
<property name="phpunit" value="phpunit"/>
This works fine as is, assuming that phpmd/phpunit are on the path, and using phpunit as a further example, is run under the following target:
<target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit">
<exec executable="${phpunit}" resultproperty="result.phpunit" taskname="phpunit">
<arg value="--configuration"/>
<arg path="${basedir}/phpunit.xml"/>
</exec>
<property name="phpunit.done" value="true"/>
</target>
All this works well as is- but I want to use docker from now on, which I had hoped would simply mean changing <property name="phpunit" value="phpunit"/> to <property name="phpunit" value="docker-compose run php phpunit"/>, but this instead gives me the following error:
Execute failed: java.io.IOException: Cannot run program "docker-compose run -w /var/www/src php phpunit" (in directory "/var/lib/jenkins/jobs/Blah blah blah/workspace/src"): error=2, No such file or directory
I know that you would usually add additional <arg/> nodes to targets- but is it not possible at all to provide the full command with inline arguments on the initial <property>?
Ant is obviously complaining because, along with those inline arguments, that executable doesn't exist. Will I have to use arg nodes and update every single target?
Using docker-compose alone works fine, but I need the args for the correct container and working directory to be used- preferably inline, otherwise I have to insert many arg nodes.
In the end I just created a property for phpunit arguments and then added it by using the <args line="${phpunitArgs}">.
Definitely not ideal, but at least it does what it is supposed to. I certainly prefer using Gulp! XML feels like a bad choice for a build system.

Conditional execution in Ant

I have a target, that is executed if my_step==true:
<target name="pre-compile" if="my_step">
...
</target>
But I want to make that pre-compile target available regardless of the value of my_step, so that I could execute my action manually using ant do_my_step:
<target name"-do_my_step">
...
</target>
Question. How can I run make pre-compile execute -do_my_step target?
That is, if property my_step is true, then pre-compile step will execute -do_my_step target.
Obviously, I could simply copy-paste contents of -do_my_step target into pre-compile target, but I want to keep my target cleanly separated.
Target names with prefix '-' are a common practice to make the target somewhat 'private' as it's impossible to call it via commandline. ant -f yourbuildfile.xml -yourprivatetarget won't work as ant commandline interface uses leading '-' for options. So strip the leading '-' from your target name to call it via ant -f yourbuildfile.xml do_my_step
Also consider :
"..Question. How can I run make pre-compile execute -do_my_step target? .."
Ant has antcall task for calling a target within the same buildscript. But antcall should be avoided because it opens a new project scope (so it needs more memory and will slow down your build) and breaks the dependency chain which is normally built via <target name="..." depends"=..."> . antcall is superfluous since ant 1.6 introduced macrodef for that purpose (reuse of functionality).
<target name="pre-compile" if="my_step" depends="-do_my_step">
...
</target>
When pre-compile is called, it will run -do_my_step before.

run all tests marked #Ignore

I want to make a Jenkins job to run an ant task to run all tests in my codebase which are tagged #Ignore because using annotations like #Category(IgnoredTest.class) do not work with our test run parallelization. After a lot of searching it looks undoable, but I still have hope. Help?
JUnit 4.10
I'm not sure what the impediment is with your "test run parallelization", but you might be able to do this with a rule if you're willing to use a custom "ignore" annotation instead of the JUnit one. The reason for that is that JUnit handles #Ignored tests at the Runner level, specifically in the BlockJUnit4ClassRunner.runChild() (by default). If you could find a way to use a custom Runner in Ant, you could come up with one to meet your needs pretty easily, but I don't know if that's easily doable in Ant.
As I first mentioned, though, you can easily use a different annotation and a rule to choose which methods to run. I made up a quick example of such a rule on github, along with a test that uses it. My little example uses a system property for switching, but you can also obviously make it switch on anything you can think of that you can get your hands on here.
You can clone and run this example with:
git clone git#github.com:zzantozz/testbed tmp
cd tmp
mvn test -pl stackoverflow/9611070-toggleable-custom-ignore -q
mvn test -pl stackoverflow/9611070-toggleable-custom-ignore -q -D junit.invertIgnores
The one downside of this approach that I can think of is that your tests won't get properly marked as "ignored" because that's also done by the BlockJUnit4ClassRunner.runChild() method, and if you peek at ParentRunner.runLeaf() (which runChild() delegates to), you'll see that the notifier, which is what you need to report ignored tests, isn't passed down far enough to be used by a Rule. Again, it's something you'd need a custom Runner for.
You could create a special ant target that removes the #Ignore annotation and add an #ignore annotation to any active #Test annotated method
the target would be something like this:
<project name="anyname" default="test" basedir=".">
..
..
<target name="enable-ignored-test" depends="copy-code-to-replace-ignored">
<fileset id="fsTestCase" dir="." includes="**/*Test.java">
</fileset>
<replaceregexp flags="gm">
<regexp pattern="^#Ignore"/>
<substitution expression=""/>
<fileset refid="${fsTestCase}"/>
</replaceregexp>
<replaceregexp flags="gm">
<regexp pattern="#Test"/>
<substitution expression="#Ignore #Test"/>
<fileset refid="${fsTestCase}"/>
</replaceregexp>
</target>
<target name="run-ignored-tests" depends="enable-ignored-test,test" />
..
..
</project>

checking latest version in version control

i am currently writing an ANT script which will include some intelligence to check for things. I am using SnapshotCM from True Blue Software as my version control and using CruiseControl as a framework for my nightly build.
Basically, I will need to always check for the latest version found in my version control and execute commands. In this case here is an example:
<project name="nightly_build" default="main" basedir="checkout">
<target name="init">
<property file="initial.properties"/>
</target>
<target name="main" depends="init">
<!-- need some code to set variable -->
<!-- need some code to increment variable -->
<!-- need some code here to check for the latest version -->
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg line='-f -R "C:/Work/7.10.000_Tip/7.10.000_Tip_GUI_TEST/"'/>
</exec>
</target>
</project>
In the code above, I will load the "initial.properties" file.
The algorithm should be as follow:
load the initial properties file
get the build_number
increment build_number by 1 (let this new variable be X)
if X is found, increament X by 1 (if not found jump to 6.)
if X is found, repeat 4 (until X cannot be found)
else use the build number inside the <arg line ='-f -R "C:/..../7.10.100.X..../"'/>
The initial.properties file is as follow:
Major_Version=7
Minor_Version=10
Project_Number=100
Build_Number=036
Product_Version=${Major_Version}.${Minor_Version}.${Project_Number}.${Build_Number}
can anyone guide me on that?
Ant is not a programming language. It's a dependency matrix language.
That means you don't specify execution order in Ant. Ant will calculate the order it needs to run the targets. It also means Ant doesn't have the ability to do loops, or even change the value of a property once it is set.
There are a few packages that build upon Ant. The old standby is the Antcontrib. Antcontrib has the concept of variables which are like mutable properties. It also has various looping structures. However, I'm not sure if the <foreach> or <for> tasks will do what you want...
Searching sequentially for the next build number is something you can do in a shell script. In fact, I highly recommend this.
I use Ant for builds only and keep my CM functions outside of my build.xml file. Instead, I rely on my build system to do everything that's not related to the build itself. This includes checking out the code, saving the artifacts, and compiling unit tests. This way, if I change the way I use my continuous build system or my version control system, I don't have to modify my build.xml files.

Ant build scripts, antcall, dependencies, etc

I have a build script and as part of that script it copies a jar file to a directory, for ease lets call it the utils jar. the utils jar is built by another build script sitting in another directory. What im trying to do have my build script run the utils build script so that I can ensure the utils jar is up to date.
So I know I need to import the utils build file.
<import file="../utils/build/build.xml" />
Which doesn't work because the import task, unlike almost every other ant taks, doesn't run from basedir, it runs from the pwd. So to get around that I have this little ditty, which does successfully import the build file
<property name="baseDirUpOne" location=".." />
<import file="${baseDirUpOne}/utils/build/build.xml" />
So now that ive solved my import problem I need to call the task, well that should be easy right:
<antcall target="utils.package" />
note that in the above, utils is the project name of ../utils/build/build.xml
the problem I'm now running into is that ant call doesn't execute in ../utils/build so what I need, and cant find, is a runat property or something similar, essentially:
<antcall target="utils.package" runat="../utils/build" />
The reason I need this is that in my utils build file the step to select which code to copy to the jar is based on relative paths so as to avoid hardcoding paths in my ant file. Any ideas?
I've got something similar set up: I have a main Ant build.xml which calls a separate build.xml that takes care of building my tests. This is how I do it:
<target name="build-tests">
<subant target="build">
<fileset dir="${test.home}" includes="build.xml"/>
</subant>
</target>
The trick is to use subant instead of antcall. You don't have to import the other build file.
Try using the "ant" task instead of the "antcall" task, which runs the imported build directly instead of importing it into the current build file. It has a "dir" parameter:
the directory to use as a basedir
for the new Ant project. Defaults to
the current project's basedir, unless
inheritall has been set to false, in
which case it doesn't have a default
value. This will override the basedir
setting of the called project.
So you could do:
<ant antfile="${baseDirUpOne}/utils/build/build.xml" dir="../utils/build" />
or something like that.
You can pass params down to antcall using nested in the antcall block. So, you can pass the properties down that way (probably even basedir since properties are immutable).

Resources