Ant attributes duplication for javac - ant

I have an Ant build with a lot of javac tasks.
I want all of them to be executed with the following attributes:
debug = "true" debuglevel = "lines,vars,source"
(by default debugging information is turned off which makes it harder to investigate the console).
Is it possible to provide such attributes in some centralized place which will have influence for all javac tasks in current Ant build? (I don't want duplicating them over all javac tasks...)

You need ant's presetdef
From the example
<presetdef name="my.javac">
<javac debug="${debug}" deprecation="${deprecation}"
srcdir="${src.dir}" destdir="${classes.dir}">
<src path="${gen.dir}"/>
</javac>
</presetdef>
Instead of my.javac, you can put javac.
You can define this in one build file and import every where else.

Related

Ant script split file name and extension into 2 separate properties

I have a fileset that has say 10 files with extensions. I need to then take this and get the filename and extension into 2 separate properties/variables but not sure how. The reason I need to do this as a file starts out on Unix as XB12345.FILE which I need to move to an I/5 system with the file name as XB12345.FILE and the member as FILE.MBR. Most of the files do not have a consistent extension and will only be known at run time. Any help would be appreciated.
This sounds like a job for the Ant-Contrib tasks.
The Ant-Contrib tasks have been around for a long time and are quite common to see in Ant projects. The PropertyRegex task will do what you want. In fact, there's even a For task that can handle loops.
The <PropertyRegEx> task would look something like this:
<propertyregex property="base.name"
input="file.name"
regexp="(.*)\.(.*)"
select="\1"/>
<propertyregex property="suffix.name"
input="file.name"
regexp="(.*)\.(.*)"
select="\2"/>
Installing the Ant-Contrib tasks is fairly easy if you follow these steps:
Download the ant-contrib-1.0b3.jar.
Create a directory in the root of your project called antlib/ac.
Put the ant-contrib-1.0b3.jar file in theantlib/ac` directory.
Add the task definition.
Like this:
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${basedir}/antlib/ac"/>
<classpath>
</taskdef>
If you use a version control system, check in the ant-contrib-1.0b3.jar file into your version control system for the project. Now, when someone needs to do a build, they checkout your project, and the Ant Contrib tasks are already defined and the Ant-Contrib jar is there. There's no need for the developer to install Ant-Contrib. Your build just works.
Though propertyregex is the solution for the intended problem, but you must use override property for you solution.
<propertyregex property="base.name"
input="file.name"
regexp="(.*)\.(.*)"
select="\1" override="true"/>
<propertyregex property="suffix.name"
input="file.name"
regexp="(.*)\.(.*)"
select="\2" override="true"/>

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.

Passing "-J-Duser.language" into javac through ant to ensure compilation errors are reported in the correct language

My PC is currently set up as Japanese for testing purposes. If my java project has a compilation error the message is reported in Japanese.
e.g.
Compiling 1 source file to [...directory...]
[...class...].java:172: シンボルを見つけられません。
I would prefer to see the errors in english.
Without using ant the fix for this is to use
javac -J-Duser.language=en [..java files...]
which makes javac give english error messages (the -J tells javac to pass the rest of the argument to java)
My question is: how do I pass this to ant
[editted to remove options I tried that didn't work]
Try adding a <compilerarg> to your <javac> call. For example:
<javac srcdir="${src.dir}" destdir="${classes.dir}" fork="true">
<compilerarg value="-J-Duser.language=en"/>
<compilerarg value="-J-Duser.country=GB"/>
</javac>
EDIT Fixed the arg values. Also, this only works if the compiler is forked; I updated the example to reflect that.

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