bodewig 01/07/12 05:06:56
Modified: . WHATSNEW
docs/manual coretasklist.html
docs/manual/CoreTasks apply.html
src/main/org/apache/tools/ant/taskdefs ExecuteOn.java
Transform.java
Removed: docs/manual/CoreTasks execon.html
Log:
Make <apply> work really parallel and not parallel on a per fileset basis.
PR: 1763
Merge <apply> and <execon> into a single task (and keep Transform as
an empty class for backwards compatibility at the source level).
Revision Changes Path
1.128 +5 -0 jakarta-ant/WHATSNEW
Index: WHATSNEW
===================================================================
RCS file: /home/cvs/jakarta-ant/WHATSNEW,v
retrieving revision 1.127
retrieving revision 1.128
diff -u -r1.127 -r1.128
--- WHATSNEW 2001/07/12 08:07:13 1.127
+++ WHATSNEW 2001/07/12 12:05:59 1.128
@@ -108,6 +108,8 @@
* New update attribute for <zip> and friends - update an existing
archive instead of creating a new one.
+* <apply> and <execon> have been merged into a single task.
+
Fixed bugs:
-----------
@@ -174,6 +176,9 @@
* <junit> tries to include all necessary classes for the task itself
to the classpath when running in fork mode - doesn't work for JDK 1.1
+
+* <apply> and <execon> do now execute the command only once, if you
+ specify the parallel attribute - instead of once per fileset.
Changes from Ant 1.2 to Ant 1.3
===========================================
1.14 +1 -2 jakarta-ant/docs/manual/coretasklist.html
Index: coretasklist.html
===================================================================
RCS file: /home/cvs/jakarta-ant/docs/manual/coretasklist.html,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- coretasklist.html 2001/07/08 20:30:59 1.13
+++ coretasklist.html 2001/07/12 12:06:10 1.14
@@ -23,7 +23,7 @@
<a href="CoreTasks/ant.html">Ant</a><br>
<a href="CoreTasks/antcall.html">AntCall</a><br>
<a href="CoreTasks/antstructure.html">AntStructure</a><br>
-<a href="CoreTasks/apply.html">Apply</a><br>
+<a href="CoreTasks/apply.html">Apply/<i>ExecOn</i></a><br>
<a href="CoreTasks/available.html">Available</a><br>
<a href="CoreTasks/chmod.html">Chmod</a><br>
<a href="CoreTasks/copy.html">Copy</a><br>
@@ -36,7 +36,6 @@
<a href="CoreTasks/ear.html">Ear</a><br>
<a href="CoreTasks/echo.html">Echo</a><br>
<a href="CoreTasks/exec.html">Exec</a><br>
-<a href="CoreTasks/execon.html">ExecOn</a><br>
<a href="CoreTasks/fail.html">Fail</a><br>
<a href="CoreTasks/filter.html">Filter</a><br>
<a href="CoreTasks/fixcrlf.html">FixCRLF</a><br>
1.6 +61 -14 jakarta-ant/docs/manual/CoreTasks/apply.html
Index: apply.html
===================================================================
RCS file: /home/cvs/jakarta-ant/docs/manual/CoreTasks/apply.html,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apply.html 2001/07/07 14:57:44 1.5
+++ apply.html 2001/07/12 12:06:22 1.6
@@ -7,17 +7,23 @@
<body>
-<h2><a name="apply">Apply</a></h2>
+<h2><a name="apply">Apply/<i>ExecOn</i></a></h2>
+<p><i>The name execon is deprecated and only kept for backwards
+compatibilty.</i></p>
<h3>Description</h3>
<p>Executes a system command. When the <i>os</i> attribute is specified, then
the command is only executed when Ant is run on one of the specified
operating
systems.</p>
<p>The files and/or directories of a number of <a
-href="../CoreTypes/fileset.html">FileSet</a>s are passed as arguments to the
system
-command. The timestamp of each source file is compared to the
-timestamp of a target file which is defined by a nested <a
-href="../CoreTypes/mapper.html">mapper</a> element. At least one fileset and
exactly
-one mapper element are required.</p>
+href="../CoreTypes/fileset.html">FileSet</a>s are passed as arguments
+to the system command.</p>
+<p>If you specify a nested <a
+href="../CoreTypes/mapper.html">mapper</a> and the destdir attribute,
+the timestamp of each source file is compared to the timestamp of a
+target file which is defined by the nested mapper element and searched
+for in the given destdir.</p>
+<p>At least one fileset is required, you must not specify more than
+one mapper.</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -36,7 +42,7 @@
<td valign="top">the directory where the <apply> expects the
target files will be placed by the
command, when it is executed.
</td>
- <td align="center" valign="top">Yes</td>
+ <td align="center" valign="top">Yes, if you specify a nested mapper</td>
</tr>
<tr>
<td valign="top">dir</td>
@@ -68,12 +74,6 @@
<td align="center" valign="top">No</td>
</tr>
<tr>
- <td valign="top">newenvironment</td>
- <td valign="top">Do not propagate old environment when new environment
- variables are specified.</td>
- <td align="center" valign="top">No, default is <i>false</i></td>
- </tr>
- <tr>
<td valign="top">skipemptyfilesets</td>
<td valign="top">Don't run the command, if no source files have
been found or are newer than their corresponding target
@@ -95,6 +95,23 @@
the names of directories are considered.</td>
<td align="center" valign="top">No, default is <i>file</i></td>
</tr>
+ <tr>
+ <td valign="top">newenvironment</td>
+ <td valign="top">Do not propagate old environment when new environment
+ variables are specified.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">vmlauncher</td>
+ <td valign="top">Run command using the Java VM's execution facilities
+ where available. If set to false the underlying OS's shell,
+ either directly or through the antRun scripts, will be used.
+ Under some operating systems, this gives access to facilities
+ not normally available through the VM including, under Windows,
+ being able to execute scripts, rather than their associated
+ interpreter.</td>
+ <td align="center" valign="top">No, default is <i>true</i></td>
+ </tr>
</table>
<h3>Parameters specified as nested elements</h3>
<h4>fileset</h4>
@@ -114,7 +131,9 @@
<p><code><targetfile></code> is similar to
<code><srcfile></code> and marks the position of the target
filename on the command line. If omitted, the target filenames will
-not be added to the command line at all.</p>
+not be added to the command line at all. This element can only be
+specified, if you also define a nested mapper and the destdir
+attribute.</p>
<h4>env</h4>
<p>It is possible to specify environment variables to pass to the
system command via nested <code><env></code> elements. See the
@@ -123,6 +142,34 @@
<b>not</b> passed to the system command if you specify variables using
<code><env></code>.</p>
<h3>Examples</h3>
+<blockquote><pre>
+<apply executable="ls" >
+ <arg value="-l"/>
+ <fileset dir="/tmp">
+ <patternset>
+ <exclude name="**/*.txt"/>
+ </patternset>
+ </fileset>
+ <fileset refid="other.files"/>
+</apply>
+</pre></blockquote>
+<p>invokes <code>ls -l</code>, adding the absolute filenames of all
+files below <code>/tmp</code> not ending in <code>.txt</code> and all
+files of the FileSet with <code>id</code> <code>other.files</code> to
+the command line.</p>
+<blockquote><pre>
+<apply executable="somecommand" parallel="false" >
+ <arg value="arg1"/>
+ <srfile/>
+ <arg value="arg2"/>
+ <fileset dir="/tmp"/>
+</apply>
+</pre></blockquote>
+<p>invokes <code>somecommand arg1 SOURCEFILENAME arg2</code> for each
+file in <code>/tmp</code> replacing SOURCEFILENAME with the absolute
+filename of each file in turn. If <code>parallel</code> had been set
+to true, SOURCEFILENAME would be replaced with the absolute filenames
+of all files separated by spaces.</p>
<blockquote><pre>
<apply executable="cc" dest="src/C"
parallel="false">
<arg value="-c"/>
1.14 +176 -31
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
Index: ExecuteOn.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- ExecuteOn.java 2001/05/22 09:56:10 1.13
+++ ExecuteOn.java 2001/07/12 12:06:42 1.14
@@ -56,7 +56,9 @@
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
+import org.apache.tools.ant.util.*;
+import java.util.Hashtable;
import java.util.Vector;
import java.io.File;
import java.io.IOException;
@@ -74,8 +76,17 @@
protected String type = "file";
protected Commandline.Marker srcFilePos = null;
private boolean skipEmpty = false;
+ protected Commandline.Marker targetFilePos = null;
+ protected Mapper mapperElement = null;
+ protected FileNameMapper mapper = null;
+ protected File destDir = null;
/**
+ * Has <srcfile> been specified before <targetfile>
+ */
+ protected boolean srcIsFirst = true;
+
+ /**
* Adds a set of files (nested fileset attribute).
*/
public void addFileset(FileSet set) {
@@ -104,6 +115,13 @@
}
/**
+ * Set the destination directory.
+ */
+ public void setDest(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
* Marker that indicates where the name of the source file should
* be put on the command line.
*/
@@ -116,18 +134,62 @@
return srcFilePos;
}
+ /**
+ * Marker that indicates where the name of the target file should
+ * be put on the command line.
+ */
+ public Commandline.Marker createTargetfile() {
+ if (targetFilePos != null) {
+ throw new BuildException(taskType + " doesn\'t support multiple
targetfile elements.",
+ location);
+ }
+ targetFilePos = cmdl.createMarker();
+ srcIsFirst = (srcFilePos != null);
+ return targetFilePos;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ location);
+ }
+ mapperElement = new Mapper(project);
+ return mapperElement;
+ }
+
protected void checkConfiguration() {
+ if ("execon".equals(taskName)) {
+ log("!! execon is deprecated. Use apply instead. !!");
+ }
+
super.checkConfiguration();
if (filesets.size() == 0) {
throw new BuildException("no filesets specified", location);
}
+
+ if (targetFilePos != null || mapperElement != null
+ || destDir != null) {
+
+ if (mapperElement == null) {
+ throw new BuildException("no mapper specified", location);
+ }
+ if (mapperElement == null) {
+ throw new BuildException("no dest attribute specified",
+ location);
+ }
+ mapper = mapperElement.getImplementation();
+ }
}
protected void runExec(Execute exe) throws BuildException {
try {
+ Vector fileNames = new Vector();
+ Vector baseDirs = new Vector();
for (int i=0; i<filesets.size(); i++) {
- Vector v = new Vector();
FileSet fs = (FileSet) filesets.elementAt(i);
File base = fs.getDir(project);
DirectoryScanner ds = fs.getDirectoryScanner(project);
@@ -135,36 +197,28 @@
if (!"dir".equals(type)) {
String[] s = getFiles(base, ds);
for (int j=0; j<s.length; j++) {
- v.addElement(s[j]);
+ fileNames.addElement(s[j]);
+ baseDirs.addElement(base);
}
}
if (!"file".equals(type)) {
String[] s = getDirs(base, ds);;
for (int j=0; j<s.length; j++) {
- v.addElement(s[j]);
+ fileNames.addElement(s[j]);
+ baseDirs.addElement(base);
}
}
- if (v.size() == 0 && skipEmpty) {
+ if (fileNames.size() == 0 && skipEmpty) {
log("Skipping fileset for directory "
+ base + ". It is empty.", Project.MSG_INFO);
continue;
}
-
- String[] s = new String[v.size()];
- v.copyInto(s);
-
- int err = -1;
-
- if (parallel) {
- String[] command = getCommandline(s, base);
- log("Executing " + Commandline.toString(command),
- Project.MSG_VERBOSE);
- exe.setCommandline(command);
- runExecute(exe);
- } else {
+ if (!parallel) {
+ String[] s = new String[fileNames.size()];
+ fileNames.copyInto(s);
for (int j=0; j<s.length; j++) {
String[] command = getCommandline(s[j], base);
log("Executing " + Commandline.toString(command),
@@ -172,9 +226,23 @@
exe.setCommandline(command);
runExecute(exe);
}
+ fileNames.removeAllElements();
+ baseDirs.removeAllElements();
}
}
+ if (parallel) {
+ String[] s = new String[fileNames.size()];
+ fileNames.copyInto(s);
+ File[] b = new File[baseDirs.size()];
+ baseDirs.copyInto(b);
+ String[] command = getCommandline(s, b);
+ log("Executing " + Commandline.toString(command),
+ Project.MSG_VERBOSE);
+ exe.setCommandline(command);
+ runExecute(exe);
+ }
+
} catch (IOException e) {
throw new BuildException("Execute failed: " + e, e, location);
} finally {
@@ -189,22 +257,87 @@
* @param srcFiles The filenames to add to the commandline
* @param baseDir filenames are relative to this dir
*/
- protected String[] getCommandline(String[] srcFiles, File baseDir) {
+ protected String[] getCommandline(String[] srcFiles, File[] baseDirs) {
+ Vector targets = new Vector();
+ if (targetFilePos != null) {
+ Hashtable addedFiles = new Hashtable();
+ for (int i=0; i<srcFiles.length; i++) {
+ String[] subTargets = mapper.mapFileName(srcFiles[i]);
+ if (subTargets != null) {
+ for (int j=0; j<subTargets.length; j++) {
+ String name = (new File(destDir,
subTargets[j])).getAbsolutePath();
+ if (!addedFiles.contains(name)) {
+ targets.addElement(name);
+ addedFiles.put(name, name);
+ }
+ }
+ }
+ }
+ }
+ String[] targetFiles = new String[targets.size()];
+ targets.copyInto(targetFiles);
+
String[] orig = cmdl.getCommandline();
- String[] result = new String[orig.length+srcFiles.length];
+ String[] result = new
String[orig.length+srcFiles.length+targetFiles.length];
- int index = orig.length;
+ int srcIndex = orig.length;
if (srcFilePos != null) {
- index = srcFilePos.getPosition();
+ srcIndex = srcFilePos.getPosition();
+ }
+
+ if (targetFilePos != null) {
+ int targetIndex = targetFilePos.getPosition();
+
+ if (srcIndex < targetIndex
+ || (srcIndex == targetIndex && srcIsFirst)) {
+
+ // 0 --> srcIndex
+ System.arraycopy(orig, 0, result, 0, srcIndex);
+
+ // srcIndex --> targetIndex
+ System.arraycopy(orig, srcIndex, result,
+ srcIndex + srcFiles.length,
+ targetIndex - srcIndex);
+
+ // targets are already absolute file names
+ System.arraycopy(targetFiles, 0, result,
+ targetIndex + srcFiles.length,
+ targetFiles.length);
+
+ // targetIndex --> end
+ System.arraycopy(orig, targetIndex, result,
+ targetIndex + srcFiles.length +
targetFiles.length,
+ orig.length - targetIndex);
+ } else {
+ // 0 --> targetIndex
+ System.arraycopy(orig, 0, result, 0, targetIndex);
+
+ // targets are already absolute file names
+ System.arraycopy(targetFiles, 0, result,
+ targetIndex,
+ targetFiles.length);
+
+ // targetIndex --> srcIndex
+ System.arraycopy(orig, targetIndex, result,
+ targetIndex + targetFiles.length,
+ srcIndex - targetIndex);
+
+ // srcIndex --> end
+ System.arraycopy(orig, srcIndex, result,
+ srcIndex + srcFiles.length +
targetFiles.length,
+ orig.length - srcIndex);
+ srcIndex += targetFiles.length;
+ }
+
+ } else { // no targetFilePos
+ System.arraycopy(orig, 0, result, 0, srcIndex);
}
- System.arraycopy(orig, 0, result, 0, index);
+ // fill in source file names
for (int i=0; i < srcFiles.length; i++) {
- result[index+i] = (new File(baseDir,
srcFiles[i])).getAbsolutePath();
+ result[srcIndex+i] =
+ (new File(baseDirs[i], srcFiles[i])).getAbsolutePath();
}
-
- System.arraycopy(orig, index, result, index+srcFiles.length,
- orig.length-index);
return result;
}
@@ -215,23 +348,35 @@
* @param baseDir filename is relative to this dir
*/
protected String[] getCommandline(String srcFile, File baseDir) {
- return getCommandline(new String[] {srcFile}, baseDir);
+ return getCommandline(new String[] {srcFile}, new File[] {baseDir});
}
/**
* Return the list of files from this DirectoryScanner that should
* be included on the command line.
*/
- protected String[] getFiles(File basedir, DirectoryScanner ds) {
- return ds.getIncludedFiles();
+ protected String[] getFiles(File baseDir, DirectoryScanner ds) {
+ if (mapper != null) {
+ SourceFileScanner sfs = new SourceFileScanner(this);
+ return sfs.restrict(ds.getIncludedFiles(), baseDir, destDir,
+ mapper);
+ } else {
+ return ds.getIncludedFiles();
+ }
}
/**
* Return the list of Directories from this DirectoryScanner that
* should be included on the command line.
*/
- protected String[] getDirs(File basedir, DirectoryScanner ds) {
- return ds.getIncludedDirectories();
+ protected String[] getDirs(File baseDir, DirectoryScanner ds) {
+ if (mapper != null) {
+ SourceFileScanner sfs = new SourceFileScanner(this);
+ return sfs.restrict(ds.getIncludedDirectories(), baseDir,
destDir,
+ mapper);
+ } else {
+ return ds.getIncludedDirectories();
+ }
}
/**
1.3 +2 -186
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Transform.java
Index: Transform.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Transform.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Transform.java 2001/01/03 14:18:31 1.2
+++ Transform.java 2001/07/12 12:06:45 1.3
@@ -54,193 +54,9 @@
package org.apache.tools.ant.taskdefs;
-import java.io.File;
-import java.util.Hashtable;
-import java.util.Vector;
-
-import org.apache.tools.ant.*;
-import org.apache.tools.ant.types.*;
-import org.apache.tools.ant.util.*;
-
/**
- * Executes a given command, supplying a set of files as arguments.
+ * Has been merged into ExecuteOn, empty class for backwards compatibility.
*
- * <p>Only those files that are newer than their corresponding target
- * files will be handeled, the rest will be ignored.</p>
- *
* @author <a href="mailto:[EMAIL PROTECTED]">Stefan Bodewig</a>
*/
-public class Transform extends ExecuteOn {
-
- protected Commandline.Marker targetFilePos = null;
- protected Mapper mapperElement = null;
- protected FileNameMapper mapper = null;
- protected File destDir = null;
-
- /**
- * Has <srcfile> been specified before <targetfile>
- */
- protected boolean srcIsFirst = true;
-
- /**
- * Set the destination directory.
- */
- public void setDest(File destDir) {
- this.destDir = destDir;
- }
-
- /**
- * Marker that indicates where the name of the target file should
- * be put on the command line.
- */
- public Commandline.Marker createTargetfile() {
- if (targetFilePos != null) {
- throw new BuildException(taskType + " doesn\'t support multiple
targetfile elements.",
- location);
- }
- targetFilePos = cmdl.createMarker();
- srcIsFirst = (srcFilePos != null);
- return targetFilePos;
- }
-
- /**
- * Defines the FileNameMapper to use (nested mapper element).
- */
- public Mapper createMapper() throws BuildException {
- if (mapperElement != null) {
- throw new BuildException("Cannot define more than one mapper",
- location);
- }
- mapperElement = new Mapper(project);
- return mapperElement;
- }
-
- protected void checkConfiguration() {
- super.checkConfiguration();
- if (mapperElement == null) {
- throw new BuildException("no mapper specified", location);
- }
- if (destDir == null) {
- throw new BuildException("no dest attribute specified",
location);
- }
-
- mapper = mapperElement.getImplementation();
- }
-
- /**
- * Return the list of files from this DirectoryScanner that should
- * be included on the command line - i.e. only those that are
- * newer than the corresponding target files.
- */
- protected String[] getFiles(File baseDir, DirectoryScanner ds) {
- SourceFileScanner sfs = new SourceFileScanner(this);
- return sfs.restrict(ds.getIncludedFiles(), baseDir, destDir, mapper);
- }
-
- /**
- * Return the list of Directories from this DirectoryScanner that
- * should be included on the command line - i.e. only those that
- * are newer than the corresponding target files.
- */
- protected String[] getDirs(File baseDir, DirectoryScanner ds) {
- SourceFileScanner sfs = new SourceFileScanner(this);
- return sfs.restrict(ds.getIncludedDirectories(), baseDir, destDir,
- mapper);
- }
-
- /**
- * Construct the command line for parallel execution.
- *
- * @param srcFiles The filenames to add to the commandline
- * @param baseDir filenames are relative to this dir
- */
- protected String[] getCommandline(String[] srcFiles, File baseDir) {
- if (targetFilePos == null) {
- return super.getCommandline(srcFiles, baseDir);
- }
-
- Vector targets = new Vector();
- Hashtable addedFiles = new Hashtable();
- for (int i=0; i<srcFiles.length; i++) {
- String[] subTargets = mapper.mapFileName(srcFiles[i]);
- if (subTargets != null) {
- for (int j=0; j<subTargets.length; j++) {
- String name = (new File(destDir,
subTargets[j])).getAbsolutePath();
- if (!addedFiles.contains(name)) {
- targets.addElement(name);
- addedFiles.put(name, name);
- }
- }
- }
- }
- String[] targetFiles = new String[targets.size()];
- targets.copyInto(targetFiles);
-
- String[] orig = cmdl.getCommandline();
- String[] result = new
String[orig.length+srcFiles.length+targetFiles.length];
-
- int srcIndex = orig.length;
- if (srcFilePos != null) {
- srcIndex = srcFilePos.getPosition();
- }
- int targetIndex = targetFilePos.getPosition();
-
- if (srcIndex < targetIndex || (srcIndex == targetIndex &&
srcIsFirst)) {
- // 0 --> srcIndex
- System.arraycopy(orig, 0, result, 0, srcIndex);
-
- // srcIndex --> targetIndex
- System.arraycopy(orig, srcIndex, result,
- srcIndex + srcFiles.length,
- targetIndex - srcIndex);
-
- // targets are already absolute file names
- System.arraycopy(targetFiles, 0, result,
- targetIndex + srcFiles.length,
- targetFiles.length);
-
- // targetIndex --> end
- System.arraycopy(orig, targetIndex, result,
- targetIndex + srcFiles.length +
targetFiles.length,
- orig.length - targetIndex);
- } else {
- // 0 --> targetIndex
- System.arraycopy(orig, 0, result, 0, targetIndex);
-
- // targets are already absolute file names
- System.arraycopy(targetFiles, 0, result,
- targetIndex,
- targetFiles.length);
-
- // targetIndex --> srcIndex
- System.arraycopy(orig, targetIndex, result,
- targetIndex + targetFiles.length,
- srcIndex - targetIndex);
-
- // srcIndex --> end
- System.arraycopy(orig, srcIndex, result,
- srcIndex + srcFiles.length + targetFiles.length,
- orig.length - srcIndex);
- srcIndex += targetFiles.length;
- }
-
-
- for (int i=0; i < srcFiles.length; i++) {
- result[srcIndex+i] =
- (new File(baseDir, srcFiles[i])).getAbsolutePath();
- }
- return result;
-
- }
-
- /**
- * Construct the command line for serial execution.
- *
- * @param srcFile The filename to add to the commandline
- * @param baseDir filename is relative to this dir
- */
- protected String[] getCommandline(String srcFile, File baseDir) {
- return getCommandline(new String[] {srcFile}, baseDir);
- }
-
-}
+public class Transform extends ExecuteOn {}