diff --git a/WHATSNEW b/WHATSNEW index e65f11bf5..33130dd29 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -346,6 +346,18 @@ Other changes: that can be used to turn of Microsoft extensions while using the jvc compiler. Bugzilla Report 19826. +* You can now limit the parallelism of and by using the new + maxparallel attribute. + +* With the new addsourcefile attribute, you can make ommit the + source file names from the command line. Bugzilla Report 13654. + +* and now support nested s as well. + Bugzilla Report 15929. + +* and will display a summary if you set the new + verbose attribute to true. Bugzilla Report 19883. + Changes from Ant 1.5.2 to Ant 1.5.3 =================================== diff --git a/build.xml b/build.xml index 807ef94c0..4f654c214 100644 --- a/build.xml +++ b/build.xml @@ -26,6 +26,7 @@ + @@ -963,7 +964,7 @@ + failonerror="${chmod.fail}" maxparallel="${chmod.maxparallel}"/> @@ -1037,7 +1038,7 @@ + failonerror="${chmod.fail}" maxparallel="${chmod.maxparallel}"/> diff --git a/docs/manual/CoreTasks/apply.html b/docs/manual/CoreTasks/apply.html index c43a4247a..1843f11fb 100644 --- a/docs/manual/CoreTasks/apply.html +++ b/docs/manual/CoreTasks/apply.html @@ -15,14 +15,15 @@ compatibility.

the command is only executed when Ant is run on one of the specified operating systems.

The files and/or directories of a number of FileSets are passed as arguments +href="../CoreTypes/fileset.html">FileSets or FileLists are passed as arguments to the system command.

If you specify a nested mapper and the dest 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 dest.

-

At least one fileset is required, and you must not specify more than +

At least one fileset or filelist is required, and you must not specify more than one mapper.

Parameters

@@ -53,7 +54,7 @@ one mapper.

@@ -120,7 +121,8 @@ one mapper.

+ files. Despite its name, this attribute applies to filelists as + well. @@ -158,19 +160,45 @@ one mapper.

false as well. + + + + + + + + + + + + + + +
relative whether the filenames should be passed on the command line as absolute or relative pathnames (relative to the - base directory of the corresponding fileset for source files or + base directory of the corresponding fileset/list for source files or the dest attribute for target files). No, default is false
skipemptyfilesets Don't run the command, if no source files have been found or are newer than their corresponding target - files. No, default is false
No, default is true
maxparallelLimit the amount of parallelism by passing at + most this many sourcefiles at once. Set it to <= 0 for + unlimited. Defaults to unlimited. Since Ant 1.6.No
addsourcefileWhether source file names should be added to the + command automatically. Defaults to true. + Since Ant 1.6.No
verboseWhether to print a summary after execution or not. + Defaults to false. Since Ant 1.6.No

Parameters specified as nested elements

fileset

You can use any number of nested <fileset> elements to define the files for this task and refer to <fileset>s defined elsewhere.

+

filelist

+

Since Ant 1.6

+

You can use any number of nested <filelist> +elements to define the files for this task and refer to +<filelist>s defined elsewhere.

arg

Command line arguments should be specified as nested <arg> elements. See Command line arguments.

srcfile

By default the file names of the source files will be added to the -end of the command line. If you need to place it somewhere different, +end of the command line (unless you set addsourcefile to +false). If you need to place it somewhere different, use a nested <srcfile> element between your <arg> elements to mark the insertion point.

targetfile

diff --git a/docs/manual/CoreTasks/chmod.html b/docs/manual/CoreTasks/chmod.html index cc1aba279..0bfd0bde7 100644 --- a/docs/manual/CoreTasks/chmod.html +++ b/docs/manual/CoreTasks/chmod.html @@ -19,6 +19,10 @@ write patterns.

supports all of FileSet's attributes and nested elements directly. More FileSets can be specified using nested <fileset> elements.

+ +

Starting with Ant 1.6, this task also supports nested filelists.

+

Parameters

