diff --git a/docs/manual/CoreTasks/delete.html b/docs/manual/CoreTasks/delete.html index c72da8913..579c82bd2 100644 --- a/docs/manual/CoreTasks/delete.html +++ b/docs/manual/CoreTasks/delete.html @@ -12,11 +12,14 @@

Description

Deletes a single file, a specified directory and all its files and subdirectories, or a set of files specified by one or more -FileSets. -When specifying a set of files, empty directories are not removed by -default. -To remove empty directories, use the includeEmptyDirs attribute. -

+resource collections. +The literal implication of <fileset> is that +directories are not included; however the removal of empty directories can +be triggered when using nested filesets by setting the +includeEmptyDirs attribute to true. Note that this +attribute is meaningless in the context of any of the various resource +collection types that do include directories, but that no attempt +will be made to delete non-empty directories in any case.

If you use this task to delete temporary files created by editors and it doesn't seem to work, read up on the @@ -37,7 +40,7 @@ in Directory-based Tasks, and see the filename (if the file exists in the current base directory), a relative-path filename, or a full-path filename. At least one of the two, - unless a <fileset> is specified. + unless nested resource collections are specified dir @@ -88,7 +91,7 @@ in Directory-based Tasks, and see the includes - Deprecated. Use <fileset>. + Deprecated. Use resource collections. Comma- or space-separated list of patterns of files that must be deleted. All files are relative to the directory specified in dir. @@ -96,14 +99,14 @@ in Directory-based Tasks, and see the includesfile - Deprecated. Use <fileset>. + Deprecated. Use resource collections. The name of a file. Each line of this file is taken to be an include pattern. No excludes - Deprecated. Use <fileset>. + Deprecated. Use resource collections. Comma- or space-separated list of patterns of files that must be excluded from the deletion list. All files are relative to the directory specified in dir. @@ -112,14 +115,14 @@ in Directory-based Tasks, and see the excludesfile - Deprecated. Use <fileset>. + Deprecated. Use resource collections. The name of a file. Each line of this file is taken to be an exclude pattern No defaultexcludes - Deprecated. Use <fileset>. + Deprecated. Use resource collections. Whether to use default excludes. No, default "true" @@ -131,7 +134,7 @@ in Directory-based Tasks, and see the failure to delete a file, this causes the jvm to attempt to delete the file when the jvm process is terminating. Since Ant 1.6.2 - No, default "false". + No, default "false"

Examples

@@ -158,7 +161,7 @@ and any subdirectories.

deletes all files and subdirectories of build, without build itself.

-

Copyright © 2000-2002,2004-2005 The Apache Software Foundation. +


Copyright © 2000-2002, 2004-2005 The Apache Software Foundation. All rights Reserved.

