Browse Source

Make <move> use tryHardToDelete under the covers

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1177307 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 13 years ago
parent
commit
cba6d868a8
4 changed files with 39 additions and 8 deletions
  1. +3
    -3
      WHATSNEW
  2. +1
    -1
      manual/Tasks/delete.html
  3. +13
    -0
      manual/Tasks/move.html
  4. +22
    -4
      src/main/org/apache/tools/ant/taskdefs/Move.java

+ 3
- 3
WHATSNEW View File

@@ -118,9 +118,9 @@ Other changes:


* Provide read access to Mkdir.dir. Bugzilla Report 51684. * Provide read access to Mkdir.dir. Bugzilla Report 51684.


* <delete> has a new attribute performGCOnFailedDelete that may -
when set to true - help resolve some problems with deleting empty
directories on NFS shares.
* <delete> and <move> have a new attribute performGCOnFailedDelete
that may - when set to true - help resolve some problems with
deleting empty directories on NFS shares.
Bugzilla Report 45807. Bugzilla Report 45807.


Changes from Ant 1.8.1 TO Ant 1.8.2 Changes from Ant 1.8.1 TO Ant 1.8.2


+ 1
- 1
manual/Tasks/delete.html View File

@@ -174,7 +174,7 @@ in <strong>Directory-based Tasks</strong>, and see the
<tr> <tr>
<td valign="top">performGCOnFailedDelete</td> <td valign="top">performGCOnFailedDelete</td>
<td valign="top"> <td valign="top">
If ant fails to delete a file or directory it will retry the
If Ant fails to delete a file or directory it will retry the
operation once. If this flag is set to true it will perform a operation once. If this flag is set to true it will perform a
garbage collection before retrying the delete.<br/> garbage collection before retrying the delete.<br/>
Setting this flag to true is known to resolve some problems on Setting this flag to true is known to resolve some problems on


+ 13
- 0
manual/Tasks/move.html View File

@@ -168,6 +168,19 @@ there is a directory by the same name in <i>todir</i>, the action will fail.
on separate machines with clocks being out of sync. <em>since Ant on separate machines with clocks being out of sync. <em>since Ant
1.6</em>.</td> 1.6</em>.</td>
</tr> </tr>
<tr>
<td valign="top">performGCOnFailedDelete</td>
<td valign="top">
If Ant fails to delete a file or directory it will retry the
operation once. If this flag is set to true it will perform a
garbage collection before retrying the delete.<br/>
Setting this flag to true is known to resolve some problems on
Windows (where it defaults to true) but also for directory trees
residing on an NFS share.
<em>Since Ant 1.8.3</em></td>
<td align="center" valign="top">No, default &quot;true&quot; on
Windows and &quot;true&quot; on any other OS.</td>
</tr>
</table> </table>
<h3>Parameters specified as nested elements</h3> <h3>Parameters specified as nested elements</h3>
<h4>mapper</h4> <h4>mapper</h4>


+ 22
- 4
src/main/org/apache/tools/ant/taskdefs/Move.java View File

@@ -24,6 +24,7 @@ import java.util.Iterator;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.FilterSet; import org.apache.tools.ant.types.FilterSet;
import org.apache.tools.ant.types.FilterSetCollection; import org.apache.tools.ant.types.FilterSetCollection;
@@ -51,6 +52,8 @@ import org.apache.tools.ant.types.FilterSetCollection;
*/ */
public class Move extends Copy { public class Move extends Copy {


private boolean performGc = Os.isFamily("windows");

/** /**
* Constructor of object. * Constructor of object.
* This sets the forceOverwrite attribute of the Copy parent class * This sets the forceOverwrite attribute of the Copy parent class
@@ -62,6 +65,19 @@ public class Move extends Copy {
setOverwrite(true); setOverwrite(true);
} }


/**
* Whether to perform a garbage collection before retrying a failed delete.
*
* <p>This may be required on Windows (where it is set to true by
* default) but also on other operating systems, for example when
* deleting directories from an NFS share.</p>
*
* @since Ant 1.8.3
*/
public void setPerformGcOnFailedDelete(boolean b) {
performGc = b;
}

/** {@inheritDoc}. */ /** {@inheritDoc}. */
protected void validateAttributes() throws BuildException { protected void validateAttributes() throws BuildException {
if (file != null && file.isDirectory()) { if (file != null && file.isDirectory()) {
@@ -204,7 +220,7 @@ public class Move extends Copy {


if (!moved) { if (!moved) {
copyFile(fromFile, toFile, filtering, overwrite); copyFile(fromFile, toFile, filtering, overwrite);
if (!fromFile.delete()) {
if (!getFileUtils().tryHardToDelete(fromFile, performGc)) {
throw new BuildException("Unable to delete " + "file " throw new BuildException("Unable to delete " + "file "
+ fromFile.getAbsolutePath()); + fromFile.getAbsolutePath());
} }
@@ -293,7 +309,8 @@ public class Move extends Copy {
File f = new File(d, s); File f = new File(d, s);
if (f.isDirectory()) { if (f.isDirectory()) {
deleteDir(f); deleteDir(f);
} else if (deleteFiles && !(f.delete())) {
} else if (deleteFiles && !getFileUtils().tryHardToDelete(f,
performGc)) {
throw new BuildException("Unable to delete file " + f.getAbsolutePath()); throw new BuildException("Unable to delete file " + f.getAbsolutePath());
} else { } else {
throw new BuildException("UNEXPECTED ERROR - The file " throw new BuildException("UNEXPECTED ERROR - The file "
@@ -301,7 +318,7 @@ public class Move extends Copy {
} }
} }
log("Deleting directory " + d.getAbsolutePath(), verbosity); log("Deleting directory " + d.getAbsolutePath(), verbosity);
if (!d.delete()) {
if (!getFileUtils().tryHardToDelete(d, performGc)) {
throw new BuildException("Unable to delete directory " + d.getAbsolutePath()); throw new BuildException("Unable to delete directory " + d.getAbsolutePath());
} }
} }
@@ -355,7 +372,8 @@ public class Move extends Copy {
+ " is a no-op.", Project.MSG_VERBOSE); + " is a no-op.", Project.MSG_VERBOSE);
return true; return true;
} }
if (!(getFileUtils().areSame(sourceFile, destFile) || destFile.delete())) {
if (!(getFileUtils().areSame(sourceFile, destFile)
|| getFileUtils().tryHardToDelete(destFile, performGc))) {
throw new BuildException("Unable to remove existing file " + destFile); throw new BuildException("Unable to remove existing file " + destFile);
} }
} }


Loading…
Cancel
Save