PageRenderTime 61ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/gulliver/thirdparty/phing/tasks/system/CvsTask.php

https://bitbucket.org/ferOnti/processmaker
PHP | 540 lines | 265 code | 75 blank | 200 comment | 49 complexity | 637dc641f70cb80f41133b00c991bc58 MD5 | raw file
  1. <?php
  2. /*
  3. * $Id: CvsTask.php 3076 2006-12-18 08:52:12Z fabien $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. require_once 'phing/TaskPhing.php';
  22. include_once 'phing/tasks/system/ExecTask.php';
  23. include_once 'phing/types/Commandline.php';
  24. /**
  25. * Task for performing CVS operations.
  26. *
  27. * NOTE: This implementation has been moved here from Cvs.java with
  28. * the addition of some accessors for extensibility. Another task
  29. * can extend this with some customized output processing.
  30. *
  31. * @author Hans Lellelid <hans@xmpl.org> (Phing)
  32. * @author costin@dnt.ro (Ant)
  33. * @author stefano@apache.org (Ant)
  34. * @author Wolfgang Werner <wwerner@picturesafe.de> (Ant)
  35. * @author Kevin Ross <kevin.ross@bredex.com> (Ant)
  36. * @version $Revision: 1.14 $
  37. * @package phing.tasks.system
  38. */
  39. class CvsTask extends TaskPhing {
  40. /**
  41. * Default compression level to use, if compression is enabled via
  42. * setCompression( true ).
  43. */
  44. const DEFAULT_COMPRESSION_LEVEL = 3;
  45. private $cmd;
  46. /**
  47. * List of Commandline children
  48. * @var array Commandline[]
  49. */
  50. private $commandlines = array();
  51. /**
  52. * the CVSROOT variable.
  53. */
  54. private $cvsRoot;
  55. /**
  56. * the CVS_RSH variable.
  57. */
  58. private $cvsRsh;
  59. /**
  60. * the package/module to check out.
  61. */
  62. private $cvsModule;
  63. /**
  64. * the default command.
  65. */
  66. private static $default_command = "checkout";
  67. /**
  68. * the CVS command to execute.
  69. */
  70. private $command = null;
  71. /**
  72. * suppress information messages.
  73. */
  74. private $quiet = false;
  75. /**
  76. * compression level to use.
  77. */
  78. private $compression = 0;
  79. /**
  80. * report only, don't change any files.
  81. */
  82. private $noexec = false;
  83. /**
  84. * CVS port
  85. */
  86. private $port = 0;
  87. /**
  88. * CVS password file
  89. * @var File
  90. */
  91. private $passFile = null;
  92. /**
  93. * the directory where the checked out files should be placed.
  94. * @var File
  95. */
  96. private $dest;
  97. private $error;
  98. private $output;
  99. /**
  100. * If true it will stop the build if cvs exits with error.
  101. * Default is false. (Iulian)
  102. * @var boolean
  103. */
  104. private $failOnError = false;
  105. public function init() {
  106. $this->cmd = new Commandline();
  107. }
  108. /**
  109. * Sets up the environment for toExecute and then runs it.
  110. * @param Commandline $toExecute
  111. * @throws BuildException
  112. */
  113. protected function runCommand(Commandline $toExecute) {
  114. // We are putting variables into the script's environment
  115. // and not removing them (!) This should be fine, but is
  116. // worth remembering and testing.
  117. if ($this->port > 0) {
  118. putenv("CVS_CLIENT_PORT=".$this->port);
  119. }
  120. // Need a better cross platform integration with <cvspass>, so
  121. // use the same filename.
  122. if ($this->passFile === null) {
  123. $defaultPassFile = new PhingFile(Phing::getProperty("cygwin.user.home", Phing::getProperty("user.home"))
  124. . DIRECTORY_SEPARATOR . ".cvspass");
  125. if($defaultPassFile->exists()) {
  126. $this->setPassfile($defaultPassFile);
  127. }
  128. }
  129. if ($this->passFile !== null) {
  130. if ($this->passFile->isFile() && $this->passFile->canRead()) {
  131. putenv("CVS_PASSFILE=" . $this->passFile->__toString());
  132. $this->log("Using cvs passfile: " . $this->passFile->__toString(), PROJECT_MSG_INFO);
  133. } elseif (!$this->passFile->canRead()) {
  134. $this->log("cvs passfile: " . $this->passFile->__toString()
  135. . " ignored as it is not readable", PROJECT_MSG_WARN);
  136. } else {
  137. $this->log("cvs passfile: " . $this->passFile->__toString()
  138. . " ignored as it is not a file",
  139. PROJECT_MSG_WARN);
  140. }
  141. }
  142. if ($this->cvsRsh !== null) {
  143. putenv("CVS_RSH=".$this->cvsRsh);
  144. }
  145. // Use the ExecTask to handle execution of the command
  146. $exe = new ExecTask($this->project);
  147. $exe->setProject($this->project);
  148. //exe.setAntRun(project);
  149. if ($this->dest === null) {
  150. $this->dest = $this->project->getBaseDir();
  151. }
  152. if (!$this->dest->exists()) {
  153. $this->dest->mkdirs();
  154. }
  155. if ($this->output !== null) {
  156. $exe->setOutput($this->output);
  157. }
  158. if ($this->error !== null) {
  159. $exe->setError($this->error);
  160. }
  161. $exe->setDir($this->dest);
  162. if (is_object($toExecute)) {
  163. $toExecuteStr = $toExecute->__toString(); // unfortunately no more automagic for initial 5.0.0 release :(
  164. }
  165. $exe->setCommand($toExecuteStr);
  166. try {
  167. $actualCommandLine = $toExecuteStr; // we converted to string above
  168. $this->log($actualCommandLine, PROJECT_MSG_INFO);
  169. $retCode = $exe->execute();
  170. $this->log("retCode=" . $retCode, PROJECT_MSG_DEBUG);
  171. /*Throw an exception if cvs exited with error. (Iulian)*/
  172. if ($this->failOnError && $retCode !== 0) {
  173. throw new BuildException("cvs exited with error code "
  174. . $retCode
  175. . Phing::getProperty("line.separator")
  176. . "Command line was ["
  177. . $toExecute->describeCommand() . "]", $this->getLocation());
  178. }
  179. } catch (IOException $e) {
  180. if ($this->failOnError) {
  181. throw new BuildException($e, $this->getLocation());
  182. } else {
  183. $this->log("Caught exception: " . $e, PROJECT_MSG_WARN);
  184. }
  185. } catch (BuildException $e) {
  186. if ($this->failOnError) {
  187. throw $e;
  188. } else {
  189. $t = $e->getCause();
  190. if ($t === null) {
  191. $t = $e;
  192. }
  193. $this->log("Caught exception: " . $t, PROJECT_MSG_WARN);
  194. }
  195. } catch (Exception $e) {
  196. if ($this->failOnError) {
  197. throw new BuildException($e, $this->getLocation());
  198. } else {
  199. $this->log("Caught exception: " . $e, PROJECT_MSG_WARN);
  200. }
  201. }
  202. }
  203. /**
  204. *
  205. * @return void
  206. * @throws BuildException
  207. */
  208. public function main() {
  209. $savedCommand = $this->getCommand();
  210. if ($this->getCommand() === null && empty($this->commandlines)) {
  211. // re-implement legacy behaviour:
  212. $this->setCommand(self::$default_command);
  213. }
  214. $c = $this->getCommand();
  215. $cloned = null;
  216. if ($c !== null) {
  217. $cloned = $this->cmd->__copy();
  218. $cloned->createArgument(true)->setLine($c);
  219. $this->addConfiguredCommandline($cloned, true);
  220. }
  221. try {
  222. for ($i = 0, $vecsize=count($this->commandlines); $i < $vecsize; $i++) {
  223. $this->runCommand($this->commandlines[$i]);
  224. }
  225. // finally {
  226. if ($cloned !== null) {
  227. $this->removeCommandline($cloned);
  228. }
  229. $this->setCommand($savedCommand);
  230. } catch (Exception $e) {
  231. // finally {
  232. if ($cloned !== null) {
  233. $this->removeCommandline($cloned);
  234. }
  235. $this->setCommand($savedCommand);
  236. throw $e;
  237. }
  238. }
  239. /**
  240. * The CVSROOT variable.
  241. *
  242. * @param string $root
  243. */
  244. public function setCvsRoot($root) {
  245. // Check if not real cvsroot => set it to null
  246. if ($root !== null) {
  247. if (trim($root) == "") {
  248. $root = null;
  249. }
  250. }
  251. $this->cvsRoot = $root;
  252. }
  253. public function getCvsRoot() {
  254. return $this->cvsRoot;
  255. }
  256. /**
  257. * The CVS_RSH variable.
  258. *
  259. * @param rsh
  260. */
  261. public function setCvsRsh($rsh) {
  262. // Check if not real cvsrsh => set it to null
  263. if ($rsh !== null) {
  264. if (trim($rsh) == "") {
  265. $rsh = null;
  266. }
  267. }
  268. $this->cvsRsh = $rsh;
  269. }
  270. public function getCvsRsh() {
  271. return $this->cvsRsh;
  272. }
  273. /**
  274. * Port used by CVS to communicate with the server.
  275. *
  276. * @param int $port
  277. */
  278. public function setPort($port){
  279. $this->port = $port;
  280. }
  281. /**
  282. * @return int
  283. */
  284. public function getPort() {
  285. return $this->port;
  286. }
  287. /**
  288. * Password file to read passwords from.
  289. *
  290. * @param passFile
  291. */
  292. public function setPassfile(PhingFile $passFile) {
  293. $this->passFile = $passFile;
  294. }
  295. /**
  296. * @return File
  297. */
  298. public function getPassFile() {
  299. return $this->passFile;
  300. }
  301. /**
  302. * The directory where the checked out files should be placed.
  303. *
  304. * @param PhingFile $dest
  305. */
  306. public function setDest(PhingFile $dest) {
  307. $this->dest = $dest;
  308. }
  309. public function getDest() {
  310. return $this->dest;
  311. }
  312. /**
  313. * The package/module to operate upon.
  314. *
  315. * @param string $p
  316. */
  317. public function setModule($m) {
  318. $this->cvsModule = $m;
  319. }
  320. public function getModule(){
  321. return $this->cvsModule;
  322. }
  323. /**
  324. * The tag of the package/module to operate upon.
  325. * @param string $p
  326. */
  327. public function setTag($p) {
  328. // Check if not real tag => set it to null
  329. if ($p !== null && trim($p) !== "") {
  330. $this->appendCommandArgument("-r");
  331. $this->appendCommandArgument($p);
  332. }
  333. }
  334. /**
  335. * This needs to be public to allow configuration
  336. * of commands externally.
  337. */
  338. public function appendCommandArgument($arg) {
  339. $this->cmd->createArgument()->setValue($arg);
  340. }
  341. /**
  342. * Use the most recent revision no later than the given date.
  343. * @param p
  344. */
  345. public function setDate($p) {
  346. if ($p !== null && trim($p) !== "") {
  347. $this->appendCommandArgument("-D");
  348. $this->appendCommandArgument($p);
  349. }
  350. }
  351. /**
  352. * The CVS command to execute.
  353. * @param string $c
  354. */
  355. public function setCommand($c) {
  356. $this->command = $c;
  357. }
  358. public function getCommand() {
  359. return $this->command;
  360. }
  361. /**
  362. * If true, suppress informational messages.
  363. * @param boolean $q
  364. */
  365. public function setQuiet($q) {
  366. $this->quiet = $q;
  367. }
  368. /**
  369. * If true, report only and don't change any files.
  370. *
  371. * @param boolean $ne
  372. */
  373. public function setNoexec($ne) {
  374. $this->noexec = (boolean) $ne;
  375. }
  376. /**
  377. * Stop the build process if the command exits with
  378. * a return code other than 0.
  379. * Defaults to false.
  380. * @param boolean $failOnError
  381. */
  382. public function setFailOnError($failOnError) {
  383. $this->failOnError = (boolean) $failOnError;
  384. }
  385. /**
  386. * Configure a commandline element for things like cvsRoot, quiet, etc.
  387. * @return string
  388. */
  389. protected function configureCommandline($c) {
  390. if ($c === null) {
  391. return;
  392. }
  393. $c->setExecutable("cvs");
  394. if ($this->cvsModule !== null) {
  395. $c->createArgument()->setLine($this->cvsModule);
  396. }
  397. if ($this->compression > 0 && $this->compression < 10) {
  398. $c->createArgument(true)->setValue("-z" . $this->compression);
  399. }
  400. if ($this->quiet) {
  401. $c->createArgument(true)->setValue("-q");
  402. }
  403. if ($this->noexec) {
  404. $c->createArgument(true)->setValue("-n");
  405. }
  406. if ($this->cvsRoot !== null) {
  407. $c->createArgument(true)->setLine("-d" . $this->cvsRoot);
  408. }
  409. }
  410. protected function removeCommandline(Commandline $c) {
  411. $idx = array_search($c, $this->commandlines, true);
  412. if ($idx === false) {
  413. return false;
  414. }
  415. $this->commandlines = array_splice($this->commandlines, $idx, 1);
  416. return true;
  417. }
  418. /**
  419. * Configures and adds the given Commandline.
  420. * @param insertAtStart If true, c is
  421. */
  422. public function addConfiguredCommandline(Commandline $c, $insertAtStart = false) {
  423. if ($c === null) {
  424. return;
  425. }
  426. $this->configureCommandline($c);
  427. if ($insertAtStart) {
  428. array_unshift($this->commandlines, $c);
  429. } else {
  430. array_push($this->commandlines, $c);
  431. }
  432. }
  433. /**
  434. * If set to a value 1-9 it adds -zN to the cvs command line, else
  435. * it disables compression.
  436. * @param int $level
  437. */
  438. public function setCompressionLevel($level) {
  439. $this->compression = $level;
  440. }
  441. /**
  442. * If true, this is the same as compressionlevel="3".
  443. *
  444. * @param boolean $usecomp If true, turns on compression using default
  445. * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL.
  446. */
  447. public function setCompression($usecomp) {
  448. $this->setCompressionLevel($usecomp ?
  449. self::DEFAULT_COMPRESSION_LEVEL : 0);
  450. }
  451. /**
  452. * File to which output should be written.
  453. * @param PhingFile $output
  454. */
  455. function setOutput(PhingFile $f) {
  456. $this->output = $f;
  457. }
  458. /**
  459. * File to which error output should be written.
  460. * @param PhingFile $output
  461. */
  462. function setError(PhingFile $f) {
  463. $this->error = $f;
  464. }
  465. }