diff --git a/src/etc/testcases/taskdefs/delete.xml b/src/etc/testcases/taskdefs/delete.xml index 9b29d5a2c..7b729bc78 100644 --- a/src/etc/testcases/taskdefs/delete.xml +++ b/src/etc/testcases/taskdefs/delete.xml @@ -2,27 +2,107 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + - + + + + + + + + + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/Delete.java b/src/main/org/apache/tools/ant/taskdefs/Delete.java index 3b233d94f..3a1770f66 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Delete.java +++ b/src/main/org/apache/tools/ant/taskdefs/Delete.java @@ -19,12 +19,21 @@ package org.apache.tools.ant.taskdefs; import java.io.File; import java.util.Vector; +import java.util.Iterator; + import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.condition.Os; +import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.PatternSet; +import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.types.resources.Sort; +import org.apache.tools.ant.types.resources.BCFileSet; +import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.types.resources.comparators.FileSystem; +import org.apache.tools.ant.types.resources.comparators.Reverse; import org.apache.tools.ant.types.selectors.AndSelector; import org.apache.tools.ant.types.selectors.ContainsRegexpSelector; import org.apache.tools.ant.types.selectors.ContainsSelector; @@ -70,6 +79,7 @@ public class Delete extends MatchingTask { private boolean quiet = false; private boolean failonerror = true; private boolean deleteOnExit = false; + private Vector rcs = new Vector(); /** * Set the name of a single file to be removed. @@ -87,6 +97,7 @@ public class Delete extends MatchingTask { */ public void setDir(File dir) { this.dir = dir; + getImplicitFileSet().setDir(dir); } /** @@ -155,6 +166,14 @@ public class Delete extends MatchingTask { filesets.addElement(set); } + /** + * Add an arbitrary ResourceCollection to be deleted. + * @param rc the filesystem-only ResourceCollection. + */ + public void add(ResourceCollection rc) { + rcs.add(rc); + } + /** * add a name entry on the include list * @return a NameEntry object to be configured @@ -442,9 +461,9 @@ public class Delete extends MatchingTask { + "Use a nested fileset element instead."); } - if (file == null && dir == null && filesets.size() == 0) { + if (file == null && dir == null && filesets.size() == 0 && rcs.size() == 0) { throw new BuildException("At least one of the file or dir " - + "attributes, or a fileset element, " + + "attributes, or a nested resource collection, " + "must be set."); } @@ -453,7 +472,6 @@ public class Delete extends MatchingTask { + "set to true", getLocation()); } - // delete the single file if (file != null) { if (file.exists()) { @@ -497,39 +515,32 @@ public class Delete extends MatchingTask { } removeDir(dir); } - - // delete the files in the filesets + Path p = new Path(getProject()); + p.addAll(rcs); for (int i = 0; i < filesets.size(); i++) { - FileSet fs = (FileSet) filesets.elementAt(i); - try { - DirectoryScanner ds = fs.getDirectoryScanner(getProject()); - String[] files = ds.getIncludedFiles(); - String[] dirs = ds.getIncludedDirectories(); - removeFiles(fs.getDir(getProject()), files, dirs); - } catch (BuildException be) { - // directory doesn't exist or is not readable - if (failonerror) { - throw be; - } else { - log(be.getMessage(), - quiet ? Project.MSG_VERBOSE : Project.MSG_WARN); - } - } + FileSet fs = (FileSet) filesets.get(i); + p.add(includeEmpty ? new BCFileSet(fs) : fs); } - - // delete the files from the default fileset if (usedMatchingTask && dir != null) { - try { - DirectoryScanner ds = super.getDirectoryScanner(dir); - String[] files = ds.getIncludedFiles(); - String[] dirs = ds.getIncludedDirectories(); - removeFiles(dir, files, dirs); - } catch (BuildException be) { - // directory doesn't exist or is not readable - if (failonerror) { - throw be; - } else { - log(be.getMessage(), + //add the files from the default fileset: + FileSet implicit = getImplicitFileSet(); + p.add(includeEmpty ? new BCFileSet(implicit) : implicit); + } + // delete the files in the resource collections; sort to files, then dirs + Sort s = new Sort(); + s.add(new Reverse(new FileSystem())); + s.add(p); + for (Iterator iter = s.iterator(); iter.hasNext();) { + FileResource r = (FileResource) iter.next(); + if (!(r.isDirectory()) || r.getFile().list().length == 0) { + log("Deleting " + r, verbosity); + if (!delete(r.getFile())) { + String message = "Unable to delete " + + (r.isDirectory() ? "directory " : "file ") + r; + if (failonerror) { + throw new BuildException(message); + } + log(message, quiet ? Project.MSG_VERBOSE : Project.MSG_WARN); } } diff --git a/src/main/org/apache/tools/ant/types/resources/BCFileSet.java b/src/main/org/apache/tools/ant/types/resources/BCFileSet.java new file mode 100644 index 000000000..05ac2914c --- /dev/null +++ b/src/main/org/apache/tools/ant/types/resources/BCFileSet.java @@ -0,0 +1,71 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tools.ant.types.resources; + +import java.util.Iterator; + +import org.apache.tools.ant.types.FileSet; + +/** + * Utility FileSet that includes directories for backwards-compatibility + * with certain tasks e.g. Delete. + * @since Ant 1.7 + */ +public class BCFileSet extends FileSet { + /** + * Default constructor. + */ + public BCFileSet() { + } + + /** + * Construct a new BCFileSet from the specified FileSet. + * @param fs the FileSet from which to inherit config. + */ + public BCFileSet(FileSet fs) { + super(fs); + } + + /** + * Fulfill the ResourceCollection contract. + * @return an Iterator of Resources. + * @since Ant 1.7 + */ + public Iterator iterator() { + if (isReference()) { + return ((FileSet) getRef(getProject())).iterator(); + } + FileResourceIterator result = new FileResourceIterator(getDir()); + result.addFiles(getDirectoryScanner().getIncludedFiles()); + result.addFiles(getDirectoryScanner().getIncludedDirectories()); + return result; + } + + /** + * Fulfill the ResourceCollection contract. + * @return number of elements as int. + * @since Ant 1.7 + */ + public int size() { + if (isReference()) { + return ((FileSet) getRef(getProject())).size(); + } + return getDirectoryScanner().getIncludedFilesCount() + + getDirectoryScanner().getIncludedDirsCount(); + } + +} diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java b/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java new file mode 100644 index 000000000..9b02f10fa --- /dev/null +++ b/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java @@ -0,0 +1,48 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tools.ant.types.resources.comparators; + +import java.io.File; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.util.FileUtils; + +/** + * Compares filesystem Resources. + * @since Ant 1.7 + */ +public class FileSystem extends ResourceComparator { + private static FileUtils fileUtils = FileUtils.getFileUtils(); + + /** + * Compare two Resources. + * @param foo the first Resource. + * @param bar the second Resource. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + * @throws ClassCastException if either resource is not an instance of FileResource. + */ + protected int resourceCompare(Resource foo, Resource bar) { + File foofile = ((FileResource) foo).getFile(); + File barfile = ((FileResource) bar).getFile(); + return foofile.equals(barfile) ? 0 + : fileUtils.isLeadingPath(foofile, barfile) ? -1 + : fileUtils.normalize(foofile.getAbsolutePath()).compareTo( + fileUtils.normalize(barfile.getAbsolutePath())); + } + +} diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java index 4c6c3b2ab..2d9846c39 100644 --- a/src/main/org/apache/tools/ant/util/FileUtils.java +++ b/src/main/org/apache/tools/ant/util/FileUtils.java @@ -1341,6 +1341,27 @@ public class FileUtils { return (p.startsWith(l)) ? p.substring(l.length()) : p; } + /** + * Learn whether one path "leads" another. + * @param leading The leading path, must not be null, must be absolute. + * @param path The path to remove from, must not be null, must be absolute. + * @return true if path starts with leading; false otherwise. + * @since Ant 1.7 + */ + public boolean isLeadingPath(File leading, File path) { + String l = normalize(leading.getAbsolutePath()).getAbsolutePath(); + String p = normalize(path.getAbsolutePath()).getAbsolutePath(); + if (l.equals(p)) { + return true; + } + // ensure that l ends with a / + // so we never think /foo was a parent directory of /foobar + if (!l.endsWith(File.separator)) { + l += File.separator; + } + return p.startsWith(l); + } + /** * Constructs a file: URI that represents the * external form of the given pathname. diff --git a/src/testcases/org/apache/tools/ant/taskdefs/DeleteTest.java b/src/testcases/org/apache/tools/ant/taskdefs/DeleteTest.java index 3f87944ae..ca5eb39c9 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/DeleteTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/DeleteTest.java @@ -42,8 +42,23 @@ public class DeleteTest extends BuildFileTest { public void test2() { executeTarget("test2"); } - +//where oh where has my test case 3 gone? public void test4() { executeTarget("test4"); } + public void test5() { + executeTarget("test5"); + } + public void test6() { + executeTarget("test6"); + } + public void test7() { + executeTarget("test7"); + } + public void test8() { + executeTarget("test8"); + } + public void test9() { + executeTarget("test9"); + } }