@@ -74,6 +78,19 @@ directly. More FileSets can be specified using nested the directories are considered. + + + + + + + + + +
No, default is file
maxparallelLimit the amount of parallelism by passing at + most this many sourcefiles at once. Set it to <= 0 for + unlimited. Defaults to unlimited. Since Ant 1.6.No
verboseWhether to print a summary after execution or not. + Defaults to false. Since Ant 1.6.No

Examples

diff --git a/src/main/org/apache/tools/ant/taskdefs/Chmod.java b/src/main/org/apache/tools/ant/taskdefs/Chmod.java index f8327cb75..eaf329028 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Chmod.java +++ b/src/main/org/apache/tools/ant/taskdefs/Chmod.java @@ -254,6 +254,14 @@ public class Chmod extends ExecuteOn { + " doesn\'t support the skipemptyfileset attribute", getLocation()); } + /** + * @ant.attribute ignore="true" + */ + public void setAddsourcefile(boolean b) { + throw new BuildException(getTaskType() + + " doesn\'t support the addsourcefile attribute", getLocation()); + } + protected boolean isValidOs() { return (Os.isFamily("unix") || Os.isFamily("tandem")) && super.isValidOs(); diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java index 4ee472c22..4c826edb4 100644 --- a/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java +++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java @@ -63,6 +63,7 @@ import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Commandline; import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.types.FileList; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Mapper; import org.apache.tools.ant.util.FileNameMapper; @@ -81,6 +82,7 @@ import org.apache.tools.ant.util.SourceFileScanner; public class ExecuteOn extends ExecTask { protected Vector filesets = new Vector(); + private Vector filelists = new Vector(); private boolean relative = false; private boolean parallel = false; private boolean forwardSlash = false; @@ -91,6 +93,9 @@ public class ExecuteOn extends ExecTask { protected Mapper mapperElement = null; protected FileNameMapper mapper = null; protected File destDir = null; + private int maxParallel = -1; + private boolean addSourceFile = true; + private boolean verbose = false; /** * Has <srcfile> been specified before <targetfile> @@ -104,6 +109,13 @@ public class ExecuteOn extends ExecTask { filesets.addElement(set); } + /** + * Source files to operate upon. + */ + public void addFilelist(FileList list) { + filelists.addElement(list); + } + /** * Whether the filenames should be passed on the command line as * absolute or relative pathnames. Paths are relative to the base @@ -153,6 +165,38 @@ public class ExecuteOn extends ExecTask { this.forwardSlash = forwardSlash; } + /** + * Limit the command line length by passing at maximum this many + * sourcefiles at once to the command. + * + *

Set to <= 0 for unlimited - this is the default.

+ * + * @since Ant 1.6 + */ + public void setMaxParallel(int max) { + maxParallel = max; + } + + /** + * Whether to send the source file name on the command line. + * + *

Defaults to true. + * + * @since Ant 1.6 + */ + public void setAddsourcefile(boolean b) { + addSourceFile = b; + } + + /** + * Whether to print a verbose summary after execution. + * + * @since Ant 1.6 + */ + public void setVerbose(boolean b) { + verbose = b; + } + /** * Marker that indicates where the name of the source file should * be put on the command line. @@ -202,8 +246,9 @@ public class ExecuteOn extends ExecTask { } super.checkConfiguration(); - if (filesets.size() == 0) { - throw new BuildException("no filesets specified", getLocation()); + if (filesets.size() == 0 && filelists.size() == 0) { + throw new BuildException("no filesets and no filelists specified", + getLocation()); } if (targetFilePos != null || mapperElement != null @@ -221,6 +266,9 @@ public class ExecuteOn extends ExecTask { } protected void runExec(Execute exe) throws BuildException { + int totalFiles = 0; + int totalDirs = 0; + boolean haveExecuted = false; try { Vector fileNames = new Vector(); @@ -233,6 +281,7 @@ public class ExecuteOn extends ExecTask { if (!"dir".equals(type)) { String[] s = getFiles(base, ds); for (int j = 0; j < s.length; j++) { + totalFiles++; fileNames.addElement(s[j]); baseDirs.addElement(base); } @@ -241,6 +290,7 @@ public class ExecuteOn extends ExecTask { if (!"file".equals(type)) { String[] s = getDirs(base, ds);; for (int j = 0; j < s.length; j++) { + totalDirs++; fileNames.addElement(s[j]); baseDirs.addElement(base); } @@ -261,6 +311,50 @@ public class ExecuteOn extends ExecTask { Project.MSG_VERBOSE); exe.setCommandline(command); runExecute(exe); + haveExecuted = true; + } + fileNames.removeAllElements(); + baseDirs.removeAllElements(); + } + } + + for (int i = 0; i < filelists.size(); i++) { + FileList list = (FileList) filelists.elementAt(i); + File base = list.getDir(getProject()); + String[] names = list.getFiles(getProject()); + + for (int j = 0; j < names.length; j++) { + File f = new File(base, names[j]); + if ((f.isFile() && !"dir".equals(type)) + || (f.isDirectory() && !"file".equals(type))) { + + if (f.isFile()) { + totalFiles++; + } else { + totalDirs++; + } + + fileNames.addElement(names[j]); + baseDirs.addElement(base); + } + } + + if (fileNames.size() == 0 && skipEmpty) { + log("Skipping filelist for directory " + + base + ". It is empty.", Project.MSG_INFO); + continue; + } + + 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(Commandline.describeCommand(command), + Project.MSG_VERBOSE); + exe.setCommandline(command); + runExecute(exe); + haveExecuted = true; } fileNames.removeAllElements(); baseDirs.removeAllElements(); @@ -268,14 +362,17 @@ public class ExecuteOn extends ExecTask { } if (parallel && (fileNames.size() > 0 || !skipEmpty)) { - String[] s = new String[fileNames.size()]; - fileNames.copyInto(s); - File[] b = new File[baseDirs.size()]; - baseDirs.copyInto(b); - String[] command = getCommandline(s, b); - log(Commandline.describeCommand(command), Project.MSG_VERBOSE); - exe.setCommandline(command); - runExecute(exe); + runParallel(exe, fileNames, baseDirs); + haveExecuted = true; + } + + if (haveExecuted) { + log("Applied " + cmdl.getExecutable() + " to " + + totalFiles + " file" + + (totalFiles != 1 ? "s" : "") + " and " + + totalDirs + " director" + + (totalDirs != 1 ? "ies" : "y") + ".", + verbose ? Project.MSG_INFO : Project.MSG_VERBOSE); } } catch (IOException e) { @@ -321,6 +418,10 @@ public class ExecuteOn extends ExecTask { String[] targetFiles = new String[targets.size()]; targets.copyInto(targetFiles); + if (!addSourceFile) { + srcFiles = new String[0]; + } + String[] orig = cmdl.getCommandline(); String[] result = new String[orig.length + srcFiles.length + targetFiles.length]; @@ -439,6 +540,46 @@ public class ExecuteOn extends ExecTask { } } + /** + * Runs the command in "parallel" mode, making sure that at most + * maxParallel sourcefiles get passed on the command line. + * + * @since Ant 1.6 + */ + protected void runParallel(Execute exe, Vector fileNames, + Vector baseDirs) + throws IOException, BuildException { + String[] s = new String[fileNames.size()]; + fileNames.copyInto(s); + File[] b = new File[baseDirs.size()]; + baseDirs.copyInto(b); + + if (maxParallel <= 0 + || s.length == 0 /* this is skipEmpty == false */) { + String[] command = getCommandline(s, b); + log(Commandline.describeCommand(command), Project.MSG_VERBOSE); + exe.setCommandline(command); + runExecute(exe); + } else { + int stillToDo = fileNames.size(); + int currentOffset = 0; + while (stillToDo > 0) { + int currentAmount = Math.min(stillToDo, maxParallel); + String[] cs = new String[currentAmount]; + System.arraycopy(s, currentOffset, cs, 0, currentAmount); + File[] cb = new File[currentAmount]; + System.arraycopy(b, currentOffset, cb, 0, currentAmount); + String[] command = getCommandline(cs, cb); + log(Commandline.describeCommand(command), Project.MSG_VERBOSE); + exe.setCommandline(command); + runExecute(exe); + + stillToDo -= currentAmount; + currentOffset += currentAmount; + } + } + } + /** * Enumerated attribute with the values "file", "dir" and "both" * for the type attribute.