You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@apache.org on 2005/01/20 14:50:57 UTC

cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs SyncTest.java

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: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs SyncTest.java

Posted by Stefan Bodewig <bo...@apache.org>.
On 20 Jan 2005, <bo...@apache.org> wrote:

>   Allow <sync> to keep files in target even if they are not in any
>   source directories, PR 21832

Two things:

(1) Dominique, could you please try a build of CVS HEAD (doesn't
necessarily have to be any more recent than a month or so) on one
of your larger sync targets to see whether <sync> has slowed down?

I have patched DirectoryScanner to optimize non-pattern matches in
December, so the performance problems you expected should have
been addressed.

(2) Names again.

    <sync todir="${dest}">
      <fileset dir="${src}"/>
      <deletefromtarget>
        <exclude name="e/f"/>
      </deletefromtarget>
    </sync>

<deletefromtarget> is a <fileset> that doesn't allow dir to be
set.  It implicitly contains <exclude>s for all the files that
have been matched by one of the source-<fileset> (everything that
should be there).  It can be used to keep things like logfiles or
config files or similar in you target directory.  Default is to
delete everything not present in any of the source sets.

Now, is <deletefromtarget> a good name?  Is there a better one to
capture what it does?

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org