You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by mb...@apache.org on 2005/09/15 17:39:25 UTC

svn commit: r289262 - in /ant/core/trunk: docs/manual/CoreTasks/dependset.html src/etc/testcases/taskdefs/dependset.xml src/main/org/apache/tools/ant/taskdefs/DependSet.java src/testcases/org/apache/tools/ant/taskdefs/DependSetTest.java

Author: mbenson
Date: Thu Sep 15 08:39:15 2005
New Revision: 289262

URL: http://svn.apache.org/viewcvs?rev=289262&view=rev
Log:
dependset + resource collection support

Modified:
    ant/core/trunk/docs/manual/CoreTasks/dependset.html
    ant/core/trunk/src/etc/testcases/taskdefs/dependset.xml
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/DependSet.java
    ant/core/trunk/src/testcases/org/apache/tools/ant/taskdefs/DependSetTest.java

Modified: ant/core/trunk/docs/manual/CoreTasks/dependset.html
URL: http://svn.apache.org/viewcvs/ant/core/trunk/docs/manual/CoreTasks/dependset.html?rev=289262&r1=289261&r2=289262&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/CoreTasks/dependset.html (original)
+++ ant/core/trunk/docs/manual/CoreTasks/dependset.html Thu Sep 15 08:39:15 2005
@@ -10,21 +10,20 @@
 
 <h2>DependSet</h2>
 
-A task to manage arbitrary dependencies between files.
+A task to manage arbitrary dependencies between resources.
 
 <h3>Description</h3>
 
 <p>
-The dependset task compares a set of source files with a set of target
-files.  If any of the source files is more recent than any of
-the target files, all of the target files are removed.  
+The dependset task compares a set of sources with a set of target
+files.  If any of the sources has been modified more recently than
+any of the target files, all of the target files are removed.
 </p>
 <p>
-Source files and target files are specified via nested <a
-href="../CoreTypes/fileset.html">FileSets</a> and/or nested <a
-href="../CoreTypes/filelist.html">FileLists</a>.  Arbitrarily many
-source and target filesets/filelists may be specified, but at 
-least one filelist/fileset is required for both sources and targets.
+Sources and target files are specified via nested
+<a href="../CoreTypes/resources.html#collection">Resource Collection</a>s;
+sources can be resources of any type, while targets are restricted to files
+only. At least one set of sources and one set of targets is required.
 </p>
 <p>
 Use a FileSet when you want to use wildcard include or exclude
@@ -50,50 +49,64 @@
 
 <h3>Parameters Specified as Nested Elements</h3>
 
+<h4>sources</h4>
+
+<p>The <code>&lt;sources&gt;</code> element is a
+<a href="../CoreTypes/resources.html#union">Union</a> into which
+arbitrary resource collections can be nested. <b>Since Ant 1.7</b>
+</p>
+
 <h4>srcfileset</h4>
 
 <p>
-The nested <code>srcfileset</code> element specifies a <a
+The nested <code>&lt;srcfileset&gt;</code> element specifies a <a
 href="../CoreTypes/fileset.html">FileSet</a>. All files included in
 this fileset will be compared against all files included in all of the
-<code>targetfileset</code> filesets and <code>targetfilelist</code>
-filelists.  Multiple <code>srcfileset</code> filesets may be specified.
+<code>&lt;targetfileset&gt;</code> filesets and <code>&lt;targetfilelist&gt;</code>
+filelists.  Multiple <code>&lt;srcfileset&gt;</code> filesets may be specified.
 </p>
 
 <h4>srcfilelist</h4>
 
 <p>
-The nested <code>srcfilelist</code> element specifies a <a
+The nested <code>&lt;srcfilelist&gt;</code> element specifies a <a
 href="../CoreTypes/filelist.html">FileList</a>. All files included in
 this filelist will be compared against all files included in all of the 
