How to link or copy in Ant? - ant

I want in Ant to do the equivalent of:
mkdir -p build/test
ln */build/test build/test
or:
mkdir -p build/test
ln -s */build/test build/test
or:
mkdir -p build/test
cp */build/test build/test
I've tried:
<groovy>
new File('build/test').mkdirs()
'ln */build/test/TEST-*.xml build/test'.execute()
</groovy>
and:
<mkdir dir="build/test"/>
<copy todir="build/test">
<fileset dir=".">
<filename name="*/build/test/TEST-*.xml"/>
</fileset>
</copy>
It seems that globbing in isn't very straightforward and the Ant task preserves the directory name. What's the best way to do this?

Example as requested:
<mkdir dir="build/test"/>
<copy todir="build/test">
<fileset dir=".">
<include name="*/build/test/TEST-*.xml"/>
</fileset>
<flattenmapper/>
</copy>

<groovy>
new File('build/test').mkdirs()
new AntBuilder().fileScanner {
fileset(dir:'.', includes:'*/build/test/TEST-*.xml')
}.each {
"ln ${it} build/test".execute()
}
</groovy>

Related

How can I use ant <exec> to execute commands on Windchill?

Need to run this below command in the Ant exec tag.
windchill ext.cummins.securityLabel.CumminsLoadAgreement -d
%WT_HOME%/loadFiles/ext/cummins/Agreements/AgreementList/Agreement_Loader.xlsx -u wcadmin -p wcadmin
You can make use of Java Task in your ant script to perform this.
Use the below script
<java classname="ext.cummins.securityLabel.CumminsLoadAgreement" fork="true">
<arg value="${username}"/>
<arg value="${password}"/>
<arg value="-d"/>
<arg path="${Your_Custom_Directory}/${Custom_file}"/>
</java>
In a your ant xml file, define a ant target with the tag , the path for Windchill Home is accessible with the variable ${env.WT_HOME}
<project name="YourProjectName" default="YourTargetName" basedir=".">
<target name="YourTargetName">
<exec executable="windchill" dir="." failonerror="true">
<arg line="ext.cummins.securityLabel.CumminsLoadAgreement -d ${env.WT_HOME}/loadFiles/ext/cummins/Agreements/AgreementList/Agreement_Loader.xlsx -u wcadmin -p wcadmin" />
</exec>
</target>
</project>
From a windchill shell you can then run the target as "usual":
ant -f yourFile.xml YourTargetName
Tipp: if you name your ant file build.xml, you even do not need to specify it as parameter.

Ant-javac doesn't see dependencies from Gradle

I'm trying to migrate from ant to gradle. First phase of this is to move all dependecies to gradle.build and still build war via ant.
In ant building task looks like that:
<fileset id="project-libraries" dir="${project.libs.path}">
<include name="*jar"/>
</fileset>
<path id="master-classpath">
<fileset refid="project-libraries"/>
<fileset refid="tomcat"/>
<fileset refid="hibernate-tools"/>
<fileset refid="findbug"/>
<pathelement path="${build.dir}"/>
</path>
<target name="build" description="Build the application">
<javac destdir="${build.dir}" target="${javac.version}" source="${javac.version}" nowarn="true" deprecation="false" optimize="false" failonerror="true" encoding="utf-8" debug="on">
<src refid="src.dir.set"/>
<classpath refid="master-classpath${master-classpath-version}"/>
<compilerarg value="-Xlint:-unchecked"/>
</javac>
</target>
In Gradle I'm importing build.xml with this code:
ant.importBuild('build.xml') { antTargetName ->
'ant_' + antTargetName
}
The problem is that ant task (./gradlew ant_build) doesn't have dependencies from Gradle (dependencies { ... }). How can I put them into classpath (without modifying ant build)?
You can do the following to add the dependencies to the project's AntBuilder instance:
task antClasspathSetter {
doLast {
def antClassLoader = org.apache.tools.ant.Project.class.classLoader
configurations.compile.each { File f ->
antClassLoader.addURL(f.toURI().toURL())
}
}
}
ant_build.dependsOn antClasspathSetter
However, this is a 'hacky' solution.
Using taskdef is a better solution, if the ant build script can be moved to a separate ant task file. In that case, you can do the following:
ant.taskdef(name: 'myAntTask',
classname: 'my.ant.Task',
classpath: configurations.compile.asPath)
I used a copy task to put all of my gradle dependencies into a {libs} folder that I declared on my ant master-classpath.
//add property
<property name="lib.dir" value="${basedir}/lib" /></pre>
//tell ANT to put all jars in folder on classpath
<path id="master-classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
....
</path>
// copy task goes in your build.gradle file
task copyGradleDependenciesInAntFolder(type: Copy) {
from configurations.compile
into 'lib'
}
// make sure to run it before your {ant_build} target
{ant_build}.dependsOn copyGradleDependenciesInAntFolder

