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