-<code>targetfileset</code> filesets and <code>targetfilelist</code>
-filelists.  Multiple <code>srcfilelist</code> filelists may be specified.
+<code>&lt;targetfileset&gt;</code> filesets and <code>&lt;targetfilelist&gt;</code>
+filelists.  Multiple <code>&lt;srcfilelist&gt;</code> filelists may be specified.
+</p>
+
+<h4>targets</h4>
+
+<p>The <code>&lt;targets&gt;</code> element is a
+<a href="../using.html#path">Path</a> and thus can
+include any filesystem-based resource. <b>Since Ant 1.7</b>
 </p>
 
 <h4>targetfileset</h4>
 
 <p>
-The nested <code>targetfileset</code> element specifies a <a
+The nested <code>&lt;targetfileset&gt;</code> element specifies a <a
 href="../CoreTypes/fileset.html">FileSet</a>.  All files included in
 this fileset will be compared against all files included in all of the
-<code>srcfileset</code> filesets and <code>sourcefilelist</code>
+<code>&lt;srcfileset&gt;</code> filesets and <code>&lt;sourcefilelist&gt;</code>
 filelists, and if any are older, they are all deleted.
-Multiple <code>targetfileset</code> filesets may be specified.
+Multiple <code>&lt;targetfileset&gt;</code> filesets may be specified.
 </p>
 
 <h4>targetfilelist</h4>
 
 <p>
-The nested <code>targetfilelist</code> element specifies a <a
+The nested <code>&lt;targetfilelist&gt;</code> element specifies a <a
 href="../CoreTypes/filelist.html">FileList</a>.  All files included in
 this filelist will be compared against all files included in all of the
-<code>srcfileset</code> filesets and <code>sourcefilelist</code>
+<code>&lt;srcfileset&gt;</code> filesets and <code>&lt;sourcefilelist&gt;</code>
 filelists, and if any are older, they are all deleted.
-Multiple <code>targetfilelist</code> filelists may be specified.
+Multiple <code>&lt;targetfilelist&gt;</code> filelists may be specified.
 </p>
 
 <h3>Examples</h3>
-<blockquote> <pre>    
+<blockquote> <pre>
     &lt;dependset&gt;
        &lt;srcfilelist
            dir   = &quot;${dtd.dir}&quot;
@@ -121,13 +134,13 @@
 </ol>
 
 <p>
-If any of the source files in the above example does not exist, all
-target files will also be removed.  To ignore missing source files instead,
-use filesets instead of filelists for the source files.
+If any of the sources in the above example does not exist, all
+target files will also be removed.  To ignore missing sources instead,
+use filesets instead of filelists for the sources.
 </p>
 
 <hr>
-<p align="center">Copyright &copy; 2001,2004-2005 The Apache Software Foundation.
+<p align="center">Copyright &copy; 2001, 2004-2005 The Apache Software Foundation.
 All rights
 Reserved.</p>
 

Modified: ant/core/trunk/src/etc/testcases/taskdefs/dependset.xml
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/etc/testcases/taskdefs/dependset.xml?rev=289262&r1=289261&r2=289262&view=diff
==============================================================================
--- ant/core/trunk/src/etc/testcases/taskdefs/dependset.xml (original)
+++ ant/core/trunk/src/etc/testcases/taskdefs/dependset.xml Thu Sep 15 08:39:15 2005
@@ -40,7 +40,63 @@
       </condition>
     </fail>
   </target>
