diff --git a/classes/phing/tasks/system/ExecTask.php b/classes/phing/tasks/system/ExecTask.php
index 89815a0381..c3ae2b946b 100644
--- a/classes/phing/tasks/system/ExecTask.php
+++ b/classes/phing/tasks/system/ExecTask.php
@@ -131,6 +131,8 @@ class ExecTask extends Task
*/
protected $checkreturn = false;
+ private $osFamily;
+
/**
*
*/
@@ -146,7 +148,7 @@ public function __construct()
*/
public function main()
{
- if (!$this->isApplicable()) {
+ if (!$this->isValidOs()) {
return;
}
@@ -156,38 +158,6 @@ public function main()
$this->cleanup($return, $output);
}
- /**
- * Checks whether the command shall be executed
- *
- * @return boolean False if the exec command shall not be run
- */
- protected function isApplicable()
- {
- if ($this->os === null) {
- return true;
- }
-
- $myos = Phing::getProperty('os.name');
- $this->log('Myos = ' . $myos, Project::MSG_VERBOSE);
-
- if (strpos($this->os, $myos) !== false) {
- // this command will be executed only on the specified OS
- // OS matches
- return true;
- }
-
- $this->log(
- sprintf(
- 'Operating system %s not found in %s',
- $myos,
- $this->os
- ),
- Project::MSG_VERBOSE
- );
-
- return false;
- }
-
/**
* Prepares the command building and execution, i.e.
* changes to the specified directory.
@@ -202,9 +172,15 @@ protected function prepare()
}
// expand any symbolic links first
- if (!$this->dir->getCanonicalFile()->isDirectory()) {
+ try {
+ if (!$this->dir->getCanonicalFile()->isDirectory()) {
+ throw new BuildException(
+ "'" . (string) $this->dir . "' is not a valid directory"
+ );
+ }
+ } catch (IOException $e) {
throw new BuildException(
- "'" . (string) $this->dir . "' is not a valid directory"
+ "'" . (string) $this->dir . "' is not a readable directory"
);
}
$this->currdir = getcwd();
@@ -420,6 +396,31 @@ public function setOs($os)
$this->os = (string) $os;
}
+ /**
+ * List of operating systems on which the command may be executed.
+ */
+ public function getOs()
+ {
+ return $this->os;
+ }
+
+ /**
+ * Restrict this execution to a single OS Family
+ * @param string $osFamily the family to restrict to.
+ */
+ public function setOsFamily($osFamily)
+ {
+ $this->osFamily = strtolower($osFamily);
+ }
+
+ /**
+ * Restrict this execution to a single OS Family
+ */
+ public function getOsFamily()
+ {
+ return $this->osFamily;
+ }
+
/**
* File to which output should be written.
*
@@ -453,7 +454,7 @@ public function setError(PhingFile $f)
*/
public function setPassthru($passthru)
{
- $this->passthru = (bool) $passthru;
+ $this->passthru = $passthru;
}
/**
@@ -465,7 +466,7 @@ public function setPassthru($passthru)
*/
public function setLogoutput($logOutput)
{
- $this->logOutput = (bool) $logOutput;
+ $this->logOutput = $logOutput;
}
/**
@@ -477,7 +478,7 @@ public function setLogoutput($logOutput)
*/
public function setSpawn($spawn)
{
- $this->spawn = (bool) $spawn;
+ $this->spawn = $spawn;
}
/**
@@ -489,7 +490,7 @@ public function setSpawn($spawn)
*/
public function setCheckreturn($checkreturn)
{
- $this->checkreturn = (bool) $checkreturn;
+ $this->checkreturn = $checkreturn;
}
/**
@@ -558,4 +559,42 @@ public function createArg()
{
return $this->commandline->createArgument();
}
+
+ /**
+ * Is this the OS the user wanted?
+ * @return boolean.
+ *
+ * -
+ *
true
if the os and osfamily attributes are null.
+ * true
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
+ * os
attribute must also evaluate true.
+ *
+ * -
+ *
true
if os is set, and the system.property os.name
+ * is found in the os attribute,
+ * false
otherwise.
+ *
+ */
+ protected function isValidOs()
+ {
+ //hand osfamily off to Os class, if set
+ if ($this->osFamily !== null && !OsCondition::isFamily($this->osFamily)) {
+ 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
+ $myos = Phing::getProperty("os.name");
+ $this->log("Current OS is " . $myos, Project::MSG_VERBOSE);
+ if (($this->os !== null) && (strpos($this->os, $myos) === false)) {
+ // this command will be executed only on the specified OS
+ $this->log("This OS, " . $myos
+ . " was not found in the specified list of valid OSes: " . $this->os,
+ Project::MSG_VERBOSE);
+ return false;
+ }
+ return true;
+ }
}
diff --git a/classes/phing/tasks/system/condition/OsCondition.php b/classes/phing/tasks/system/condition/OsCondition.php
index 62798bad0b..c9f584c27b 100644
--- a/classes/phing/tasks/system/condition/OsCondition.php
+++ b/classes/phing/tasks/system/condition/OsCondition.php
@@ -41,20 +41,40 @@ public function setFamily($f)
$this->family = strtolower($f);
}
+ public function evaluate()
+ {
+ return self::isOS($this->family);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the
+ * given OS family.
+ * @param string $family the family to check for
+ * @return true if the OS matches
+ */
+ public static function isFamily($family)
+ {
+ return self::isOS($family);
+ }
+
/**
+ * @param string $family
* @return bool
- * @throws BuildException
*/
- public function evaluate()
+ public static function isOS($family)
{
$osName = strtolower(Phing::getProperty("os.name"));
- if ($this->family !== null) {
- if ($this->family === "windows") {
+ if ($family !== null) {
+ if ($family === "windows") {
return StringHelper::startsWith("win", $osName);
- } elseif ($this->family === "mac") {
+ }
+
+ if ($family === "mac") {
return (strpos($osName, "mac") !== false || strpos($osName, "darwin") !== false);
- } elseif ($this->family === ("unix")) {
+ }
+
+ if ($family === ("unix")) {
return (
StringHelper::endsWith("ix", $osName) ||
StringHelper::endsWith("ux", $osName) ||
@@ -63,7 +83,7 @@ public function evaluate()
StringHelper::startsWith("darwin", $osName)
);
}
- throw new BuildException("Don't know how to detect os family '" . $this->family . "'");
+ throw new BuildException("Don't know how to detect os family '" . $family . "'");
}
return false;
diff --git a/docs/docbook5/en/source/appendixes/coretasks.xml b/docs/docbook5/en/source/appendixes/coretasks.xml
index 94ea5380c3..0cd894c63a 100644
--- a/docs/docbook5/en/source/appendixes/coretasks.xml
+++ b/docs/docbook5/en/source/appendixes/coretasks.xml
@@ -1696,6 +1696,13 @@ verbose="true" failonerror="false" />
n/a
No
+
+ osfamily
+ String
+ OS family as used in the <os> condition.
+ n/a
+ No
+
escape
Boolean
diff --git a/etc/phing-grammar.rng b/etc/phing-grammar.rng
index 586e55900a..db01520c23 100644
--- a/etc/phing-grammar.rng
+++ b/etc/phing-grammar.rng
@@ -1096,12 +1096,12 @@
-
+
-
+
@@ -1112,12 +1112,15 @@
-
+
+
+
+
-
+
@@ -1128,7 +1131,7 @@
-
+
@@ -6511,9 +6514,16 @@
+
+
+
+
+
+
+
diff --git a/test/classes/phing/tasks/system/ExecTaskTest.php b/test/classes/phing/tasks/system/ExecTaskTest.php
index cea215e9f0..a01e60dbd5 100644
--- a/test/classes/phing/tasks/system/ExecTaskTest.php
+++ b/test/classes/phing/tasks/system/ExecTaskTest.php
@@ -212,19 +212,30 @@ public function testPropertySetLevelUnknown()
public function testDoNotExecuteOnWrongOs()
{
$this->executeTarget(__FUNCTION__);
- $this->assertInLogs('Not found in unknownos');
+ $this->assertInLogs('not found in the specified list of valid OSes: unknownos');
$this->assertNotContains(
'this should not be executed',
$this->getOutput()
);
}
+ public function testDoNotExecuteOnWrongOsFamily()
+ {
+ $this->expectBuildException(__FUNCTION__, "Don't know how to detect os family 'unknownos'");
+ }
+
public function testExecuteOnCorrectOs()
{
$this->executeTarget(__FUNCTION__);
$this->assertInLogs('this should be executed');
}
+ public function testExecuteOnCorrectOsFamily()
+ {
+ $this->executeTarget(__FUNCTION__);
+ $this->assertInLogs('this should be executed');
+ }
+
public function testFailOnNonExistingDir()
{
try {
diff --git a/test/etc/tasks/system/ExecTest.xml b/test/etc/tasks/system/ExecTest.xml
index c312b4881d..64537ee91e 100644
--- a/test/etc/tasks/system/ExecTest.xml
+++ b/test/etc/tasks/system/ExecTest.xml
@@ -76,11 +76,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+