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><sources></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><srcfileset></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><targetfileset></code> filesets and <code><targetfilelist></code> +filelists. Multiple <code><srcfileset></code> filesets may be specified. </p> <h4>srcfilelist</h4> <p> -The nested <code>srcfilelist</code> element specifies a <a +The nested <code><srcfilelist></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><targetfileset></code> filesets and <code><targetfilelist></code> +filelists. Multiple <code><srcfilelist></code> filelists may be specified. +</p> + +<h4>targets</h4> + +<p>The <code><targets></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><targetfileset></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><srcfileset></code> filesets and <code><sourcefilelist></code> filelists, and if any are older, they are all deleted. -Multiple <code>targetfileset</code> filesets may be specified. +Multiple <code><targetfileset></code> filesets may be specified. </p> <h4>targetfilelist</h4> <p> -The nested <code>targetfilelist</code> element specifies a <a +The nested <code><targetfilelist></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><srcfileset></code> filesets and <code><sourcefilelist></code> filelists, and if any are older, they are all deleted. -Multiple <code>targetfilelist</code> filelists may be specified. +Multiple <code><targetfilelist></code> filelists may be specified. </p> <h3>Examples</h3> -<blockquote> <pre> +<blockquote> <pre> <dependset> <srcfilelist dir = "${dtd.dir}" @@ -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 © 2001,2004-2005 The Apache Software Foundation. +<p align="center">Copyright © 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]