Hey, following the discussion about 'execFor' functionality I wrote a
trivial extension to the existing exec task definition. With the patch,
the exec task will behave as usual if used as usual. However, if used with
the additional optional attribute 'src' which should be a directory, will
search for files, and will exec a command with attached list of files as
an additional last argument.


Examples:
(*) <exec dir="/tmp" command="ls -l" output="out.txt"/>
will execute effectively as usual
cd /tmp; ls -l


(*) <exec dir="${basedir}" 
      command="jidl --output-dir ${src.dir} --package com.my.idl" 
      src="src/idl" output="out.txt"/>
and if inside ${basedir}/src/idls we have files: a.idl, b.idl, c.txt
will execute effectively:
cd ${basedir}; jidl --output-dir src/main --package com.my.idl \
${basedir}/src/idl/a.idl ${basedir}/src/idl/b.idl ${basedir}/src/idl/c.txt


(*) <exec dir="${basedir}"
      command="jidl --output-dir ${src.dir} --package com.my.idl"
      src="src/idl" output="out.txt">
      <include name="*.idl"/>
    </exec>
and if inside ${basedir}/src/idls we have files: a.idl, b.idl, c.txt
will execute effectively:
cd ${basedir}; jidl --output-dir src/main --package com.my.idl \
${basedir}/src/idl/a.idl ${basedir}/src/idl/b.idl


The patch assumes that the command should be invoked once with the list of
all matching files as last attribute. I cannot find a use of executing
commands in list of files sequentially file after file with unknown order,
but if somebody needs it, the patch can be easily extended (i.e. exec 
task can be easily extended). Maybe there are usefull file/source
processors which can deal with single file only at once...


----
best regards
Mariusz
diff -U 5 -r old/main/org/apache/tools/ant/taskdefs/Exec.java 
new/main/org/apache/tools/ant/taskdefs/Exec.java
--- old/main/org/apache/tools/ant/taskdefs/Exec.java    Sun Apr  2 02:25:07 2000
+++ new/main/org/apache/tools/ant/taskdefs/Exec.java    Thu May  4 15:28:35 2000
@@ -56,32 +56,37 @@
 
 import org.apache.tools.ant.*;
 import java.io.*;
 
 /**
- * Executes a given command if the os platform is appropriate.
+ * Executes a given command if the os platform is appropriate. This task 
conforms to 
+ * all other matching tasks and can take src attribute together with 
include/exclude tags 
+ * for files to be used as arguments of the specified command. 
  *
  * @author [EMAIL PROTECTED]
  * @author [EMAIL PROTECTED]
+ * @author Mariusz Nowostawski (Marni)  
+       <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>
  */
 
-public class Exec extends Task {
+public class Exec extends MatchingTask {
+
     private String os;
     private String out;
-    private File dir;
+    private File dir; //command to be executed in dir
+    private File srcDir; //source directory for files to be used as parameters
     private String command;
 
     private static final int BUFFER_SIZE = 512;
 
     public void execute() throws BuildException {
         run(command);
     }
 
     protected int run(String command) throws BuildException {
-
-        int err = -1; // assume the worst
-
+        int err = -1;
+        
         // test if os match
         String myos = System.getProperty("os.name");
         project.log("Myos = " + myos, Project.MSG_VERBOSE);
         if ((os != null) && (os.indexOf(myos) < 0)){
             // this command will be executed only on the specified OS
@@ -102,55 +107,84 @@
 
             command = antRun + " " + dir + " " + command;
         }
 
         try {
-            // show the command
-            project.log(command, "exec", Project.MSG_VERBOSE);
+            if(srcDir == null){ //normal exec, no files included as arguments
 
-            // exec command on system runtime
-            Process proc = Runtime.getRuntime().exec(command);
+              project.log(command, "exec", Project.MSG_VERBOSE);
+              err = executeCommand(command);
 
-            PrintWriter fos=null;
-            if( out!=null )  {
-                fos=new PrintWriter( new FileWriter( out ) );
-                project.log("Output redirected to " + out, 
Project.MSG_VERBOSE);
-            }
+            }else{//execFor, executes single command with given file list
 
-            // copy input and error to the output stream
-            StreamPumper inputPumper =
-                new StreamPumper(proc.getInputStream(), "exec", project, fos);
-            StreamPumper errorPumper =
-                new StreamPumper(proc.getErrorStream(), "error", project, fos);
-
-            // starts pumping away the generated output/error
-            inputPumper.start();
-            errorPumper.start();
-
-            // Wait for everything to finish
-            proc.waitFor();
-            inputPumper.join();
-            errorPumper.join();
-            proc.destroy();
-
-            // close the output file if required
-            if (fos != null) fos.close();
-
-            // check its exit value
-            err = proc.exitValue();
-            if (err != 0) {
-                project.log("Result: " + err, "exec", Project.MSG_ERR);
+                DirectoryScanner ds = getDirectoryScanner(srcDir);
+                String[] files = ds.getIncludedFiles();
+                
+                StringBuffer argFiles = new StringBuffer();
+                String filesep = System.getProperty("file.separator");
+                for (int i = 0; i < files.length; i++) {
+                  argFiles.append(" 
").append(srcDir).append(filesep).append(files[i]);
+                }
+                project.log(this.command+" in "+dir.getAbsolutePath()+" for 
"+files.length+" files.", "exec", Project.MSG_INFO);                
+                command += argFiles.toString();
+                project.log(command, "exec", Project.MSG_VERBOSE);
+                err = executeCommand(command);
             }
         } catch (IOException ioe) {
             throw new BuildException("Error exec: " + command );
         } catch (InterruptedException ex) {}
 
         return err;
     }
 
+    /** Executes (forks) a given command, waits for results, and clean up. */
+    private int executeCommand(String command) throws IOException, 
InterruptedException {
+      
+          int err = -1; // assume the worst
+
+          // exec command on system runtime
+          Process proc = Runtime.getRuntime().exec(command);
+          
+          PrintWriter fos=null;
+          if( out!=null )  {
+              fos=new PrintWriter( new FileWriter( out ) );
+              project.log("Output redirected to " + out, Project.MSG_VERBOSE);
+          }
+
+          // copy input and error to the output stream
+          StreamPumper inputPumper =
+            new StreamPumper(proc.getInputStream(), "exec", project, fos);
+          StreamPumper errorPumper =
+            new StreamPumper(proc.getErrorStream(), "error", project, fos);
+          
+          // starts pumping away the generated output/error
+          inputPumper.start();
+          errorPumper.start();
+          
+          // Wait for everything to finish
+          proc.waitFor();
+          inputPumper.join();
+          errorPumper.join();
+          proc.destroy();
+          
+          // close the output file if required
+          if (fos != null) fos.close();
+
+          // check its exit value
+          err = proc.exitValue();
+          if (err != 0) {
+            project.log("Result: " + err, "exec", Project.MSG_ERR);
+          }
+          return err;
+    }
+
     public void setDir(String d) {
         this.dir = project.resolveFile(d);
+    }
+
+    public void setSrc(String d) {
+        this.srcDir = project.resolveFile(d);
     }
 
     public void setOs(String os) {
         this.os = os;
     }

Reply via email to