ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject svn commit: r727750 - in /ant/core/trunk: WHATSNEW docs/manual/CoreTasks/sync.html src/main/org/apache/tools/ant/taskdefs/Sync.java src/tests/antunit/taskdefs/sync-test.xml
Date Thu, 18 Dec 2008 15:42:27 GMT
Author: bodewig
Date: Thu Dec 18 07:42:27 2008
New Revision: 727750

URL: http://svn.apache.org/viewvc?rev=727750&view=rev
Log:
partial implementation of a new preserveemptydirs attribute for sync's preservintarget.  PR
43159.  Unfortunately DirectorScanner.slowScan doesn't work as expected and I'm running out
of time before a meeting, so I'm commiting it unfinished.

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/docs/manual/CoreTasks/sync.html
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Sync.java
    ant/core/trunk/src/tests/antunit/taskdefs/sync-test.xml

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=727750&r1=727749&r2=727750&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Thu Dec 18 07:42:27 2008
@@ -620,6 +620,10 @@
    build fail if the task didn't do anything.
    Bugzilla Report 21064.
 
+ * <sync>'s <preserveInTarget> has a new attribute that conrols
+   whether empty directories should be kept.
+   Bugzilla Report 43159.
+
 Changes from Ant 1.7.0 TO Ant 1.7.1
 =============================================
 

Modified: ant/core/trunk/docs/manual/CoreTasks/sync.html
URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/sync.html?rev=727750&r1=727749&r2=727750&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/CoreTasks/sync.html (original)
+++ ant/core/trunk/docs/manual/CoreTasks/sync.html Thu Dec 18 07:42:27 2008
@@ -62,7 +62,9 @@
        nested &lt;preserveintarget&gt; element.  If this attribute is
        false (the default) empty directories that only exist in the
        target directory will be removed even if they are matched by
-       the patterns of &lt;preserveintarget&gt;.
+       the patterns of &lt;preserveintarget&gt;.  This can be
+       overridden by &lt;preserveintarget&gt;'s
+       preserveEmptyDirs attribute.
      </td>
      <td valign="top" align="center">No; defaults to false.</td>
   </tr>
@@ -112,6 +114,26 @@
 support the dir attribute and the usedefaultexcludes attribute
 defaults to false.</p>
 
+<h5>Additional Parameters</h5>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">preserveEmptyDirs</td>
+    <td valign="top">Overrules the includeEmptydirs setting for
+      directories matched by this element.  If you want to preserve
+      empty directories that are not in your source directory you can
+      either set the task's includeemptydirs attribute or this one.
+      If the two attribute values conflict, this attribute
+      "wins".</td>
+    <td align="center" valign="top">No, defaults to the value of the
+      task's includeemptydirs attribute</td>
+  </tr>  
+</table>
+
 <h3>Examples</h3>
 
 <blockquote><pre>

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Sync.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Sync.java?rev=727750&r1=727749&r2=727750&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Sync.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Sync.java Thu Dec 18 07:42:27 2008
@@ -22,6 +22,7 @@
 
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -113,17 +114,33 @@
             return; // nope ;-)
         }
 
+        // will hold the directories matched by SyncTarget in reversed
+        // lexicographic order (order is important, that's why we use
+        // a LinkedHashSet
+        Set preservedDirectories = new LinkedHashSet();
+
         // Get rid of all files not listed in the source filesets.
         log("PASS#2: Removing orphan files from " + toDir, Project.MSG_DEBUG);
-        int[] removedFileCount = removeOrphanFiles(allFiles, toDir);
+        int[] removedFileCount = removeOrphanFiles(allFiles, toDir,
+                                                   preservedDirectories);
         logRemovedCount(removedFileCount[0], "dangling director", "y", "ies");
         logRemovedCount(removedFileCount[1], "dangling file", "", "s");
 
         // Get rid of empty directories on the destination side
-        if (!myCopy.getIncludeEmptyDirs()) {
+        if (!myCopy.getIncludeEmptyDirs()
+            || (syncTarget != null
+                && syncTarget.getPreserveEmptyDirs() == Boolean.FALSE)) {
             log("PASS#3: Removing empty directories from " + toDir,
                 Project.MSG_DEBUG);
-            int removedDirCount = removeEmptyDirectories(toDir, false);
+
+            int removedDirCount = 0;
+            if (!myCopy.getIncludeEmptyDirs()) {
+                removedDirCount =
+                    removeEmptyDirectories(toDir, false, preservedDirectories);
+            } else { // must be syncTarget.preserveEmptydirs == FALSE
+                removedDirCount =
+                    removeEmptyDirectories(preservedDirectories);
+            }
             logRemovedCount(removedDirCount, "empty director", "y", "ies");
         }
     }
@@ -155,11 +172,16 @@
      *
      * @param  nonOrphans the table of all non-orphan <code>File</code>s.
      * @param  file the initial file or directory to scan or test.
+     * @param  preservedDirectories will be filled with the directories
+     *         matched by preserveInTarget - if any.  Will not be
+     *         filled unless either preserveEmptyDirs is set or
+     *         includeEmptyDirs is true.
      * @return the number of orphaned files and directories actually removed.
      * Position 0 of the array is the number of orphaned directories.
      * Position 1 of the array is the number or orphaned files.
      */