-  
+
+  <target name="test6">
+    <touch file="older.tmp"/>
+    <sleep seconds="3" />
+    <touch file="newer.tmp"/>
+    <dependset>
+      <sources>
+        <file file="newer.tmp" />
+      </sources>
+      <targets>
+        <filelist dir="." files="older.tmp" />
+      </targets>
+    </dependset>
+    <fail>
+      <condition>
+        <available file="older.tmp" />
+      </condition>
+    </fail>
+  </target>
+
+  <target name="test7">
+    <touch file="older.tmp"/>
+    <dependset>
+      <sources>
+        <propertyresource name="thereisnosuchproperty" />
+      </sources>
+      <targets>
+        <filelist dir="." files="older.tmp" />
+      </targets>
+    </dependset>
+    <fail>
+      <condition>
+        <available file="older.tmp" />
+      </condition>
+    </fail>
+  </target>
+
+  <target name="test8">
+    <touch file="older.tmp" />
+    <property name="foo" value="bar" />
+    <dependset>
+      <sources>
+        <propertyresource name="foo" />
+      </sources>
+      <targets>
+        <filelist dir="." files="older.tmp" />
+      </targets>
+    </dependset>
+    <fail>
+      <condition>
+        <not>
+          <available file="older.tmp" />
+        </not>
+      </condition>
+    </fail>
+  </target>
+
   <target name="cleanup"> 
     <delete file="test4.tmp"/>
     <delete file="older.tmp"/>

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/DependSet.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/DependSet.java?rev=289262&r1=289261&r2=289262&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/DependSet.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/DependSet.java Thu Sep 15 08:39:15 2005
@@ -1,5 +1,5 @@
 /*
- * Copyright  2001-2005 The Apache Software Foundation
+ * Copyright 2001-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.
@@ -17,15 +17,24 @@
 
 package org.apache.tools.ant.taskdefs;
 
-import java.io.File;
-import java.util.Date;
-import java.util.Enumeration;
-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.types.FileList;
+import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.TimeComparison;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Sort;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.selectors.Not;
+import org.apache.tools.ant.types.resources.selectors.Exists;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.types.resources.comparators.Reverse;
+import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
 import org.apache.tools.ant.util.FileUtils;
 
 /**
@@ -39,36 +48,32 @@
  *
  * nested arguments:
  * <ul>
+ * <li>sources        (resource union describing the source resources to examine)
  * <li>srcfileset     (fileset describing the source files to examine)
  * <li>srcfilelist    (filelist describing the source files to examine)
+ * <li>targets        (path describing the target files to examine)
  * <li>targetfileset  (fileset describing the target files to examine)
  * <li>targetfilelist (filelist describing the target files to examine)
  * </ul>
- * At least one instance of either a fileset or filelist for both source and
- * target are required.
+ * At least one of both source and target entities is required.
  * <p>
- * This task will examine each of the source files against each of the target
- * files. If any target files are out of date with respect to any of the source
- * files, all targets are removed. If any files named in a (src or target)
- * filelist do not exist, all targets are removed.
+ * This task will examine each of the sources against each of the target files. If
+ * any target files are out of date with respect to any of the sources, all targets
+ * are removed. If any sources or targets do not exist, all targets are removed.
  * Hint: If missing files should be ignored, specify them as include patterns
  * in filesets, rather than using filelists.
  * </p><p>
- * This task attempts to optimize speed of dependency checking.  It will stop
- * after the first out of date file is found and remove all targets, rather
- * than exhaustively checking every source vs target combination unnecessarily.
+ * This task attempts to optimize speed of dependency checking
+ * by comparing only the dates of the oldest target file and the newest source.
  * </p><p>
  * Example uses:
  * <ul><li>
- * Record the fact that an XML file must be up to date
- * with respect to its XSD (Schema file), even though the XML file
- * itself includes no reference to its XSD.
+ * Record the fact that an XML file must be up to date with respect to its XSD
+ * (Schema file), even though the XML file itself includes no reference to its XSD.
  * </li><li>
- * Record the fact that an XSL stylesheet includes other
- * sub-stylesheets
+ * Record the fact that an XSL stylesheet includes other sub-stylesheets
  * </li><li>
- * Record the fact that java files must be recompiled if the ant build
- * file changes
+ * Record the fact that java files must be recompiled if the ant build file changes
  * </li></ul>
  *
  * @ant.task category="filesystem"
@@ -76,25 +81,53 @@
  */
 public class DependSet extends MatchingTask {
 
-    private static final FileUtils     FILE_UTILS = FileUtils.getFileUtils();
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+    private static final ResourceSelector NOT_EXISTS = new Not(new Exists());
+    private static final ResourceComparator DATE_ASC
+        = new org.apache.tools.ant.types.resources.comparators.Date();
+    private static final ResourceComparator DATE_DESC = new Reverse(DATE_ASC);
+
+    private static class NonExistent extends Restrict {
+        private NonExistent(ResourceCollection rc) {
+            super.add(rc);
+            super.add(NOT_EXISTS);
+        }
+    }
+    private static class Xest extends Sort {
+        private Xest(ResourceCollection rc, ResourceComparator c) {
+            super.add(c);
+            super.add(rc);
+        }
+    }
+    private static class Oldest extends Xest {
+        private Oldest(ResourceCollection rc) {
+            super(rc, DATE_ASC);
+        }
+    }
+    private static class Newest extends Xest {
+        private Newest(ResourceCollection rc) {
+            super(rc, DATE_DESC);
+        }
+    }
 
-    private Vector sourceFileSets  = new Vector();
-    private Vector sourceFileLists = new Vector();
-    private Vector targetFileSets  = new Vector();
-    private Vector targetFileLists = new Vector();
+    private Union sources = null;
+    private Path targets = null;
 
     /**
-     * Creates a new DependSet Task.
-     **/
-    public DependSet() {
-    } //-- DependSet
+     * Create a nested sources element.
+     * @return a Union instance.
+     */
+    public synchronized Union createSources() {
+        sources = (sources == null) ? new Union() : sources;
+        return sources;
+    }
 
     /**
      * Add a set of source files.
      * @param fs the FileSet to add.
      */
     public void addSrcfileset(FileSet fs) {
-        sourceFileSets.addElement(fs);
+        createSources().add(fs);
     }
 
     /**
@@ -102,7 +135,16 @@
      * @param fl the FileList to add.
      */
     public void addSrcfilelist(FileList fl) {
-        sourceFileLists.addElement(fl);
+        createSources().add(fl);
+    }
+
+    /**
+     * Create a nested targets element.
+     * @return a Union instance.
+     */
+    public synchronized Path createTargets() {
+        targets = (targets == null) ? new Path(getProject()) : targets;
+        return targets;
     }
 
     /**
@@ -110,7 +152,7 @@
      * @param fs the FileSet to add.
      */
     public void addTargetfileset(FileSet fs) {
-        targetFileSets.addElement(fs);
+        createTargets().add(fs);
     }
 
     /**
@@ -118,158 +160,65 @@
      * @param fl the FileList to add.
      */
     public void addTargetfilelist(FileList fl) {
-        targetFileLists.addElement(fl);
+        createTargets().add(fl);
     }
 
     /**
-     * Executes the task.
+     * Execute the task.
      * @throws BuildException if errors occur.
      */
     public void execute() throws BuildException {
-
-        if ((sourceFileSets.size() == 0) && (sourceFileLists.size() == 0)) {
-          throw new BuildException("At least one <srcfileset> or <srcfilelist>"
-                                   + " element must be set");
-        }
-        if ((targetFileSets.size() == 0) && (targetFileLists.size() == 0)) {
-          throw new BuildException("At least one <targetfileset> or"
-                                   + " <targetfilelist> element must be set");
-        }
-        long now = (new Date()).getTime();
-        /*
-          We have to munge the time to allow for the filesystem time
-          granularity.
-        */
-        now += FILE_UTILS.getFileTimestampGranularity();
-
-        // Grab all the target files specified via filesets:
-        Vector allTargets = new Vector();
-        long oldestTargetTime = 0;
-        File oldestTarget = null;
-        Enumeration enumTargetSets = targetFileSets.elements();
-        while (enumTargetSets.hasMoreElements()) {
-
-           FileSet targetFS          = (FileSet) enumTargetSets.nextElement();
-           if (!targetFS.getDir(getProject()).exists()) {
-               // this is the same as if it was empty, no target files found
-               continue;
-           }
-           DirectoryScanner targetDS = targetFS.getDirectoryScanner(getProject());
-           String[] targetFiles      = targetDS.getIncludedFiles();
-
-           for (int i = 0; i < targetFiles.length; i++) {
-
-              File dest = new File(targetFS.getDir(getProject()), targetFiles[i]);
-              allTargets.addElement(dest);
-
-              if (dest.lastModified() > now) {
-                 log("Warning: " + targetFiles[i] + " modified in the future.",
-                     Project.MSG_WARN);
-              }
-              if (oldestTarget == null
-                || dest.lastModified() < oldestTargetTime) {
-                  oldestTargetTime = dest.lastModified();
-                  oldestTarget = dest;
-              }
-           }
-        }
-        // Grab all the target files specified via filelists:
-        boolean upToDate = true;
-        Enumeration enumTargetLists = targetFileLists.elements();
-        while (enumTargetLists.hasMoreElements()) {
-
-           FileList targetFL    = (FileList) enumTargetLists.nextElement();
-           String[] targetFiles = targetFL.getFiles(getProject());
-
-           for (int i = 0; i < targetFiles.length; i++) {
-
-              File dest = new File(targetFL.getDir(getProject()), targetFiles[i]);
-              if (!dest.exists()) {
-                 log(targetFiles[i] + " does not exist.", Project.MSG_VERBOSE);
-                 upToDate = false;
-                 continue;
-              } else {
-                 allTargets.addElement(dest);
-              }
-              if (dest.lastModified() > now) {
-                 log("Warning: " + targetFiles[i] + " modified in the future.",
-                     Project.MSG_WARN);
-              }
-              if (oldestTarget == null
-                  || dest.lastModified() < oldestTargetTime) {
-                  oldestTargetTime = dest.lastModified();
-                  oldestTarget = dest;
-              }
-           }
-        }
-        if (oldestTarget != null) {
-            log(oldestTarget + " is oldest target file", Project.MSG_VERBOSE);
-        } else {
-            // no target files, then we cannot remove any target files and
-            // skip the following tests right away
-            upToDate = false;
+        if (sources == null) {
+          throw new BuildException(
+              "At least one set of source resources must be specified");
+        }
+        if (targets == null) {
+          throw new BuildException(
+              "At least one set of target files must be specified");
+        }
+        //no sources = nothing to compare; no targets = nothing to delete:
+        if (sources.size() > 0 && targets.size() > 0 && !uptodate(sources, targets)) {
+           log("Deleting all target files.", Project.MSG_VERBOSE);
+           Delete delete = new Delete();
+           delete.bindToOwner(this);
+           delete.add(targets);
+           delete.perform();
         }
-        // Check targets vs source files specified via filelists:
-        if (upToDate) {
-           Enumeration enumSourceLists = sourceFileLists.elements();
-           while (upToDate && enumSourceLists.hasMoreElements()) {
-
-              FileList sourceFL    = (FileList) enumSourceLists.nextElement();
-              String[] sourceFiles = sourceFL.getFiles(getProject());
-
-              for (int i = 0; upToDate && i < sourceFiles.length; i++) {
-                 File src = new File(sourceFL.getDir(getProject()), sourceFiles[i]);
-
-                 if (src.lastModified() > now) {
-                    log("Warning: " + sourceFiles[i]
-                        + " modified in the future.", Project.MSG_WARN);
-                 }
-                 if (!src.exists()) {
-                    log(sourceFiles[i] + " does not exist.",
-                        Project.MSG_VERBOSE);
-                    upToDate = false;
-                    break;
-                 }
-                 if (src.lastModified() > oldestTargetTime) {
-                    upToDate = false;
-                    log(oldestTarget + " is out of date with respect to "
-                        + sourceFiles[i], Project.MSG_VERBOSE);
-                 }
-              }
-           }
-        }
-        // Check targets vs source files specified via filesets:
-        if (upToDate) {
-           Enumeration enumSourceSets = sourceFileSets.elements();
-           while (upToDate && enumSourceSets.hasMoreElements()) {
-
-              FileSet sourceFS          = (FileSet) enumSourceSets.nextElement();
-              DirectoryScanner sourceDS = sourceFS.getDirectoryScanner(getProject());
-              String[] sourceFiles      = sourceDS.getIncludedFiles();
-
-              for (int i = 0; upToDate && i < sourceFiles.length; i++) {
-                 File src = new File(sourceFS.getDir(getProject()), sourceFiles[i]);
-
-                 if (src.lastModified() > now) {
-                    log("Warning: " + sourceFiles[i]
-                        + " modified in the future.", Project.MSG_WARN);
-                 }
-                 if (src.lastModified() > oldestTargetTime) {
-                    upToDate = false;
-                    log(oldestTarget + " is out of date with respect to "
-                        + sourceFiles[i], Project.MSG_VERBOSE);
-                 }
-              }
-           }
-        }
-        if (!upToDate) {
-           log("Deleting all target files. ", Project.MSG_VERBOSE);
-           for (Enumeration e = allTargets.elements(); e.hasMoreElements();) {
-              File fileToRemove = (File) e.nextElement();
-              log("Deleting file " + fileToRemove.getAbsolutePath(),
-                  Project.MSG_VERBOSE);
-              fileToRemove.delete();
-           }
+    }
+
+    private boolean uptodate(ResourceCollection src, ResourceCollection target) {
+        org.apache.tools.ant.types.resources.selectors.Date datesel
+            = new org.apache.tools.ant.types.resources.selectors.Date();
+        datesel.setMillis(System.currentTimeMillis());
+        datesel.setWhen(TimeComparison.AFTER);
+        logFuture(targets, datesel);
+
+        int neTargets = new NonExistent(targets).size();
+        if (neTargets > 0) {
+            log(neTargets + " nonexistent targets", Project.MSG_VERBOSE);
+            return false;
+        }
+        FileResource oldestTarget = (FileResource) (new Oldest(targets).iterator().next());
+        log(oldestTarget + " is oldest target file", Project.MSG_VERBOSE);
+
+        logFuture(sources, datesel);
+
+        int neSources = new NonExistent(sources).size();
+        if (neSources > 0) {
+            log(neSources + " nonexistent sources", Project.MSG_VERBOSE);
+            return false;
+        }
+        Resource newestSource = (Resource) (new Newest(sources).iterator().next());
+        log(newestSource.toLongString() + " is newest source", Project.MSG_VERBOSE);
+        return oldestTarget.getLastModified() >= newestSource.getLastModified();
+    }
+
+    private void logFuture(ResourceCollection rc, ResourceSelector rsel) {
+        Restrict r = new Restrict();
+        r.add(rsel);
+        r.add(rc);
+        for (Iterator i = r.iterator(); i.hasNext();) {
+            log("Warning: " + i.next() + " modified in the future.", Project.MSG_WARN);
         }
     }
 }

Modified: ant/core/trunk/src/testcases/org/apache/tools/ant/taskdefs/DependSetTest.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/testcases/org/apache/tools/ant/taskdefs/DependSetTest.java?rev=289262&r1=289261&r2=289262&view=diff
==============================================================================
--- ant/core/trunk/src/testcases/org/apache/tools/ant/taskdefs/DependSetTest.java (original)
+++ ant/core/trunk/src/testcases/org/apache/tools/ant/taskdefs/DependSetTest.java Thu Sep 15 08:39:15 2005
@@ -57,4 +57,13 @@
         executeTarget("test5");
     }
 
+    public void test6() {
+        executeTarget("test6");
+    }
+    public void test7() {
+        executeTarget("test7");
+    }
+    public void test8() {
+        executeTarget("test8");
+    }
 }



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