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]

Reply via email to