-    private int[] removeOrphanFiles(Set nonOrphans, File toDir) {
+    private int[] removeOrphanFiles(Set nonOrphans, File toDir,
+                                    Set preservedDirectories) {
         int[] removedCount = new int[] {0, 0};
         String[] excls =
             (String[]) nonOrphans.toArray(new String[nonOrphans.size() + 1]);
@@ -216,11 +238,22 @@
         for (int i = dirs.length - 1; i >= 0; --i) {
             File f = new File(toDir, dirs[i]);
             if (f.list().length < 1) {
-            log("Removing orphan directory: " + f, Project.MSG_DEBUG);
-            f.delete();
-            ++removedCount[0];
+                log("Removing orphan directory: " + f, Project.MSG_DEBUG);
+                f.delete();
+                ++removedCount[0];
             }
         }
+
+        if (syncTarget != null) {
+            if (syncTarget.getPreserveEmptyDirs() != null
+                || myCopy.getIncludeEmptyDirs()) {
+                String[] preservedDirs = ds.getExcludedDirectories();
+                for (int i = preservedDirs.length - 1; i >= 0; --i) {
+                    preservedDirectories.add(new File(toDir, preservedDirs[i]));
+                }
+            }
+        }
+
         return removedCount;
     }
 
@@ -238,17 +271,23 @@
      * @param  dir the root directory to scan for empty directories.
      * @param  removeIfEmpty whether to remove the root directory
      *         itself if it becomes empty.
+     * @param  preservedEmptyDirectories directories matched by
+     *         syncTarget
      * @return the number of empty directories actually removed.
      */
-    private int removeEmptyDirectories(File dir, boolean removeIfEmpty) {
+    private int removeEmptyDirectories(File dir, boolean removeIfEmpty,
+                                       Set preservedEmptyDirectories) {
         int removedCount = 0;
-        if (dir.isDirectory()) {
+        if (!preservedEmptyDirectories.contains(dir) && dir.isDirectory()) {
             File[] children = dir.listFiles();
             for (int i = 0; i < children.length; ++i) {
                 File file = children[i];
                 // Test here again to avoid method call for non-directories!
-                if (file.isDirectory()) {
-                    removedCount += removeEmptyDirectories(file, true);
+                if (!preservedEmptyDirectories.contains(file)
+                    && file.isDirectory()) {
+                    removedCount +=
+                        removeEmptyDirectories(file, true,
+                                               preservedEmptyDirectories);
                 }
             }
             if (children.length > 0) {
@@ -265,6 +304,33 @@
         return removedCount;
     }
 
+    /**
+     * Removes all empty directories preserved by preserveInTarget in
+     * the preserveEmptyDirs == FALSE case.
+     *
+     * <p>Relies on the set to be ordered in reversed lexicographic
+     * order so that directories will be removed depth-first.</p>
+     *
+     * @param  preservedEmptyDirectories directories matched by
+     *         syncTarget
+     * @return the number of empty directories actually removed.
+     *
+     * @since Ant 1.8.0
+     */
+    private int removeEmptyDirectories(Set preservedEmptyDirectories) {
+        int removedCount = 0;
+        for (Iterator iter = preservedEmptyDirectories.iterator();
+             iter.hasNext(); ) {
+            File f = (File) iter.next();
+            String[] s = f.list();
+            if (s == null || s.length == 0) {
+                log("Removing empty directory: " + f, Project.MSG_DEBUG);
+                f.delete();
+                ++removedCount;
+            }
+        }
+        return removedCount;
+    }
 
     //
     // Various copy attributes/subelements of <copy> passed thru to <mycopy>
@@ -438,6 +504,8 @@
      */
     public static class SyncTarget extends AbstractFileSet {
 
+        private Boolean preserveEmptyDirs;
+
         /**
          * Constructor for SyncTarget.
          * This just changes the default value of "defaultexcludes" from
@@ -458,6 +526,25 @@
                                      + "attribute");
         }
 
+        /**
+         * Whether empty directories matched by this fileset should be
+         * preserved.
+         *
+         * @since Ant 1.8.0
+         */
+        public void setPreserveEmptyDirs(boolean b) {
+            preserveEmptyDirs = Boolean.valueOf(b);
+        }
+
+        /**
+         * Whether empty directories matched by this fileset should be
+         * preserved.
+         *
+         * @since Ant 1.8.0
+         */
+        public Boolean getPreserveEmptyDirs() {
+            return preserveEmptyDirs;
+        }
     }
 
     /**

Modified: ant/core/trunk/src/tests/antunit/taskdefs/sync-test.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/antunit/taskdefs/sync-test.xml?rev=727750&r1=727749&r2=727750&view=diff
==============================================================================
--- ant/core/trunk/src/tests/antunit/taskdefs/sync-test.xml (original)
+++ ant/core/trunk/src/tests/antunit/taskdefs/sync-test.xml Thu Dec 18 07:42:27 2008
@@ -56,4 +56,35 @@
     <au:assertFileExists file="${output}/b/baz.txt"/>
     <au:assertFileDoesntExist file="${output}/b/c"/>
   </target>
+
+  <target name="testPreserveEmptyOverridesDefault" depends="setUp">
+
+    <sync todir="${output}">
+      <fileset dir="${input}"/>
+      <preserveintarget preserveEmptyDirs="true">
+        <include name="**/b/**"/>
+      </preserveintarget>
+    </sync>
+
+    <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+    <au:assertFileExists file="${output}/a/foo.txt"/>
+    <au:assertFileExists file="${output}/b/baz.txt"/>
+    <au:assertFileExists file="${output}/b/c"/>
+  </target>
+
+  <target name="xtestPreserveEmptyOverrulesIncludeEmpty" depends="setUp">
+
+    <sync todir="${output}" includeEmptyDirs="true">
+      <fileset dir="${input}"/>
+      <preserveintarget preserveEmptyDirs="false">
+        <include name="**/b/**"/>
+      </preserveintarget>
+    </sync>
+
+    <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+    <au:assertFileExists file="${output}/a/foo.txt"/>
+    <au:assertFileExists file="${output}/b/baz.txt"/>
+    <au:assertFileDoesntExist file="${output}/b/c"/>
+  </target>
+
 </project>



Mime
View raw message