Browse Source

delete + resource collection support

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@280944 13f79535-47bb-0310-9956-ffa450edef68
master
Matthew Jason Benson 20 years ago
parent
commit
ec53cbb02a
7 changed files with 306 additions and 57 deletions
  1. +16
    -13
      docs/manual/CoreTasks/delete.html
  2. +90
    -10
      src/etc/testcases/taskdefs/delete.xml
  3. +44
    -33
      src/main/org/apache/tools/ant/taskdefs/Delete.java
  4. +71
    -0
      src/main/org/apache/tools/ant/types/resources/BCFileSet.java
  5. +48
    -0
      src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java
  6. +21
    -0
      src/main/org/apache/tools/ant/util/FileUtils.java
  7. +16
    -1
      src/testcases/org/apache/tools/ant/taskdefs/DeleteTest.java

+ 16
- 13
docs/manual/CoreTasks/delete.html View File

@@ -12,11 +12,14 @@
<h3>Description</h3>
<p>Deletes a single file, a specified directory and all its files and
subdirectories, or a set of files specified by one or more
<a href="../CoreTypes/fileset.html">FileSet</a>s.
When specifying a set of files, empty directories are <i>not</i> removed by
default.
To remove empty directories, use the <code>includeEmptyDirs</code> attribute.
</p>
<a href="../CoreTypes/resources.html#collection">resource collection</a>s.
The literal implication of <code>&lt;fileset&gt;</code> is that
directories are not included; however the removal of empty directories can
be triggered when using nested filesets by setting the
<code>includeEmptyDirs</code> attribute to <i>true</i>. Note that this
attribute is meaningless in the context of any of the various resource
collection types that <i>do</i> include directories, but that no attempt
will be made to delete non-empty directories in any case.</p>
<p>
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 <strong>Directory-based Tasks</strong>, and see the
filename (if the file exists in the current base directory), a
relative-path filename, or a full-path filename.</td>
<td align="center" valign="middle" rowspan="2">At least one of the two,
unless a <code>&lt;fileset&gt;</code> is specified.</td>
unless nested resource collections are specified
</tr>
<tr>
<td valign="top">dir</td>
@@ -88,7 +91,7 @@ in <strong>Directory-based Tasks</strong>, and see the
</tr>
<tr>
<td valign="top">includes</td>
<td valign="top"><em>Deprecated.</em> Use <code>&lt;fileset&gt;</code>.
<td valign="top"><em>Deprecated.</em> 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 <code>dir</code>.</td>
@@ -96,14 +99,14 @@ in <strong>Directory-based Tasks</strong>, and see the
</tr>
<tr>
<td valign="top">includesfile</td>
<td valign="top"><em>Deprecated.</em> Use <code>&lt;fileset&gt;</code>.
<td valign="top"><em>Deprecated.</em> Use resource collections.
The name of a file. Each line of
this file is taken to be an include pattern.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">excludes</td>
<td valign="top"><em>Deprecated.</em> Use <code>&lt;fileset&gt;</code>.
<td valign="top"><em>Deprecated.</em> 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 <code>dir</code>.
@@ -112,14 +115,14 @@ in <strong>Directory-based Tasks</strong>, and see the
</tr>
<tr>
<td valign="top">excludesfile</td>
<td valign="top"><em>Deprecated.</em> Use <code>&lt;fileset&gt;</code>.
<td valign="top"><em>Deprecated.</em> Use resource collections.
The name of a file. Each line of
this file is taken to be an exclude pattern</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">defaultexcludes</td>
<td valign="top"><em>Deprecated.</em> Use <code>&lt;fileset&gt;</code>.
<td valign="top"><em>Deprecated.</em> Use resource collections.
Whether to use <a href="../dirtasks.html#defaultexcludes">
default excludes.</a></td>
<td align="center" valign="top">No, default &quot;true&quot;</td>
@@ -131,7 +134,7 @@ in <strong>Directory-based Tasks</strong>, and see the
failure to delete a file, this causes the jvm to attempt
to delete the file when the jvm process is terminating.
<em>Since Ant 1.6.2</em></td>
<td align="center" valign="top">No, default &quot;false&quot;.</td>
<td align="center" valign="top">No, default &quot;false&quot;</td>
</tr>
</table>
<h3>Examples</h3>
@@ -158,7 +161,7 @@ and any subdirectories.</p>
</pre>
<p>deletes all files and subdirectories of <code>build</code>, without
<code>build</code> itself.</p>
<hr><p align="center">Copyright &copy; 2000-2002,2004-2005 The Apache Software Foundation.
<hr><p align="center">Copyright &copy; 2000-2002, 2004-2005 The Apache Software Foundation.
All rights Reserved.</p>

