This is a patch for Delete.java and the associated documents, which adds a
failonerror flag. This flag is more than just !quiet; the quiet flag in
delete not only means 'dont fail on errors', it means 'don't even mention
that things went wrong', which is too discrete for me.

I've been using this patch during deployment tasks; sometimes the odd jar is
kept in use (jce.jar in particular); warning of this is useful as we humans
can then intervene but I still want the task to proceed to the end before
attempting recovery actions. (in this case renaming things)

I have tested against files which cant be deleted, but not all the corner
cases which this task can actually bail out on. Some unit tests may be
possible.

-Steve


cvs diff -u Delete.java (in directory 
D:\Java\Apps\jakarta-ant\src\main\org\apache\tools\ant\taskdefs)
Index: Delete.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Delete.java,v
retrieving revision 1.17
diff -u -r1.17 Delete.java
--- Delete.java 2001/03/14 13:02:52     1.17
+++ Delete.java 2001/05/30 04:36:16
@@ -83,28 +83,29 @@
 
     private int verbosity = Project.MSG_VERBOSE;
     private boolean quiet = false;
+    private boolean failonerror = true;
 
     /**
      * Set the name of a single file to be removed.
-     * 
+     *
      * @param file the file to be deleted
      */
     public void setFile(File file) {
         this.file = file;
-    } 
+    }
 
     /**
      * Set the directory from which files are to be deleted
-     * 
+     *
      * @param dir the directory path.
      */
     public void setDir(File dir) {
         this.dir = dir;
-    } 
+    }
 
     /**
      * Used to force listing of all names of deleted files.
-     * 
+     *
      * @param verbose "true" or "on"
      */
     public void setVerbose(boolean verbose) {
@@ -112,21 +113,30 @@
             this.verbosity = Project.MSG_INFO;
         } else {
             this.verbosity = Project.MSG_VERBOSE;
-        } 
-    } 
+        }
+    }
 
     /**
-     * If the file does not exist, do not display a diagnostic 
+     * If the file does not exist, do not display a diagnostic
      * message or modify the exit status to reflect an error.
      * This means that if a file or directory cannot be deleted,
-     * then no error is reported. This setting emulates the 
+     * then no error is reported. This setting emulates the
      * -f option to the Unix "rm" command.
      * Default is false meaning things are "noisy"
      * @param quiet "true" or "on"
      */
     public void setQuiet(boolean quiet) {
         this.quiet = quiet;
-    } 
+    }
+
+    /**
+     * this flag means 'note errors to the output, but keep going'
+     * @param failonerror true or false
+     */
+     public void setFailOnError(boolean failonerror) {
+         this.failonerror=failonerror;
+     }
+
 
     /**
      * Used to delete empty directories.
@@ -141,7 +151,7 @@
     public void addFileset(FileSet set) {
         filesets.addElement(set);
     }
- 
+
     /**
      * add a name entry on the include list
      */
@@ -149,7 +159,7 @@
         usedMatchingTask = true;
         return super.createInclude();
     }
-    
+
     /**
      * add a name entry on the exclude list
      */
@@ -191,7 +201,7 @@
     /**
      * Sets whether default exclusions should be used or not.
      *
-     * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions 
+     * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
      *                           should be used, "false"|"off"|"no" when they
      *                           shouldn't be used.
      */
@@ -204,7 +214,7 @@
      * Sets the name of the file containing the includes patterns.
      *
      * @param includesfile A string containing the filename to fetch
-     * the include patterns from.  
+     * the include patterns from.
      */
     public void setIncludesfile(File includesfile) {
         usedMatchingTask = true;
@@ -215,7 +225,7 @@
      * Sets the name of the file containing the includes patterns.
      *
      * @param excludesfile A string containing the filename to fetch
-     * the include patterns from.  
+     * the include patterns from.
      */
     public void setExcludesfile(File excludesfile) {
         usedMatchingTask = true;
@@ -232,7 +242,7 @@
 
         if (file == null && dir == null && filesets.size() == 0) {
             throw new BuildException("At least one of the file or dir 
attributes, or a fileset element, must be set.");
-        } 
+        }
 
         // delete the single file
         if (file != null) {
@@ -241,11 +251,15 @@
                     log("Directory " + file.getAbsolutePath() + " cannot be 
removed using the file attribute.  Use dir instead.");
                 } else {
                     log("Deleting: " + file.getAbsolutePath());
-  
+
                     if (!file.delete() && !quiet) {
-                        throw new BuildException("Unable to delete file " + 
file.getAbsolutePath());
-                    } 
-                } 
+                        String message="Unable to delete file " + 
file.getAbsolutePath();
+                        if(failonerror)
+                            throw new BuildException(message);
+                        else
+                            log(message,Project.MSG_WARN);
+                    }
+                }
             } else {
                 log("Could not find file " + file.getAbsolutePath() + " to 
delete.", Project.MSG_VERBOSE);
             }
@@ -255,8 +269,8 @@
         if (dir != null && dir.exists() && dir.isDirectory() && 
!usedMatchingTask) {
             /*
                If verbosity is MSG_VERBOSE, that mean we are doing regular 
logging
-               (backwards as that sounds).  In that case, we want to print one 
-               message about deleting the top of the directory tree.  
Otherwise, 
+               (backwards as that sounds).  In that case, we want to print one
+               message about deleting the top of the directory tree.  
Otherwise,
                the removeDir method will handle messages for _all_ directories.
              */
             if (verbosity == Project.MSG_VERBOSE) {
@@ -275,10 +289,10 @@
                 removeFiles(fs.getDir(project), files, dirs);
             } catch (BuildException be) {
                 // directory doesn't exist or is not readable
-                if (!quiet) {
+                if (!quiet && failonerror) {
                     throw be;
                 } else {
-                    log(be.getMessage(), Project.MSG_VERBOSE);
+                    log(be.getMessage(), 
quiet?Project.MSG_VERBOSE:Project.MSG_WARN);
                 }
             }
         }
@@ -292,14 +306,14 @@
                 removeFiles(dir, files, dirs);
             } catch (BuildException be) {
                 // directory doesn't exist or is not readable
-                if (!quiet) {
+                if (!quiet && failonerror) {
                     throw be;
                 } else {
-                    log(be.getMessage(), Project.MSG_VERBOSE);
+                    log(be.getMessage(), 
quiet?Project.MSG_VERBOSE:Project.MSG_WARN);
                 }
             }
         }
-    } 
+    }
 
 //************************************************************************
 //  protected and private methods
