PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/core/Build/BuilderElement/Task/Exec.php

http://cintient.googlecode.com/
PHP | 237 lines | 162 code | 8 blank | 67 comment | 20 complexity | ddcb0fad1648bd108e5d3075abad6982 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /*
  3. *
  4. * Cintient, Continuous Integration made simple.
  5. * Copyright (c) 2010, 2011, Pedro Mata-Mouros Fonseca
  6. *
  7. * This file is part of Cintient.
  8. *
  9. * Cintient is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * Cintient is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with Cintient. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. /**
  24. * The exec task is perhaps the single most universal and important task.
  25. * All other tasks could be, in some way or another be specified by an
  26. * exec task.
  27. *
  28. * Usage:
  29. *
  30. * $exec = new Build_BuilderElement_Task_Exec();
  31. * $exec->setExecutable('php');
  32. * $exec->setArgs('runMe.php arg1 arg2');
  33. * $exec->setDir('/tmp/');
  34. * $exec->setOutputProperty('fooBar');
  35. * echo $exec->toString('ant');
  36. *
  37. * @package Build
  38. * @subpackage Task
  39. * @author Pedro Mata-Mouros Fonseca <pedro.matamouros@gmail.com>
  40. * @copyright 2010-2011, Pedro Mata-Mouros Fonseca.
  41. * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPLv3 or later.
  42. * @version $LastChangedRevision: 363 $
  43. * @link $HeadURL: http://cintient.googlecode.com/svn/trunk/src/core/Build/BuilderElement/Task/Exec.php $
  44. * Changed by $LastChangedBy: pedro.matamouros $
  45. * Changed on $LastChangedDate: 2011-09-26 01:32:38 +0200 (Mon, 26 Sep 2011) $
  46. */
  47. class Build_BuilderElement_Task_Exec extends Build_BuilderElement
  48. {
  49. protected $_executable;
  50. protected $_args; // The arguments to the executable command, if any, a space separated string
  51. protected $_baseDir; // The directory in which the command should be executed in
  52. protected $_outputProperty; // Log the command's output to the variable with this name
  53. public function __construct()
  54. {
  55. parent::__construct();
  56. $this->_executable = null;
  57. $this->_args = null;
  58. $this->_baseDir = null;
  59. $this->_outputProperty = null;
  60. }
  61. /**
  62. * Creates a new instance of this builder element, with default values.
  63. */
  64. static public function create()
  65. {
  66. return new self();
  67. }
  68. /**
  69. * Setter. Makes sure <code>$dir</code> always ends in a valid
  70. * <code>DIRECTORY_SEPARATOR</code> token.
  71. *
  72. * @param string $dir
  73. */
  74. public function setBaseDir($dir)
  75. {
  76. if (!empty($dir) && strpos($dir, DIRECTORY_SEPARATOR, (strlen($dir)-1)) === false) {
  77. $dir .= DIRECTORY_SEPARATOR;
  78. }
  79. $this->_baseDir = $dir;
  80. }
  81. public function toAnt()
  82. {
  83. if (!$this->getExecutable()) {
  84. SystemEvent::raise(SystemEvent::ERROR, 'Executable not set for exec task.', __METHOD__);
  85. return false;
  86. }
  87. $xml = new XmlDoc();
  88. $xml->startElement('exec');
  89. if ($this->getOutputProperty()) {
  90. $xml->writeAttribute('outputproperty', $this->getOutputProperty());
  91. }
  92. if ($this->getBaseDir()) {
  93. $xml->writeAttribute('dir', $this->getBaseDir());
  94. }
  95. if ($this->getFailOnError() !== null) {
  96. $xml->writeAttribute('failonerror', ($this->getFailOnError()?'true':'false'));
  97. }
  98. $xml->writeAttribute('executable', $this->getExecutable());
  99. if ($this->getArgs()) {
  100. $args = $this->getArgs();
  101. foreach ($args as $arg) {
  102. $xml->startElement('arg');
  103. $xml->writeAttribute('line', $arg);
  104. $xml->endElement();
  105. }
  106. }
  107. $xml->endElement();
  108. return $xml->flush();
  109. }
  110. public function toHtml()
  111. {
  112. parent::toHtml();
  113. if (!$this->isVisible()) {
  114. return true;
  115. }
  116. $o = $this;
  117. h::li(array('class' => 'builderElement', 'id' => $o->getInternalId()), function() use ($o) {
  118. $o->getHtmlTitle(array('title' => 'Exec'));
  119. h::div(array('class' => 'builderElementForm'), function() use ($o) {
  120. $o->toHtmlFailOnError();
  121. // Executable, textfield
  122. h::div(array('class' => 'label'), 'Executable');
  123. h::div(array('class' => 'textfieldContainer'), function() use ($o) {
  124. h::input(array('class' => 'textfield', 'type' => 'text', 'name' => 'executable', 'value' => $o->getExecutable()));
  125. });
  126. // Args, textfield
  127. h::div(array('class' => 'label'), 'Args <span class="fineprintLabel">(space separated)</span>');
  128. h::div(array('class' => 'textfieldContainer'), function() use ($o) {
  129. h::input(array('class' => 'textfield', 'type' => 'text', 'name' => 'args', 'value' => $o->getArgs()));
  130. });
  131. // Dir, textfield
  132. h::div(array('class' => 'label'), 'Base dir');
  133. h::div(array('class' => 'textfieldContainer'), function() use ($o) {
  134. h::input(array('class' => 'textfield', 'type' => 'text', 'name' => 'basedir', 'value' => $o->getBaseDir()));
  135. });
  136. // Output property, textfield
  137. h::div(array('class' => 'label'), 'Output property');
  138. h::div(array('class' => 'textfieldContainer'), function() use ($o) {
  139. h::input(array('class' => 'textfield', 'type' => 'text', 'name' => 'outputProperty', 'value' => $o->getOutputProperty()));
  140. });
  141. });
  142. });
  143. }
  144. public function toPhing()
  145. {
  146. if (!$this->getExecutable()) {
  147. SystemEvent::raise(SystemEvent::ERROR, 'Executable not set for exec task.', __METHOD__);
  148. return false;
  149. }
  150. $xml = new XmlDoc();
  151. $xml->startElement('exec');
  152. if ($this->getOutputProperty()) {
  153. $xml->writeAttribute('outputProperty', $this->getOutputProperty());
  154. }
  155. if ($this->getBaseDir()) {
  156. $xml->writeAttribute('dir', $this->getBaseDir());
  157. }
  158. $args = '';
  159. if ($this->getArgs()) {
  160. $args = ' ' . implode(' ', $this->getArgs());
  161. }
  162. $xml->writeAttribute('command', $this->getExecutable() . $args);
  163. $xml->endElement();
  164. return $xml->flush();
  165. }
  166. public function toPhp(Array &$context = array())
  167. {
  168. $php = '';
  169. if (!$this->getExecutable()) {
  170. SystemEvent::raise(SystemEvent::ERROR, 'Executable not set for exec task.', __METHOD__);
  171. return false;
  172. }
  173. $php .= "
  174. \$GLOBALS['result']['task'] = 'exec';
  175. \$getBaseDir = '';
  176. ";
  177. if ($this->getBaseDir()) {
  178. $php .= "
  179. \$getBaseDir = \"cd \" . expandStr('{$this->getBaseDir()}') . \"; \";
  180. ";
  181. }
  182. $php .= "
  183. \$args = '';
  184. ";
  185. if ($this->getArgs()) {
  186. $php .= "
  187. \$getArgs = expandStr(' {$this->getArgs()}');
  188. ";
  189. }
  190. $php .= "
  191. \$getExecutable = expandStr('{$this->getExecutable()}');
  192. \$GLOBALS['result']['task'] = 'exec';
  193. output(\"Executing '\$getBaseDir\$getExecutable\$getArgs'.\");
  194. \$ret = exec(\"\$getBaseDir\$getExecutable\$getArgs\", \$lines, \$retval);
  195. foreach (\$lines as \$line) {
  196. output(\$line);
  197. }
  198. ";
  199. if ($this->getOutputProperty()) {
  200. $php .= "
  201. \$GLOBALS['properties']['{$this->getOutputProperty()}_{$context['id']}'] = \$ret;
  202. ";
  203. }
  204. $php .= "
  205. if (\$retval > 0) {
  206. output('Failed.');
  207. if ({$this->getFailOnError()}) {
  208. \$GLOBALS['result']['ok'] = false;
  209. return false;
  210. } else {
  211. \$GLOBALS['result']['ok'] = \$GLOBALS['result']['ok'] & true;
  212. }
  213. } else {
  214. \$GLOBALS['result']['ok'] = \$GLOBALS['result']['ok'] & true;
  215. output('Success.');
  216. }
  217. ";
  218. //TODO: bullet proof this for boolean falses (they're not showing up)
  219. /*
  220. $php .= "if ({$this->getFailOnError()} && !\$ret) {
  221. \$GLOBALS['result']['ok'] = false;
  222. return false;
  223. }
  224. \$GLOBALS['result']['ok'] = true;
  225. return true;
  226. ";*/
  227. return $php;
  228. }
  229. }