</body>


+ 90
- 10
src/etc/testcases/taskdefs/delete.xml View File

@@ -2,27 +2,107 @@

<project name="delete-test" basedir="." default="test1">

<target name="test1">
<delete/>
</target>
<property name="dirname" value="taskdefs.tmp" />
<property name="dir" location="${dirname}" />

<macrodef name="expectabsent">
<sequential>
<fail>
<condition>
<available file="${dir}" />
</condition>
</fail>
</sequential>
</macrodef>

<macrodef name="expectdirsonly">
<sequential>
<fail>
<condition>
<or>
<resourcecount when="greater" count="0">
<fileset refid="fs" />
</resourcecount>
<not>
<resourcecount count="${srcdirs}">
<dirset dir="${dir}" />
</resourcecount>
</not>
</or>
</condition>
</fail>
</sequential>
</macrodef>

<target name="init">
<mkdir dir="taskdefs.tmp" />
<copy todir="taskdefs.tmp">
<fileset dir="." excludes="taskdefs.tmp,taskdefs.tmp/**" />
<resourcecount property="srcdirs">
<dirset dir="${basedir}" />
</resourcecount>

<resourcecount property="srcsize">
<files includes="${basedir}/" />
</resourcecount>

<mkdir dir="${dir}" />

<copy todir="${dir}">
<fileset dir="${basedir}" excludes="${dirname},${dirname}/**" />
</copy>
</target>

<target name="test1">
<delete />
</target>

<target name="test2" depends="init">
<delete file="taskdefs.tmp"/>
<delete file="${dir}" />
<fail>
<condition>
<not>
<resourcecount count="${srcsize}">
<files includes="${dir}/" />
</resourcecount>
</not>
</condition>
</fail>
</target>

<target name="test4" depends="init">
<delete dir="taskdefs.tmp"/>
<delete dir="${dir}" />
<expectabsent />
</target>

<target name="cleanup">
<delete dir="taskdefs.tmp" />
<target name="test5" depends="init">
<delete dir="${dir}" includes="**" />
<expectdirsonly />
</target>

<target name="test6" depends="init">
<delete dir="${dir}" includes="**" includeemptydirs="true" />
<expectabsent />
</target>

<target name="test7" depends="init">
<delete>
<fileset id="fs" dir="${dir}" />
</delete>
<expectdirsonly />
</target>

<target name="test8" depends="init">
<delete includeemptydirs="true">
<fileset dir="${dir}" />
</delete>
<expectabsent />
</target>

<target name="test9" depends="init">
<delete>
<files includes="${dir}/**" />
</delete>
<expectabsent />
</target>

<target name="cleanup" depends="test4" />

</project>

+ 44
- 33
src/main/org/apache/tools/ant/taskdefs/Delete.java View File

@@ -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);
}
}


+ 71
- 0
src/main/org/apache/tools/ant/types/resources/BCFileSet.java View File

@@ -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();
}

}

+ 48
- 0
src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java View File

@@ -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()));
}

}

+ 21
- 0
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -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 <code>file:</code> URI that represents the
* external form of the given pathname.


+ 16
- 1
src/testcases/org/apache/tools/ant/taskdefs/DeleteTest.java View File

@@ -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");
}
}

Loading…
Cancel
Save