I want to copy some files to D drive, but in the test environment there is only C drive, so I want to add condition to check if there is D drive first, else copy the file to C.
<if>
<available file="D:\" />
<then>
<copy todir="D:shared/CountrySettings" overwrite="true">
<fileset dir="${dist.CountrySettings.dir}/cfg" />
</copy>
</then>
<else>
<copy todir="C:shared/CountrySettings" overwrite="true">
<fileset dir="${dist.CountrySettings.dir}/cfg" />
</copy>
</else>
</if>
seems not correct, How can fix it?
It looks like the main problem is that you're missing the first slash in your destination directories. D:shared/CountrySettings should be D:/shared/CountrySettings (or D:\shared\CountrySettings since you're on Windows).
I would also highly recommend using native Ant's condition task whenever possible instead of ant-contrib's if/else functionality.
<condition property="dest.dir" value="D:\shared\CountrySettings" else="C:\shared\CountrySettings">
<available file="D:\" />
</condition>
<copy todir="${dest.dir}" overwrite="true">
<fileset dir="${dist.CountrySettings.dir}/cfg" />
</copy>
Related
I need to copy all dml.sql files to inside DB2_List.txt file if DML.sql file is present. But after executing this file i'm getting error like this:
copy doesn't support the nested "if" element.
Please let me know if you have any better idea about the nested loop in Ant.
<available file="DB/DML.sql" property="db.check.present"/>
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
<if>
<equals arg1="${db.check.present}" arg2="true"/>
<then>
<filterchain>
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</then>
</if>
</copy>
It is possible to accomplish what you are after, you just have to approach it quite differently in Ant. Just note that you will need to utilize separate targets.
<target name="db.check">
<available file="DB/DML.sql" property="db.check.present"/>
</target>
<target name="db.copy" depends="db.check" if="db.check.present">
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
<filterchain>
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</copy>
</target>
Take a look at Ant 1.9.1 which supports special if/unless attributes on tags. This might be possible:
<project name="mysterious.moe" basedir="." default="package"
xmlns:if="ant:if"
xmlns:unless="ant:unless"/>
<target name="db.copy">
<available file="DB/DML.sql" property="db.check.present"/>
<copy file="DB/DDL.sql"
tofile="DB2/DB2_List.txt">
<filterchain if:true="db.ceck.present">
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</copy>
<target>
...
</project>
Otherwise, you'll have to use two separate copies. You can't put <if> antcontrib inside tasks. Only around tasks:
<available file="DB/DML.sql" property="db.check.present"/>
<if>
<equals arg1="${db.check.present}" arg2="true"/>
<then>
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
<filterchain>
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</copy>
</then>
<else>
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
</else>
</if>
</copy>
I would like to create a jar file dynamically depending on selected java modules
Here is the part of the ant script which does that.
<property name="modules.selected" value="A,C,F" />
<for list="${modules.selected}" param="module">
<sequential>
<echo>Module chosen ${basedir}/#{module}/src</echo>
<copy todir="${build.dir.src}" overwrite="true">
<fileset dir="${basedir}/#{module}/src">
<include name="**/*.${src.valid.exts}" />
</fileset>
</copy>
</sequential>
</for>
In the above script I am selecting a module and then constructing a directory and copying all the modules present in the directory to a location (build/src).
But I really dont like the logic mentioned above would like to change to include all the required modules in a fileset and use the populated fileset to copy.
Here is the logic I am looking for
<fileset id="required-modules" dir="${basedir}/#{module}/src">
<for list="${modules.selected}" param="module">
<sequential>
<echo>Module chosen ${basedir}/#{module}/src</echo>
<include name="**/*.${src.valid.exts}" />
</sequential>
</for>
</fileset>
<copy todir="${build.dir.src}" overwrite="true">
<fileset refid="required-modules" />
</copy>
Could anyone update the above script to make it work.
At the moment I'm doing this:
<delete dir="${RSA.dir}/file1" />
<copy todir="${RSA.dir}/file1" >
<fileset dir="${CLEARCASE.dir}/file1" />
</copy>
and repeating the same thing for other files - but it takes a long time.
I only want to delete and copy files that have been updated, with their modified date in clearcase later than that in RSA.
How can I do that?
Look into the sync task.
If you want to do it based on file contents, and ignore the timestamp, I think this macro will do that:
<macrodef name="mirror" description="Copy files only if different; remove files that do not exist in dir. This works similiar to robocopy /MIR." >
<attribute name="dir"/>
<attribute name="todir"/>
<sequential>
<copy overwrite="true" todir="#{todir}">
<fileset dir="#{dir}">
<different targetdir="${todir}"/>
</fileset>
</copy>
<delete includeemptydirs="true">
<fileset dir="#todir}">
<present targetdir="${dir}" present="srconly"/>
</fileset>
</delete>
</sequential>
</macrodef>
You need to use a selector on a FileSet. Something like this:
<fileset dir="${your.working.dir}/src/main" includes="**/*.java">
<different targetdir="${clean.clearcase.checkout}/src/main"
ignoreFileTimes="false"
ignoreContents="true" />
</fileset>
That compares your working dir to a clean checkout you have elsewhere, and returns the files whose last modified times have changed. You can use the fileset as the argument for a <delete> or a <copy>.
I am attempting to remove all lines that begin with log if a macrodef attribute is set to prod (example below). I plan on using replaceregexp to remove all lines beginning with log. However, I am not sure how to test if an attribute is set to a specific value, besides using the if task. I would like to not introduce any non-core Ant tasks to perform this, but I can't come up with any other solutions. Do I have any other options besides using the if-task?
Thanks
<macrodef name="setBuildstamp">
<attribute name="platform" />
<sequential>
<if>
<equals arg1="platform" arg2="prod" />
<then>
<replaceregexp match="^log\(.*" value="" />
</then>
</if>
</sequential>
</macrodef>
You should use a reference to a parameter, like this #{platform}.
Also, your replaceregexp task is missing a few parameters.
I think that in your particular case it is better to use linecontainsregexp filter reader. Here is modified code (note negate argument to linecontainsregexp).
<macrodef name="setBuildstamp">
<attribute name="platform" />
<sequential>
<if>
<equals arg1="#{platform}" arg2="prod" />
<then>
<copy todir="dest-dir">
<fileset dir="src-dir"/>
<filterchain>
<linecontainsregexp
regexp="^log\(.*"
negate="true"
/>
</filterchain>
</copy>
</then>
</if>
</sequential>
</macrodef>
They may be a couple of ways to solve this, but none are as straightforward as using the ant-contrib element. I'm not sure if this will get you what you need for your application, but you could try the following:
Using conditional targets. If you can replace your macrodef with a target to call, this may work for you. Note that this will set the property globally, so it might not work for your application.
<target name="default">
<condition property="platformIsProd">
<equals arg1="${platform}" arg2="prod" />
</condition>
<antcall target="do-buildstamp" />
</target>
<target name="do-buildstamp" if="platformIsProd">
<echo>doing prod stuff...</echo>
</target>
Handle the 'else' case. If you need to handle an alternate case, you'll need to provide a few targets...
<target name="default">
<property name="platform" value="prod" />
<antcall target="do-buildstamp" />
</target>
<target name="do-buildstamp">
<condition property="platformIsProd">
<equals arg1="${platform}" arg2="prod" />
</condition>
<antcall target="do-buildstamp-prod" />
<antcall target="do-buildstamp-other" />
</target>
<target name="do-buildstamp-prod" if="platformIsProd">
<echo>doing internal prod stuff...</echo>
</target>
<target name="do-buildstamp-other" unless="platformIsProd">
<echo>doing internal non-prod stuff...</echo>
</target>
Using an external build file. If you need to make multiple calls with different values for your property, you could isolate this in another build file within the same project. This creates a bit of a performance hit, but you would not need the additional library.
in build.xml:
<target name="default">
<ant antfile="buildstamp.xml" target="do-buildstamp" />
<ant antfile="buildstamp.xml" target="do-buildstamp">
<property name="platform" value="prod" />
</ant>
<ant antfile="buildstamp.xml" target="do-buildstamp">
<property name="platform" value="nonprod" />
</ant>
</target>
in buildstamp.xml:
<condition property="platformIsProd">
<equals arg1="${platform}" arg2="prod" />
</condition>
<target name="do-buildstamp">
<antcall target="do-buildstamp-prod" />
<antcall target="do-buildstamp-other" />
</target>
<target name="do-buildstamp-prod" if="platformIsProd">
<echo>doing external prod stuff...</echo>
</target>
<target name="do-buildstamp-other" unless="platformIsProd">
<echo>doing external non-prod stuff...</echo>
</target>
Add ant-contrib to your project. Of course, if you can add a file to your project, the easiest thing would be to just add the ant-contrib.jar file. You could put it under a "tools" folder and pull it in using a taskdef:
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${basedir}/tools/ant-contrib.jar" />
It looks like when you are building your project specifically for your Production environment - you are stripping out code you don't want to run in Production. Thus you are creating a different binary than what will run in your Dev or Testing environment.
How about using an environment variable or property file at run-time instead of build-time which determines whether or not logging happens? This way when you're having trouble in Production and you want to use the same exact binary (instead of determining the revision, checking out the code, rebuilding with a different environment flag) you just re-deploy it to your Dev or Test environment and turn on debugging in a properties file or environment variable?
I am trying to get ant4eclipse to work and I have used ant a bit, but not much above a simple scripting language. We have multiple source folders in our Eclipse projects so the example in the ant4eclipse documentation needs adapting:
Currently I have the following:
<target name="build">
<!-- resolve the eclipse output location -->
<getOutputpath property="classes.dir" workspace="${workspace}" projectName="${project.name}" />
<!-- init output location -->
<delete dir="${classes.dir}" />
<mkdir dir="${classes.dir}" />
<!-- resolve the eclipse source location -->
<getSourcepath pathId="source.path" project="." allowMultipleFolders='true'/>
<!-- read the eclipse classpath -->
<getEclipseClasspath pathId="build.classpath"
workspace="${workspace}" projectName="${project.name}" />
<!-- compile -->
<javac destdir="${classes.dir}" classpathref="build.classpath" verbose="false" encoding="iso-8859-1">
<src refid="source.path" />
</javac>
<!-- copy resources from src to bin -->
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset refid="source.path">
<include name="**/*"/>
<!--
patternset refid="not.java.files"/>
-->
</fileset>
</copy>
</target>
The task runs successfully, but I cannot get the to work - it is supposed to copy all non-java files over too to emulate the behaviour of eclipse.
So, I have a pathId named source.path which contains multiple directories, which I somehow needs to massage into something the copy-task like. I have tried nesting which is not valid, and some other wild guesses.
How can I do this - thanks in advance.
You might consider using pathconvert to build a pattern that fileset includes can work with.
<pathconvert pathsep="/**/*," refid="source.path" property="my_fileset_pattern">
<filtermapper>
<replacestring from="${basedir}/" to="" />
</filtermapper>
</pathconvert>
That will populate ${my_fileset_pattern} with a string like:
1/**/*,2/**/*,3
if source.path consisted of the three directories 1, 2, and 3 under the basedir. We're using the pathsep to insert wildcards that will expand to the full set of files later.
The property can now be used to generate a fileset of all the files. Note that an extra trailing /**/* is needed to expand out the last directory in the set. Exclusion can be applied at this point.
<fileset dir="." id="my_fileset" includes="${my_fileset_pattern}/**/*">
<exclude name="**/*.java" />
</fileset>
The copy of all the non-java files then becomes:
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset refid="my_fileset" />
</copy>
That will copy the source files over retaining the source directory structure under todir. If needed, the flatten attribute of the copy task can be set to instead make all the source files copy directly to todir.
Note that the pathconvert example here is for a unix fileseystem, rather than windows. If something portable is needed, then the file.separator property should be used to build up the pattern:
<property name="wildcard" value="${file.separator}**${file.separator}*" />
<pathconvert pathsep="${wildcard}," refid="source.path" property="my_fileset">
...
You could use the foreach task from the ant-contrib library:
<target name="build">
...
<!-- copy resources from src to bin -->
<foreach target="copy.resources" param="resource.dir">
<path refid="source.path"/>
</foreach>
</target>
<target name="copy.resources">
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset dir="${resource.dir}" exclude="**/*.java">
</copy>
</target>
If your source.path contains file paths as well then you could the if task (also from ant-contrib) to prevent attempting to copy files for a file path, e.g.
<target name="copy.resources">
<if>
<available file="${classes.dir}" type="dir"/>
<then>
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset dir="${resource.dir}" exclude="**/*.java">
</copy>
</then>
</if>
</target>