ant: create dirset with all dirs containing files in a fileset - unit-testing

Context: a directory, recursively containing python unittest.TestCases:
projectdir/build.xml
projectdir/src/x.java
projectdir/distribute/p.jar
projectdir/tests/a/test1.py
projectdir/tests/a/test2.py
projectdir/tests/b/test1.py
projectdir/tests/c/test1.py
projectdir/tests/javaunittests/test2.java
And I want ant to call
python -m unittest discover -s a b c
Now I was trying to convert a fileset to the dirset of the containing directories? The idea is to run python unittests:
<apply command="python">
<arg line="-m unittest"/>
<arg value="-s"/>
<dirset include="${python_unittests}"/>
</apply>
where ${python_unittests}" would refer to afileset` (but I don't find how) like this:
<fileset id="python_unittests" include="**/*.py">
<containsregexp expression="\(unittest.TestCase\)"/>
</fileset>
Or am I erring, and is there a better way to achieve this?

You want all python files with testcases, you don't need a dirset, use :
<apply executable="python">
<arg line="-m unittest"/>
<arg value="-s"/>
<fileset dir="projectdir" includes="**/*.py">
<contains text="unittest.TestCase"/>
</fileset>
</apply>
EDIT
Just checked the docs for unittest on python.org after your comment.
As i understand it, that should be sufficient :
<property name="projectroot" location="foo/bar/yourprojectdir"/>
<exec executable="python" failonerror="true">
<arg line="-m unittest discover ${projectroot} 'test*.py'"/>
</exec>
as python docs section 26.3.3. Test Discovery explains :
The -s, -p, and -t options can be passed in as positional arguments in that order. The following two command lines are equivalent:
python -m unittest discover -s project_directory -p '*_test.py'<br>
python -m unittest discover project_directory '*_test.py'
I expect that discover works recursively starting from project_directory.

Related

ANT build : Variable inside resolver:artifacts is undefined

I have setup this ANT build.xml file which pulls in version info from a txt file , reads the first line, trims it and copies it into a variable called 'versionVal' with below code:
<target name="clean"
.
. do something more
.
<loadfile property="versionValTxt" srcfile="version.txt">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.HeadFilter">
<param name="lines" value="1" />
</filterreader>
</filterchain>
</loadfile>
<loadresource property="versionVal">
<propertyresource name="versionValTxt"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from="V" to=""/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadresource>
<echo>"Building for version: ${versionVal}"</echo>
</target>
And in one of the targets I am trying to refer a resolver artifact which uses this versionVal to find a file with that specific version in its name as shown below:
<resolver:artifacts id="producedArtifacts" >
<resolver:artifact file="${dist.dir}/App.${versionVal}.zip"/>
</resolver:artifacts>
<target name="nexus">
<echo>"versionVal: ${versionVal}"</echo>
<resolver:deploy artifactsref="producedArtifacts">
<resolver:remoterepo refid="ossrh"/>
</resolver:deploy>
</target>
And the build keeps failing as below, where it shows the variable versionVal is undefined.
C:\Users\XYZ\git\App\WebContent\dist\App.${versionVal}.zip does not exist
Note that the block is able to recognize ${dist.dir} but it doesnt recognize ${versionVal}. However I am able to print the value using an echo inside the target-nexus.
Much appreciated if anyone can point me in the right direction. I am not able to figure out why this variable is not recognized under "resolver:artifact file" and if there are any alternatives to this problem.
Realised I had to include below resolver artifact inside a target block and then use that as depends in the nexus block. After making this change the variable 'versionVal' was recognized.
Solution:
<target name="packagedArtifact" >
<resolver:artifacts id="producedArtifacts" >
<resolver:artifact file="${dist.dir}/App.${versionVal}.zip"/>
</resolver:artifacts>
</target>
<target name="nexus" depends="packagedArtifact">
<resolver:deploy artifactsref="producedArtifacts">
<resolver:remoterepo refid="ossrh"/>
</resolver:deploy>
</target>

Rename a file before Copy Task in ant build

I am new to ant build files.
Currently I get a list of files for build as:
a.cls
b.cls
c.cls
but in my local I have to run build on files, in the same directory:
a-meta.cls
b-meta.cls
c-meta.cls
Here meta keyword stays consistent. And I am using the following build.xml file. I am not sure how can I rename filename before actually copying them. I tried replace, mapper and other antlib tasks. But not helpful.
<project name="test" default="compile">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<loadfile property="file" srcfile="filesToMove.txt"/> <!-- these are the list of files, i mentioned earlier -->
<target name="compile">
<echo>${file}</echo> <!-- here i have to rename file name to include -meta -->
<copy file="./classes/${file}" tofile="./src/classes/${file}" overwrite="true"/>
</target>
</project>
How to rename the files before moving them.
The solution to it was replacing the .cls to find only the name and then append the -meta.html. As follows (some portion is changed compared to previous version in the question)
<project name="test" default="compile">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<loadfile property="file" srcfile="filesToMove.txt"/> <!-- these are the list of files, i mentioned earlier -->
<target name="compile">
<echo>${file}</echo> <!-- here i have to rename file name to include -meta -->
<copy file="./classes/${file}" tofile="./src/classes/${file}" overwrite="true"/>
<for param="file">
<path>
<fileset dir="./" includes="*.cls"/>
</path>
<sequential>
<basename file="#{file}" property="#{file}" suffix=".md"/>
<echo message=" ${#{file}}"/>
<copy file="${#{file}}-meta.cls" toDir="test"/>
</sequential>
</for>
</target>
</project>