Ant Non Recursive Fileset

Here is my directory structure:
module/
a/
foo.php
b/
bar.php
b/
c/
I would like to run a command for each directory under module/ but non recursively, so only these should be included:
a/
b/
c/
If I do this:
<target name="foo">
<apply executable="ls">
<arg value="-l" />
<fileset dir="${basedir}/module/">
</fileset>
</apply>
</target>
This will run recursively for each directory and file under module.
You only want to do this in the first level of directories?
<target name="foo">
<apply executable="ls">
<arg value="-l" />
<dirset dir="${basedir}/module/">
<include name="*"/>
</dirset>
</apply>
</target>
Note the <include>. I'm specifying only the directories immediately under the directory I specified in my <dirset/>. If I said, <include names="**/*"/>, it would specify all directories.
When you are dealing with directories and not files, use <dirset/> and not <fileset/>. <fileset/> is for specifying files. <dirset/> is for specifying directories.

How to locally echo Apply task?

Is it possible to execute an apply on a file set and have ant print the command it is executing?
For example:
<target name="test">
<apply executable="ls" failonerror="true" verbose="true" ignoremissing="false">
<fileset dir=".">
<include name="*.xml" />
</fileset>
<arg line="-la" />
</apply>
</target>
I would like the output to be something close to the following, with the key line being:
[apply] ls -la ./build.xml"
E.g.
Buildfile: /home/abarker/NetBeansProjects/TestProject/build.xml
test:
[apply] ls -la ./build.xml
[apply] -rw-r--r-- 1 abarker abarker 29231 Feb 13 11:29 /home/abarker/NetBeansProjects/TestProject/build.xml
[apply] Applied ls to 1 file and 0 directories.
There are several ideas I have:
You can use the outputproperty parameter. This will give you the output of the command in the <apply> task.
You can use fileset reference instead of an actual fileset.
Like this:
<property name="apply.files.prop" refid='apply.files'/>
<echo>The files you're operating on are "${apply.files.prop}"</echo>
<apply executable="ls" failonerror="true" verbose="true" ignoremissing="false">
<fileset refid="apply.files"/>
<arg line="-la" />
</apply>
You can then look at the fileset reference apply.files to see what files the <apply> task is operating on.
You can always add the -debug and -verbose flag when you run ant. This will print exactly what you want and then some -- then some a whole lot. I wish there was a way to turn verbose mode on and off on a particular task, but I don't know how to do that -- at least an easy way to do that.
For debug purposes - Just replace your own executable with echo. Here is an example of how I do it on Windows machines:
<target name="test">
<apply executable="cmd" failonerror="true" verbose="true" ignoremissing="false">
<fileset dir=".">
<include name="*.xml" />
</fileset>
<arg line="/c" />
<arg line="echo" />
<arg line="ls" />
<arg line="-la" />
</apply>
</target>
Normally when you run ant with -v/-verbose flag, it will print each execution of the command (this also includes exec and apply).

How Ant script execute command for each file

I would like to use ant script set readonly for each file in the directory
but exec doesn't allow filelist:
<target name="readonly">
<exec executable="attrib +r">
<fileset dir="${reset.root.dir}">
<include name="**/*" />
</fileset>
</exec>
</target>
The type doesn't support the
nested "fileset" element.
Try using the apply task instead of exec, it supports <fileset>.

Resources