Browse Source

Reworked the <exec> and (now so called) <execon> tasks.

Submitted by:	Mariusz Nowostawski <mariusz@marni.otago.ac.nz>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267834 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 25 years ago
parent
commit
61320f305f
4 changed files with 205 additions and 129 deletions
  1. +78
    -46
      src/main/org/apache/tools/ant/taskdefs/ExecTask.java
  2. +67
    -3
      src/main/org/apache/tools/ant/taskdefs/Execute.java
  3. +59
    -79
      src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
  4. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/defaults.properties

+ 78
- 46
src/main/org/apache/tools/ant/taskdefs/ExecTask.java View File

@@ -66,116 +66,140 @@ import java.io.*;
* @author rubys@us.ibm.com
* @author thomas.haas@softwired-inc.com
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
* @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a>
*/
public class ExecTask extends Task {

private String os;
private File out;
private File dir;
private boolean failOnError = false;
protected boolean failOnError = false;
private Integer timeout = null;
private Environment env = new Environment();
private Commandline cmdl = new Commandline();
protected Commandline cmdl = new Commandline();
private FileOutputStream fos = null;

/**
* Timeout in milliseconds after which the process will be killed.
*/
public void setTimeout(Integer value) {
timeout = value;
}

/**
* The command to execute.
*/
public void setExecutable(String value) {
cmdl.setExecutable(value);
}

/**
* The working directory of the process
*/
public void setDir(File d) {
this.dir = d;
}

/**
* Only execute the process if <code>os.name</code> includes this string.
*/
public void setOs(String os) {
this.os = os;
}

/**
* The full commandline to execute, executable + arguments.
*/
public void setCommand(Commandline cmdl) {
this.cmdl = cmdl;
}

/**
* File the output of the process is redirected to.
*/
public void setOutput(File out) {
this.out = out;
}

/**
* Throw a BuildException if process returns non 0.
*/
public void setFailonerror(boolean fail) {
failOnError = fail;
}

/**
* Add a nested env element - an environment variable.
*/
public void addEnv(Environment.Variable var) {
env.addVariable(var);
}

/**
* Add a nested arg element - a command line argument.
*/
public Commandline.Argument createArg() {
return cmdl.createArgument();
}

/**
* Do the work.
*/
public void execute() throws BuildException {
checkConfiguration();
if (isValidOs()) {
runExec(prepareExec());
}
}

/**
* Has the user set all necessary attributes?
*/
protected void checkConfiguration() throws BuildException {
if (cmdl.getExecutable() == null) {
throw new BuildException("no executable specified", location);
}
}

String[] orig = cmdl.getCommandline();
int err = -1; // assume the worst

/**
* Is this the OS the user wanted?
*/
private boolean isValidOs() {
// test if os match
String myos = System.getProperty("os.name");
log("Myos = " + myos, Project.MSG_VERBOSE);
if ((os != null) && (os.indexOf(myos) < 0)){
// this command will be executed only on the specified OS
log("Not found in " + os, Project.MSG_VERBOSE);
return;
return false;
}
return true;
}

/**
* Create an Execute instance with the correct working directory set.
*/
protected Execute prepareExec() throws BuildException {
// default directory to the project's base directory
if (dir == null) dir = project.getBaseDir();
// show the command
log(cmdl.toString(), Project.MSG_VERBOSE);
Execute exe = new Execute(createHandler(), createWatchdog());
exe.setAntRun(project);
exe.setWorkingDirectory(dir);
exe.setEnvironment(env.getVariables());
return exe;
}

if (myos.toLowerCase().indexOf("windows") >= 0) {
if (!dir.equals(project.resolveFile("."))) {
if (myos.toLowerCase().indexOf("nt") >= 0) {
cmdl = new Commandline();
cmdl.setExecutable("cmd");
cmdl.addValue("/c");
cmdl.addValue("cd");
cmdl.addValue(dir.getAbsolutePath());
cmdl.addValue("&&");
cmdl.addLine(orig);
} else {
String ant = project.getProperty("ant.home");
if (ant == null) {
throw new BuildException("Property 'ant.home' not found", location);
}
String antRun = project.resolveFile(ant + "/bin/antRun.bat").toString();
cmdl = new Commandline();
cmdl.setExecutable(antRun);
cmdl.addValue(dir.getAbsolutePath());
cmdl.addLine(orig);
}
}
} else {
String ant = project.getProperty("ant.home");
if (ant == null) throw new BuildException("Property 'ant.home' not found", location);
String antRun = project.resolveFile(ant + "/bin/antRun").toString();

cmdl = new Commandline();
cmdl.setExecutable(antRun);
cmdl.addValue(dir.getAbsolutePath());
cmdl.addLine(orig);
}
/**
* Run the command using the given Execute instance.
*/
protected void runExec(Execute exe) throws BuildException {
int err = -1; // assume the worst

try {
// show the command
log(cmdl.toString(), Project.MSG_VERBOSE);

final Execute exe = new Execute(createHandler(), createWatchdog());
exe.setCommandline(cmdl.getCommandline());
exe.setEnvironment(env.getVariables());
err = exe.execute();
if (err != 0) {
if (failOnError) {
@@ -192,7 +216,9 @@ public class ExecTask extends Task {
}
}


/**
* Create the StreamHandler to use with our Execute instance.
*/
protected ExecuteStreamHandler createHandler() throws BuildException {
if(out!=null) {
try {
@@ -210,11 +236,17 @@ public class ExecTask extends Task {
}
}

/**
* Create the Watchdog to kill a runaway process.
*/
protected ExecuteWatchdog createWatchdog() throws BuildException {
if (timeout == null) return null;
return new ExecuteWatchdog(timeout.intValue());
}

/**
* Flush the output stream - if there is one.
*/
protected void logFlush() {
try {
if (fos != null) fos.close();


+ 67
- 3
src/main/org/apache/tools/ant/taskdefs/Execute.java View File

@@ -54,6 +54,10 @@

package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -74,6 +78,12 @@ public class Execute {
private int exitValue = INVALID;
private ExecuteStreamHandler streamHandler;
private ExecuteWatchdog watchdog;
private File workingDirectory;
private String antRun;

private static String antWorkingDirectory =
(new File((new File(".")).getAbsolutePath())).getParent();
private static String myos = System.getProperty("os.name");

/**
* Creates a new execute object using <code>PumpStreamHandler</code> for
@@ -104,7 +114,31 @@ public class Execute {
* @return the commandline used to create a subprocess
*/
public String[] getCommandline() {
return cmdl;
String[] commandLine = cmdl;

if (workingDirectory != null &&
!antWorkingDirectory.equals(workingDirectory.getAbsolutePath())) {

if (myos.toLowerCase().indexOf("windows") >= 0 &&
myos.toLowerCase().indexOf("nt") >= 0) {

commandLine = new String[cmdl.length+5];
commandLine[0] = "cmd";
commandLine[1] = "/c";
commandLine[2] = "cd";
commandLine[3] = workingDirectory.getAbsolutePath();
commandLine[4] = "&&";
System.arraycopy(cmdl, 0, commandLine, 5, cmdl.length);

} else {
commandLine = new String[cmdl.length+2];
commandLine[0] = antRun;
commandLine[1] = workingDirectory.getAbsolutePath();
System.arraycopy(cmdl, 0, commandLine, 2, cmdl.length);
}
}
return commandLine;
}


@@ -128,14 +162,44 @@ public class Execute {


/**
* Sets the commandline of the subprocess to launch.
* Sets the environment variables for the subprocess to launch.
*
* @param commandline the commandline of the subprocess to launch
* @param commandline array of Strings, each element of which has
* an environment variable settings in format <em>key=value</em>
*/
public void setEnvironment(String[] env) {
this.env = env;
}

/**
* Sets the working directory of the process to execute.
*
* <p>This is emulated using the antRun scripts unless the OS is
* Windows NT in which case a cmd.exe is spawned.
*
* @param wd the working directory of the process.
*/
public void setWorkingDirectory(File wd) {
workingDirectory = wd;
}

/**
* Set the name of the antRun script using the project's value.
*
* @param project the current project.
*/
public void setAntRun(Project project) throws BuildException {
String ant = project.getProperty("ant.home");
if (ant == null) {
throw new BuildException("Property 'ant.home' not found");
}

if (myos.toLowerCase().indexOf("windows") >= 0) {
antRun = project.resolveFile(ant + "/bin/antRun.bat").toString();
} else {
antRun = project.resolveFile(ant + "/bin/antRun").toString();
}
}

/**
* Runs a process defined by the command line and returns its exit status.


+ 59
- 79
src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java View File

@@ -65,14 +65,12 @@ import java.io.IOException;
* Executes a given command, supplying a set of files as arguments.
*
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
* @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a>
*/
public class ExecuteOn extends Task {
public class ExecuteOn extends ExecTask {

private Vector filesets = new Vector();
private Commandline command = new Commandline();
private Environment env = new Environment();
private Integer timeout = null;
private boolean failOnError = false;
private boolean parallel = false;

/**
* Adds a set of files (nested fileset attribute).
@@ -82,97 +80,79 @@ public class ExecuteOn extends Task {
}

/**
* The executable.
* Shall the command work on all specified files in parallel?
*/
public void setExecutable(String exe) {
command.setExecutable(exe);
public void setParallel(boolean parallel) {
this.parallel = parallel;
}

/**
* Adds an argument to the command (nested arg element)
*/
public Commandline.Argument createArg() {
return command.createArgument();
}

/**
* Adds an environment variable (nested env element)
*/
public void addEnv(Environment.Variable var) {
env.addVariable(var);
protected void checkConfiguration() {
super.checkConfiguration();
if (filesets.size() == 0) {
throw new BuildException("no filesets specified", location);
}
}

/**
* Milliseconds we allow the process to run before we kill it.
*/
public void setTimeout(Integer value) {
timeout = value;
}
protected void runExec(Execute exe) throws BuildException {
try {

/**
* throw a build exception if process returns non 0?
*/
public void setFailonerror(boolean fail) {
failOnError = fail;
}
Vector v = new Vector();
for (int i=0; i<filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(project);
String[] s = ds.getIncludedFiles();
for (int j=0; j<s.length; j++) {
v.addElement(new File(fs.getDir(), s[j]).getAbsolutePath());
}
}

public void execute() throws BuildException {
if (command.getExecutable() == null) {
throw new BuildException("no executable specified", location);
}
String[] s = new String[v.size()];
v.copyInto(s);

if (filesets.size() == 0) {
throw new BuildException("no filesets specified", location);
}
int err = -1;
String myos = System.getProperty("os.name");

String[] orig = command.getCommandline();
String[] cmd = new String[orig.length+1];
System.arraycopy(orig, 0, cmd, 0, orig.length);

Vector v = new Vector();
for (int i=0; i<filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(project);
String[] s = ds.getIncludedFiles();
for (int j=0; j<s.length; j++) {
v.addElement(new File(fs.getDir(), s[j]).getAbsolutePath());
}
}
String label = command.toString()+" ";
String[] environment = env.getVariables();
for (int i=0; i<v.size(); i++) {
try {
// show the command
String file = (String) v.elementAt(i);
log(label+file, Project.MSG_VERBOSE);

Execute exe = new Execute(createHandler(), createWatchdog());
cmd[orig.length] = file;
exe.setCommandline(cmd);
exe.setEnvironment(environment);
int err = exe.execute();
// antRun.bat currently limits us to directory + executable
// + 7 args
if (parallel &&
(myos.toLowerCase().indexOf("windows") < 0 || s.length+cmdl.size() <= 8)
) {
cmdl.addLine(s);
exe.setCommandline(cmdl.getCommandline());
err = exe.execute();
if (err != 0) {
if (failOnError) {
throw new BuildException("Exec returned: "+err, location);
throw new BuildException("Exec returned: "+err,
location);
} else {
log("Result: " + err, Project.MSG_ERR);
}
}
} catch (IOException e) {
throw new BuildException("Execute failed: " + e, e, location);
}
}
}

protected ExecuteStreamHandler createHandler() throws BuildException {
return new LogStreamHandler(this,
Project.MSG_INFO, Project.MSG_WARN);
}
} else {
String[] cmd = new String[cmdl.size()+1];
System.arraycopy(cmdl.getCommandline(), 0, cmd, 0, cmdl.size());
for (int i=0; i<s.length; i++) {
cmd[cmdl.size()] = s[i];
exe.setCommandline(cmd);
err = exe.execute();
if (err != 0) {
if (failOnError) {
throw new BuildException("Exec returned: "+err,
location);
} else {
log("Result: " + err, Project.MSG_ERR);
}
}
}
}

protected ExecuteWatchdog createWatchdog() throws BuildException {
if (timeout == null) return null;
return new ExecuteWatchdog(timeout.intValue());
} catch (IOException e) {
throw new BuildException("Execute failed: " + e, e, location);
} finally {
// close the output file if required
logFlush();
}
}

}

+ 1
- 1
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -36,7 +36,7 @@ style=org.apache.tools.ant.taskdefs.XSLTProcess
touch=org.apache.tools.ant.taskdefs.Touch
signjar=org.apache.tools.ant.taskdefs.SignJar
antstructure=org.apache.tools.ant.taskdefs.AntStructure
executeon=org.apache.tools.ant.taskdefs.ExecuteOn
execon=org.apache.tools.ant.taskdefs.ExecuteOn
antcall=org.apache.tools.ant.taskdefs.CallTarget
sql=org.apache.tools.ant.taskdefs.SQLExec



Loading…
Cancel
Save