Jnuit and Code files in different locations

I am trying to run ANT script to execute a simple junit test case.
Now I have a requirement.
The executable file with my sample product will be in one location
My junit test cases will be in another location
Still I have to sync up and get the test case executed
Is there a way where I can ask my Junit to look another location for source.
If your junit test cases live in another project then you will need to create a seperate build.xml for that project setup for unit tests. Make sure this new build.xml references your sample product JAR as a dependency.
Yes this is possible.
Compile your source files as usual:
<javac srcdir="../${srcDir}/src" destdir="dist/src">
Compile your test files, including the compiled source in your classpath:
<javac srcdir="../${testDir}/test" destdir="dist/test">
<classpath location="dist/src"/>
</javac>
Then include both these in the JUnit classpath:
<path id="junit.path">
<pathelement location="dist/src" />
<pathelement location="dist/test" />
<fileset file="../Libraries/junit*.jar" />
<fileset file="../Libraries/ant-junit*.jar" />
<fileset dir="externalLibraries">
<include name="**/*.jar" />
</fileset>
</path>
<junit fork="yes" forkmode="once">
<classpath refid="junit.path" />
<batchtest fork="yes" todir="${dist}/testresults">
<fileset dir="dist/test">
<include name="**/*Test.class" />
</fileset>
</batchtest>
</junit>
See also Ant documentation

Ant PropertyRegex won't support capture group when in property

I'm trying to create an ant build target that supports var substitution dynamically.
<target name="replace_property" depends="init_ant_contrib">
<propertyregex input="${replace_inboundproperty"
property="${replace_outboundproperty}"
regex="${replace_match}"
replace="${replace_target}"
global="true"
override="true" />
</target>
so I load the properties file and i'm basically setting the vars as such:
replace_inboundproperty="/target/path/targetfile"
replace_outboundproperty=blah
replace_match="/target/(.*)/targetfile"
replace_target="\1"
so when I echo blah, I'm getting "1". Now if I actually do this:
<target name="replace_property" depends="init_ant_contrib">
<propertyregex input="${replace_inboundproperty"
property="${replace_outboundproperty}"
regex="${replace_match}"
replace="\1"
global="true"
override="true" />
</target>
and echo blah, I'll get "path".
Can anyone tell me what I'm missing to allow the replace to use capture groups from a properties file / ant -D? Using ant-contrib 1.0b3.
Thanks!
Found out that in the properties file, if you double escape it, it'll function correctly:
replace_target=\\1

Javac exclusion of package in ANT build.xml

I'm trying to compile all my packages except two of them, here is what my javac in build.xml looks like
<javac srcdir="${src}" destdir="${output}" debug="${debug}" failonerror="yes" >
<exclude name="com/abc/uyyy/**"/>
<exclude name="com/abc/zzz/**"/>
<include name="com/abc/zzz/Text.java"/>
<patternset refid="excluded.from.compilation.abc"/>
<classpath refid="abc.module.classpath"/>
</javac>
But all the files in package are compiled :(.
I've read the documentation (http://ant.apache.org/manual/Tasks/javac.html), but still no success, any help?
NOTE: After the Text.java is compiled, I need to build the WSDL file and then build the excluded packages. I'm using Metro to write and build my WS.
Is it not possbile to compile all the class files into one directory, then use the copy task like below to only copy the ones you want for WSDL?
<target name="copy_all_class_files">
<copy todir="${output}">
<fileset dir="classes">
<include name="com/abc/zzz/Text.class"/>
<exclude name="com/abc/uyyy/**"/>
<exclude name="com/abc/zzz/**"/>
</fileset>
</copy>
</target>
Ok here is what I did,I wrote a new target to compile only the WS file and then generate the classes, it works fine :)
<target name="compile-ws-server">
<javac srcdir="${src}" destdir="${output}"
debug="${debug}" failonerror="yes">
<include name="com/abc/xxx/Text.java"/>
<exclude name="${src}/abc/xxx/**"/>
<classpath refid="abc.module.classpath"/>
</javac>
</target>
All Above is not proper way ...
I have done like
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" excludes="com/company/example/test/**" />
</target>
Here we should avoid placing ${src} and start from inside src folder.