bodewig 2005/01/20 05:50:57
Modified: src/etc/testcases/taskdefs sync.xml
src/main/org/apache/tools/ant DirectoryScanner.java
src/main/org/apache/tools/ant/taskdefs Sync.java
src/testcases/org/apache/tools/ant/taskdefs SyncTest.java
Log:
Allow <sync> to keep files in target even if they are not in any source
directories, PR 21832
Revision Changes Path
1.2 +14 -0 ant/src/etc/testcases/taskdefs/sync.xml
Index: sync.xml
===================================================================
RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/sync.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sync.xml 9 Nov 2004 10:19:51 -0000 1.1
+++ sync.xml 20 Jan 2005 13:50:56 -0000 1.2
@@ -61,4 +61,18 @@
<fileset dir="${src}" excludes="**/d"/>
</sync>
</target>
+
+ <target name="copynoremove" depends="setup">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}"/>
+ <deletefromtarget>
+ <exclude name="e/f"/>
+ </deletefromtarget>
+ </sync>
+ </target>
+
</project>
1.78 +50 -13 ant/src/main/org/apache/tools/ant/DirectoryScanner.java
Index: DirectoryScanner.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/DirectoryScanner.java,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- DirectoryScanner.java 7 Jan 2005 17:14:42 -0000 1.77
+++ DirectoryScanner.java 20 Jan 2005 13:50:56 -0000 1.78
@@ -584,13 +584,7 @@
} else {
this.includes = new String[includes.length];
for (int i = 0; i < includes.length; i++) {
- String pattern;
- pattern = includes[i].replace('/',
File.separatorChar).replace(
- '\\', File.separatorChar);
- if (pattern.endsWith(File.separator)) {
- pattern += "**";
- }
- this.includes[i] = pattern;
+ this.includes[i] = normalizePattern(includes[i]);
}
}
}
@@ -614,17 +608,60 @@
} else {
this.excludes = new String[excludes.length];
for (int i = 0; i < excludes.length; i++) {
- String pattern;
- pattern = excludes[i].replace('/',
File.separatorChar).replace(
- '\\', File.separatorChar);
- if (pattern.endsWith(File.separator)) {
- pattern += "**";
+ this.excludes[i] = normalizePattern(excludes[i]);
+ }
+ }
+ }
+
+ /**
+ * Adds to the list of exclude patterns to use. All '/' and '\'
+ * characters are replaced by <code>File.separatorChar</code>, so
+ * the separator used need not match
+ * <code>File.separatorChar</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, in which case the
+ * exclude patterns don't get changed at all.
+ *
+ * @since Ant 1.7
+ */
+ public void addExcludes(String[] excludes) {
+ if (excludes != null) {
+ if (this.excludes != null) {
+ String[] tmp = new String[excludes.length
+ + this.excludes.length];
+ System.arraycopy(this.excludes, 0, tmp, 0,
+ this.excludes.length);
+ for (int i = 0; i < excludes.length; i++) {
+ tmp[this.excludes.length + i] =
+ normalizePattern(excludes[i]);
}
- this.excludes[i] = pattern;
+ this.excludes = tmp;
+ } else {
+ setExcludes(excludes);
}
}
}
+ /**
+ * All '/' and '\' characters are replaced by
+ * <code>File.separatorChar</code>, so the separator used need not
+ * match <code>File.separatorChar</code>.
+ *
+ * <p> When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @since Ant 1.7
+ */
+ private static String normalizePattern(String p) {
+ String pattern = p.replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+ if (pattern.endsWith(File.separator)) {
+ pattern += "**";
+ }
+ return pattern;
+ }
/**
* Sets the selectors that will select the filelist.
1.19 +58 -4 ant/src/main/org/apache/tools/ant/taskdefs/Sync.java
Index: Sync.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Sync.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- Sync.java 6 Jan 2005 12:06:41 -0000 1.18
+++ Sync.java 20 Jan 2005 13:50:56 -0000 1.19
@@ -32,6 +32,7 @@
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.AbstractFileSet;
import org.apache.tools.ant.types.FileSet;
/**
@@ -55,6 +56,9 @@
// Same as regular <copy> task... see at end-of-file!
private MyCopy myCopy;
+ // Similar to a fileset, but doesn't allow dir attribute to be set
+ private SyncTarget syncTarget;
+
// Override Task#init
/**
* @see Task#init()
@@ -152,13 +156,21 @@
*/
private int[] removeOrphanFiles(Set nonOrphans, File toDir) {
int[] removedCount = new int[] {0, 0};
- DirectoryScanner ds = new DirectoryScanner();
- ds.setBasedir(toDir);
String[] excls =
(String[]) nonOrphans.toArray(new String[nonOrphans.size() + 1]);
// want to keep toDir itself
excls[nonOrphans.size()] = "";
- ds.setExcludes(excls);
+
+ DirectoryScanner ds = null;
+ if (syncTarget != null) {
+ syncTarget.setTargetDir(toDir);
+ ds = syncTarget.getDirectoryScanner(getProject());
+ } else {
+ ds = new DirectoryScanner();
+ ds.setBasedir(toDir);
+ }
+ ds.addExcludes(excls);
+
ds.scan();
String[] files = ds.getIncludedFiles();
for (int i = 0; i < files.length; i++) {
@@ -289,6 +301,23 @@
}
/**
+ * A container for patterns and selectors that can be used to
+ * specify files that should be kept in the target even if they
+ * are not present in any source directory.
+ *
+ * <p>You must not invoke this method more than once.</p>
+ *
+ * @since Ant 1.7
+ */
+ public void addDeleteFromTarget(SyncTarget s) {
+ if (syncTarget != null) {
+ throw new BuildException("you must not specify multiple "
+ + "deletefromtaget elements.");
+ }
+ syncTarget = s;
+ }
+
+ /**
* Subclass Copy in order to access it's file/dir maps.
*/
public static class MyCopy extends Copy {
@@ -332,6 +361,31 @@
*/
public boolean getIncludeEmptyDirs() {
return includeEmpty;
+ }
+
+ }
+
+ /**
+ * Inner class used to hold exclude patterns and selectors to save
+ * stuff that happens to live in the target directory but should
+ * not get removed.
+ *
+ * @since Ant 1.7
+ */
+ public static class SyncTarget extends AbstractFileSet {
+
+ public SyncTarget() {
+ super();
+ setDefaultexcludes(false);
+ }
+
+ public void setDir(File dir) throws BuildException {
+ throw new BuildException("synctarget doesn't support the dir "
+ + "attribute");
+ }
+
+ private void setTargetDir(File dir) throws BuildException {
+ super.setDir(dir);
}
}
1.3 +10 -1
ant/src/testcases/org/apache/tools/ant/taskdefs/SyncTest.java
Index: SyncTest.java
===================================================================
RCS file:
/home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/SyncTest.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SyncTest.java 9 Nov 2004 10:31:49 -0000 1.2
+++ SyncTest.java 20 Jan 2005 13:50:57 -0000 1.3
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2004-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.
@@ -81,6 +81,15 @@
assertTrue(getFullLog().indexOf("Removing orphan directory:") > -1);
assertDebuglogContaining("NO dangling file to remove from");
assertDebuglogContaining("Removed 2 dangling directories from");
+ }
+
+ public void testCopyNoRemove() {
+ executeTarget("copynoremove");
+ String d = getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsPresent(d);
+ String f = getProject().getProperty("dest") + "/e/f";
+ assertFileIsPresent(f);
+ assertTrue(getFullLog().indexOf("Removing orphan file:") == -1);
}
public void assertFileIsPresent(String f) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]