@@ -316,16 +330,31 @@
             } else {
                 log("Deleting " + f.getAbsolutePath(), verbosity);
                 if (!f.delete() && !quiet) {
-                    throw new BuildException("Unable to delete file " + 
f.getAbsolutePath());
+                    String message="Unable to delete file " + 
f.getAbsolutePath();
+                    if(failonerror)
+                        throw new BuildException(message);
+                    else
+                        log(message,Project.MSG_WARN);
                 }
             }
         }
         log("Deleting directory " + d.getAbsolutePath(), verbosity);
         if (!d.delete() && !quiet) {
-            throw new BuildException("Unable to delete directory " + 
dir.getAbsolutePath());
+            String message="Unable to delete directory " + 
dir.getAbsolutePath();
+            if(failonerror)
+                throw new BuildException(message);
+            else
+                log(message,Project.MSG_WARN);
         }
     }
 
+    /**
+     * remove an array of files in a directory, and a list of subdirectories
+     * which will only be deleted if 'includeEmpty' is true
+     * @param d directory to work from
+     * @param files array of files to delete; can be of zero length
+     * @param dirs array of directories to delete; can of zero length
+     */
     protected void removeFiles(File d, String[] files, String[] dirs) {
         if (files.length > 0) {
             log("Deleting " + files.length + " files from " + 
d.getAbsolutePath());
@@ -333,7 +362,11 @@
                 File f = new File(d, files[j]);
                 log("Deleting " + f.getAbsolutePath(), verbosity);
                 if (!f.delete() && !quiet) {
-                    throw new BuildException("Unable to delete file " + 
f.getAbsolutePath());
+                    String message="Unable to delete file " + 
f.getAbsolutePath();
+                    if(failonerror)
+                        throw new BuildException(message);
+                    else
+                        log(message,Project.MSG_WARN);
                 }
             }
         }
@@ -346,7 +379,12 @@
                 if (dirFiles == null || dirFiles.length == 0) {
                     log("Deleting " + dir.getAbsolutePath(), verbosity);
                     if (!dir.delete() && !quiet) {
-                        throw new BuildException("Unable to delete directory " 
+ dir.getAbsolutePath());
+                        String message="Unable to delete directory "
+                                + dir.getAbsolutePath();
+                        if(failonerror)
+                            throw new BuildException(message);
+                        else
+                            log(message,Project.MSG_WARN);
                     } else {
                         dirCount++;
                     }
@@ -354,8 +392,8 @@
             }
 
             if (dirCount > 0) {
-                log("Deleted " + dirCount + " director" + 
-                    (dirCount==1 ? "y" : "ies") + 
+                log("Deleted " + dirCount + " director" +
+                    (dirCount==1 ? "y" : "ies") +
                     " from " + d.getAbsolutePath());
             }
         }

cvs diff -u delete.html (in directory 
D:\Java\Apps\jakarta-ant\docs\manual\CoreTasks)
Index: delete.html
===================================================================
RCS file: /home/cvspublic/jakarta-ant/docs/manual/CoreTasks/delete.html,v
retrieving revision 1.2
diff -u -r1.2 delete.html
--- delete.html 2001/02/13 12:31:50     1.2
+++ delete.html 2001/05/30 04:31:42
@@ -47,6 +47,16 @@
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
+    <td valign="top">failonerror</td>
+    <td valign="top">
+    This flag (which is only of relevance if 'quiet' is false),
+    controls whether an error -such as a failure to delete a file-
+    stops the build task, or is merely reported to the screen.
+    The default is &quot;false&quot;
+    </td>
+    <td align="center" valign="top">No</td>
+  </tr>  
+  <tr>
     <td valign="top">includeEmptyDirs</td>
     <td valign="top">Set to &quot;true&quot; to delete empty directories when
     using filesets.  Default is &quot;false&quot;.</td>



Reply via email to