0
votes

User passes a list of files in an XML file, below will be the sample:

<property-bundle name = "abc">
        <action>clean</action>
        <target-location>/vst/property/pog/</target-location>
        <file-name>test1.props</file-name>
        <file-name>test2.props</file-name>
        <file-name>test3.props</file-name>
</property-bundle>

Now based on that action remove, I have to incorporate logic in build.xml to delete the files in the directory , but for that I want to perform a validation only if the file exists then remove or else throw the build failure error. I was able to read the values from the user input XML and takes those files into a file list property

  <property name="file.list" value="test1.props,test2.props,test3.props"/>
  <target name = "clean">
     <delete>
           <fileset dir="${target.location}" includes  = "${file.list}"/>
     </delete>
  </target>

but with the clean target it only validates if the directory exists since it is fileset but does not do the validation if file exists , I read that filelist does validation for file exists but filelist can work with delete.

Since we are using Ant 1.6.5 in our environment I can not use antcontrib , It takes whole lot of process and approvals to upgrade Ant now , Can you please guide me on how it can be achieved with the pure Ant.

5

5 Answers

0
votes

You should be able to just use delete's @failonerror attribute which throws an error if the file cannot be deleted.

<target name = "clean">
  <delete failonerror="true">
     <fileset dir="${target.location}" includes="${file.list}"/>
  </delete>
</target>

The above will delete files and then error when it doesn't find a file, leaving you in a partially deleted state. If you want to avoid partial deletions, you can run another task to check first

<target name="failIfMissing">
  <copy failonerror="true" todir="${temp.directory}">
     <fileset dir="${target.location}" includes="${file.list}"/>
  </copy>
</target>

by attempting to copy to a temporary directory, failing if some of the target files did not exist.

0
votes

It is possible to loop over files with Ant-Contrib Tasks and then it will look something like this:

<target name="clean">
  <foreach target="delete.if.exists" param="fileName">
    <fileset dir="${target.location}" includes="${file.list}"/>
  </foreach>
</target>

<target name="delete.if.exists">
   <delete failonerror="true" file="$fileName"/>
</target>
0
votes

Folks,

Thank you all for your outstanding help & contributions , I have finally achieved this with below

  <target name="validate.file" depends="defineAntContribTasks,validate.dir">
    <echo message=" The value of the filelist is ::::::::::::: ${file.list} :::::::::::::::::: "/>
    <for param="file" list="${file.list}">
      <sequential>
         <if>
            <available file="${target.location}/@{file}"/>
            <then>
                <echo message = "File:::  @{file} ::::is valid , Found in :::${target.location}::: "/>
            </then>
            <else>
                  <fail  message=" File:::  @{file} ::::is not valid ,it is not found in :::${target.location}::: ,plesae recheck and submit again"/>
            </else>
         </if>
      </sequential>
    </for>
  </target>

Thanks again for all of your valuable time and guidance.

0
votes
 <target name="removeUnwantedFiles" description="delete the build destination tree to ensure that it will contain ONLY what is explicitly needed for a build and ONLY what is intended to be release.">
        <delete>
            <fileset dir="${project-home}">
                <includesfile name="${scripts}/excludeJavaFilesForV1.txt"/>
            </fileset>
        </delete>
</target>

This works for me.. hope this helps..

0
votes

Ant is not a programming language and therefore has no native looping mechanism. In the absence of external plugins a trick that can used is an XSL transformation. Process the input XML file into a Ant script which implements the desired operation on each file.

Example

├── build.xml
├── files-process.xsl
├── files.xml          <-- Input listed above
├── test1.props
├── test2.props
└── test3.props

Run the build and the files listed in "files.xml" are deleted:

build:
   [delete] Deleting: /home/mark/tmp/test1.props
   [delete] Deleting: /home/mark/tmp/test2.props
   [delete] Deleting: /home/mark/tmp/test3.props

Run the build a second time and an error is generated:

BUILD FAILED
/home/mark/tmp/build.xml:6: The following error occurred while executing this line:
/home/mark/tmp/build-tmp.xml:4: file not found: test1.props

build.xml

Use the xslt task to generate a temporary Ant script containing the desired file deletion logic:

<project name="demo" default="process-files">

    <target name="process-files">
        <xslt style="files-process.xsl" in="files.xml" out="build-tmp.xml"/>

        <ant antfile="build-tmp.xml"/>
    </target>

    <target name="clean">
        <delete file="build-tmp.xml"/>
    </target>

</project>

files-process.xsl

The following stylesheet generates an Ant script:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <project name="genbuild" default="build">

      <target name="build">
        <xsl:apply-templates select="property-bundle/file-name"/>
      </target>

    </project>
  </xsl:template>

  <xsl:template match="file-name">
    <available file="{.}" property="{generate-id()}.exists"/>
    <fail message="file not found: {.}" unless="{generate-id()}.exists"/>
    <delete file="{.}" verbose="true"/>
  </xsl:template>

</xsl:stylesheet>

build-tmp.xml

To aid readability I have formatted the generated Ant script:

<project name="genbuild" default="build">
  <target name="build">

    <available file="test1.props" property="N65547.exists"/>
    <fail message="file not found: test1.props" unless="N65547.exists"/>
    <delete file="test1.props" verbose="true"/>

    <available file="test2.props" property="N65550.exists"/>
    <fail message="file not found: test2.props" unless="N65550.exists"/>
    <delete file="test2.props" verbose="true"/>

    <available file="test3.props" property="N65553.exists"/>
    <fail message="file not found: test3.props" unless="N65553.exists"/>
    <delete file="test3.props" verbose="true"/>
  </target>
</project>

Note:

  • Properties in Ant are immutable, so I used the XSL generate-id() function to create a unique property name.

Software used

This example was tested with the following software versions:

$ ant -version
Apache Ant version 1.6.5 compiled on June 2 2005

$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)