git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278155 13f79535-47bb-0310-9956-ffa450edef68master
@@ -91,6 +91,12 @@ to send input to it is via the input and inputstring attributes.</p> | |||||
executed.</td> | executed.</td> | ||||
<td align="center" valign="top">No</td> | <td align="center" valign="top">No</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">osfamily</td> | |||||
<td valign="top">OS family as used in the <os> condition. | |||||
<em>since Ant 1.7</em></td> | |||||
<td align="center" valign="top">No</td> | |||||
</tr> | |||||
<tr> | <tr> | ||||
<td valign="top">output</td> | <td valign="top">output</td> | ||||
<td valign="top">the file to which the output of the command | <td valign="top">the file to which the output of the command | ||||
@@ -17,7 +17,7 @@ systems.</p> | |||||
<p>Note that you cannot interact with the forked program, the only way | <p>Note that you cannot interact with the forked program, the only way | ||||
to send input to it is via the input and inputstring attributes. Also note that | to send input to it is via the input and inputstring attributes. Also note that | ||||
in Ant 1.6, any attempt to read input in the forked program will receive an | |||||
since Ant 1.6, any attempt to read input in the forked program will receive an | |||||
EOF (-1). This is a change from Ant 1.5, where such an attempt would block.</p> | EOF (-1). This is a change from Ant 1.5, where such an attempt would block.</p> | ||||
@@ -115,7 +115,14 @@ or the task will fail as follows: | |||||
<td valign="top">list of Operating Systems on which the command may be | <td valign="top">list of Operating Systems on which the command may be | ||||
executed. If the current OS's name is contained in this list, the command will | executed. If the current OS's name is contained in this list, the command will | ||||
be executed. The OS's name is determined by the Java Virtual machine and is set | be executed. The OS's name is determined by the Java Virtual machine and is set | ||||
in the "os.name" system property.</td> | |||||
in the "os.name" system property. | |||||
</td> | |||||
<td align="center" valign="top">No</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">osfamily</td> | |||||
<td valign="top">OS family as used in the <os> condition. | |||||
<em>since Ant 1.7</em></td> | |||||
<td align="center" valign="top">No</td> | <td align="center" valign="top">No</td> | ||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
@@ -329,6 +329,34 @@ | |||||
</fail> | </fail> | ||||
</target> | </target> | ||||
<!-- test will succeed as the OS wont match--> | |||||
<target name="testExecUnknownOS"> | |||||
<exec executable="nonexistent-program-we-expect" | |||||
failonerror="true" | |||||
os="ZX81"> | |||||
</exec> | |||||
</target> | |||||
<target name="testExecOSFamily"> | |||||
<exec executable="uptime" | |||||
failonerror="true" | |||||
osFamily="unix"> | |||||
</exec> | |||||
<exec executable="time" | |||||
failonerror="true" | |||||
osFamily="nt"> | |||||
<arg value="/t" /> | |||||
</exec> | |||||
</target> | |||||
<target name="testExecInconsistentSettings"> | |||||
<exec executable="nonexistent-program-we-expect" | |||||
failonerror="true" | |||||
osFamily="WIN9X" | |||||
os="linux unix"> | |||||
</exec> | |||||
</target> | |||||
<target name="cleanup"> | <target name="cleanup"> | ||||
<delete> | <delete> | ||||
<fileset file="${logFile}" /> | <fileset file="${logFile}" /> | ||||
@@ -21,10 +21,13 @@ import java.io.File; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.Enumeration; | import java.util.Enumeration; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import java.util.Locale; | |||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.ProjectComponent; | import org.apache.tools.ant.ProjectComponent; | ||||
import org.apache.tools.ant.taskdefs.condition.Os; | |||||
import org.apache.tools.ant.types.Commandline; | import org.apache.tools.ant.types.Commandline; | ||||
import org.apache.tools.ant.types.Environment; | import org.apache.tools.ant.types.Environment; | ||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
@@ -43,6 +46,7 @@ public class ExecTask extends Task { | |||||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | ||||
private String os; | private String os; | ||||
private String osFamily; | |||||
private File dir; | private File dir; | ||||
protected boolean failOnError = false; | protected boolean failOnError = false; | ||||
@@ -382,6 +386,15 @@ public class ExecTask extends Task { | |||||
} | } | ||||
/** | |||||
* Restrict this execution to a single OS Family | |||||
* @param osFamily | |||||
*/ | |||||
public void setOsFamily(String osFamily) { | |||||
this.osFamily = osFamily.toLowerCase(Locale.US); | |||||
} | |||||
/** | /** | ||||
* The method attempts to figure out where the executable is so that we can feed | * The method attempts to figure out where the executable is so that we can feed | ||||
* the full path. We first try basedir, then the exec dir, and then | * the full path. We first try basedir, then the exec dir, and then | ||||
@@ -516,21 +529,33 @@ public class ExecTask extends Task { | |||||
* @return boolean. | * @return boolean. | ||||
* <ul> | * <ul> | ||||
* <li> | * <li> | ||||
* <code>true</code> if the os under which Ant is running is | |||||
* matches one os in the os attribute | |||||
* or if the os attribute is null</li> | |||||
* <li><code>true</code> if the os and osfamily attributes are null.</li> | |||||
* <li><code>true</code> if osfamily is set, and the os family and must match | |||||
* that of the current OS, according to the logic of | |||||
* {@link Os#isOs(String, String, String, String)}, and the result of the | |||||
* <code>os</code> attribute must also evaluate true. | |||||
* </li> | |||||
* <li> | |||||
* <code>true</code> if os is set, and the system.property os.name | |||||
* is found in the os attribute,</li> | |||||
* <li><code>false</code> otherwise.</li> | * <li><code>false</code> otherwise.</li> | ||||
* </ul> | * </ul> | ||||
*/ | */ | ||||
protected boolean isValidOs() { | protected boolean isValidOs() { | ||||
// test if os match | |||||
//hand osfamily off to Os class, if set | |||||
if(osFamily!=null && !Os.isOs(osFamily,null,null,null)) { | |||||
return false; | |||||
} | |||||
//the Exec OS check is different from Os.isOs(), which | |||||
//probes for a specific OS. Instead it searches the os field | |||||
//for the current os.name | |||||
String myos = System.getProperty("os.name"); | String myos = System.getProperty("os.name"); | ||||
log("Current OS is " + myos, Project.MSG_VERBOSE); | log("Current OS is " + myos, Project.MSG_VERBOSE); | ||||
if ((os != null) && (os.indexOf(myos) < 0)) { | if ((os != null) && (os.indexOf(myos) < 0)) { | ||||
// this command will be executed only on the specified OS | // this command will be executed only on the specified OS | ||||
log("This OS, " + myos | log("This OS, " + myos | ||||
+ " was not found in the specified list of valid OSes: " + os, | |||||
Project.MSG_VERBOSE); | |||||
+ " was not found in the specified list of valid OSes: " + os, | |||||
Project.MSG_VERBOSE); | |||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
@@ -383,6 +383,18 @@ public class ExecTaskTest extends BuildFileTest { | |||||
assertTrue("log file found after spawn", logFile.exists()); | assertTrue("log file found after spawn", logFile.exists()); | ||||
} | } | ||||
public void testExecUnknownOS() { | |||||
executeTarget("testExecUnknownOS"); | |||||
} | |||||
public void testExecOSFamily() { | |||||
executeTarget("testExecOSFamily"); | |||||
} | |||||
public void testExecInconsistentSettings() { | |||||
executeTarget("testExecInconsistentSettings"); | |||||
} | |||||
private static class MonitoredBuild implements Runnable { | private static class MonitoredBuild implements Runnable { | ||||
private Thread worker; | private Thread worker; | ||||
private File myBuildFile = null; | private File myBuildFile = null; | ||||