PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/pear/XincPEARPackageTask.php

http://xinc.googlecode.com/
PHP | 431 lines | 237 code | 48 blank | 146 comment | 7 complexity | 15f5884391f00adda5287f49663ac04d MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * Xinc - Continuous Integration.
  4. * Pear Package Task taken from phing http://phing.info
  5. *
  6. * PHP version 5
  7. *
  8. * @category Development
  9. * @package Xinc
  10. * @author Arno Schneider <username@example.org>
  11. * @author Hans Lellelid <hans@xmpl.org>
  12. * @author Alexander Opitz <opitz.alexander@gmail.com>
  13. * @license http://www.gnu.org/copyleft/lgpl.html GNU/LGPL, see license.php
  14. * This file is part of Xinc.
  15. * Xinc is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU Lesser General Public License as
  17. * published by the Free Software Foundation; either version 2.1 of
  18. * the License, or (at your option) any later version.
  19. *
  20. * Xinc is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU Lesser General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Lesser General Public
  26. * License along with Xinc, write to the Free Software Foundation,
  27. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  28. * @link http://code.google.com/p/xinc
  29. */
  30. require_once 'phing/tasks/ext/pearpackage/Fileset.php';
  31. require_once 'PEAR.php';
  32. require_once 'PEAR/Frontend.php';
  33. require_once 'PEAR/Task/Postinstallscript/rw.php';
  34. /**
  35. * The package task.
  36. *
  37. * @category Development
  38. * @package Xinc
  39. * @author Arno Schneider <username@example.org>
  40. * @author Hans Lellelid <hans@xmpl.org>
  41. * @author Alexander Opitz <opitz.alexander@gmail.com>
  42. * @license http://www.gnu.org/copyleft/lgpl.html GNU/LGPL, see license.php
  43. * @link http://code.google.com/p/xinc
  44. */
  45. class XincPEARPackageTask extends MatchingTask
  46. {
  47. /** @var PhingFile Base directory for reading files. */
  48. private $dir;
  49. /** @var string Versionnumber for this build. */
  50. private $version;
  51. /** @var string Version state for this build. */
  52. private $state = 'beta';
  53. /** @var string . */
  54. private $notes;
  55. /** @var array of FileSet. */
  56. private $arFilesets = array();
  57. /** @var PhingFile Package file */
  58. private $packageFile;
  59. public function init()
  60. {
  61. $ret = @include_once 'PEAR/PackageFileManager2.php';
  62. if (false === $ret) {
  63. throw new BuildException(
  64. 'You must have installed PEAR_PackageFileManager2'
  65. . 'in order to create a PEAR package.xml file.'
  66. );
  67. }
  68. }
  69. /**
  70. * Main entry point.
  71. *
  72. * @return void
  73. * @throws BuildException
  74. */
  75. public function main()
  76. {
  77. $this->checkPreConditions();
  78. // @var PEAR_PackageFileManager2
  79. $package = new PEAR_PackageFileManager2();
  80. $package->setOptions($this->getOptions());
  81. // the hard-coded stuff
  82. $package->setPackage('Xinc');
  83. $package->setSummary('Xinc - Continuous Integration Server');
  84. $package->setDescription(
  85. 'Xinc is a continuous integration server written in PHP 5.'
  86. . ' It has built-in support for Subversion and Phing (and therefore'
  87. . ' PHPUnit), and can be easily extended to work with alternative'
  88. . ' version control or build tools.'
  89. );
  90. $package->setChannel('pear.elektrischeslicht.de');
  91. $package->setPackageType('php');
  92. $package->setReleaseVersion($this->version);
  93. $package->setAPIVersion($this->version);
  94. $package->setReleaseStability($this->state);
  95. $package->setAPIStability($this->state);
  96. $package->setNotes($this->notes);
  97. $package->setLicense('LGPL', 'http://www.gnu.org/licenses/lgpl.html');
  98. // Add package maintainers
  99. $package->addMaintainer('lead', 'arnoschn', 'Arno Schneider', 'arnoschn@gmail.com');
  100. $package->addMaintainer('lead', 'opi', 'Alexander Opitz', 'opitz.alexander@gmail.com');
  101. $package->addMaintainer('lead', 'gavinleefoster', 'Gavin Foster', 'gavinleefoster@gmail.com', 'no');
  102. // (wow ... this is a poor design ...)
  103. //
  104. // note that the order of the method calls below is creating
  105. // sub-"release" sections which have specific rules. This replaces
  106. // the platformexceptions system in the older version of PEAR's package.xml
  107. //
  108. // Programmatically, I feel the need to re-iterate that this API for PEAR_PackageFileManager
  109. // seems really wrong. Sub-sections should be encapsulated in objects instead of having
  110. // a "flat" API that does not represent the structure being created....
  111. $this->addSubsectionWindows($package);
  112. $this->addSubsectionOthers($package);
  113. // "core" dependencies
  114. $package->setPhpDep('5.2.7');
  115. $package->setPearinstallerDep('1.4.0');
  116. // "package" dependencies
  117. $package->addExtensionDep('required', 'xsl');
  118. $package->addExtensionDep('required', 'xml');
  119. $package->addPackageDepWithChannel('required', 'phing', 'pear.phing.info', '2.4.0');
  120. $package->addPackageDepWithChannel('required', 'Base', 'components.ez.no', '1.4.1');
  121. $package->addPackageDepWithChannel('required', 'Graph', 'components.ez.no', '1.2.1');
  122. $package->addPackageDepWithChannel('optional', 'VersionControl_SVN', 'pear.php.net', '0.5.0');
  123. $package->addPackageDepWithChannel('optional', 'VersionControl_Git', 'pear.php.net', '0.4.4');
  124. $package->addPackageDepWithChannel('optional', 'Mail', 'pear.php.net', '1.2.0');
  125. $package->addPackageDepWithChannel('optional', 'PHPUnit', 'pear.phpunit.de', '3.5.0');
  126. $package->addPackageDepWithChannel('optional', 'PhpDocumentor', 'pear.php.net', '1.4.0');
  127. $package->addPackageDepWithChannel('optional', 'PHP_CodeSniffer', 'pear.php.net', '1.3.0');
  128. $package->addPackageDepWithChannel('optional', 'Xdebug', 'pecl.php.net', '2.0.0');
  129. $package->addPackageDepWithChannel('optional', 'Archive_Tar', 'pear.php.net', '1.3.0');
  130. $package->addPackageDepWithChannel('optional', 'PEAR_PackageFileManager2', 'pear.php.net', '1.0.2');
  131. // now add the replacements ....
  132. $package->addReplacement('bin/xinc.bat', 'pear-config', '@PHP_BIN@', 'php_bin');
  133. $package->addReplacement('bin/xinc-settings.bat', 'pear-config', '@PHP_BIN@', 'php_bin');
  134. $package->addReplacement('bin/xinc-settings.bat', 'pear-config', '@BIN_DIR@', 'bin_dir');
  135. $package->addReplacement('Xinc.php', 'package-info', '@VERSION@', 'version');
  136. $package->addReplacement('xinc.ini.tpl', 'package-info', '@VERSION@', 'version');
  137. $package->addReplacement('bin/xinc.bat', 'pear-config', '@BIN_DIR@', 'bin_dir');
  138. $package->addReplacement('scripts/xinc-uninstall', 'pear-config', '@PHP_BIN@', 'php_bin');
  139. $package->addReplacement('scripts/xinc-uninstall.bat', 'pear-config', '@PHP_BIN@', 'php_bin');
  140. $package->addReplacement('scripts/xinc-uninstall', 'pear-config', '@BIN_DIR@', 'bin_dir');
  141. $package->addReplacement('scripts/xinc-uninstall.bat', 'pear-config', '@BIN_DIR@', 'bin_dir');
  142. $package->addReplacement('etc/init.d/xinc.bat', 'pear-config', '@BIN_DIR@', 'bin_dir');
  143. $package->addReplacement('etc/init.d/xinc', 'pear-config', '@BIN_DIR@', 'bin_dir');
  144. $package->addReplacement('bin/xinc', 'pear-config', '@PHP_BIN@', 'php_bin');
  145. $package->addReplacement('bin/xinc-settings', 'pear-config', '@PHP_BIN@', 'php_bin');
  146. $package->addReplacement('bin/xinc-builds', 'pear-config', '@PHP_BIN@', 'php_bin');
  147. $package->addReplacement('Xinc/scripts/pear-install.sh', 'pear-config', '@data-dir@','data_dir');
  148. $config = PEAR_Config::singleton();
  149. $log = PEAR_Frontend::singleton();
  150. $task = new PEAR_Task_Postinstallscript_rw(
  151. $package, $config, $log,
  152. array('name' => 'Xinc/Postinstall/Nix.php', 'role' => 'php')
  153. );
  154. $task->addParamGroup(
  155. 'daemoninstall',
  156. array(
  157. $task->getParam('etc_dir', 'Directory to keep the Xinc config files', 'string', '/etc/xinc'),
  158. $task->getParam('xinc_dir', 'Directory to keep the Xinc Projects and Status information', 'string', '/var/xinc'),
  159. $task->getParam('log_dir', 'Directory to keep the Xinc log files', 'string', '/var/log'),
  160. $task->getParam('initd_dir', 'Directory to install the Xinc start/stop daemon', 'string', '/etc/init.d'),
  161. $task->getParam('tmp_dir', 'Directory for xinc`s temporary files', 'string', '/tmp/xinc'),
  162. $task->getParam('install_examples', 'Do you want to install the SimpleProject example', 'string', 'yes'),
  163. $task->getParam('www_dir', 'Directory to install the Xinc web-application', 'string', '/var/www/xinc'),
  164. $task->getParam('www_ip', 'IP of Xinc web-application', 'string', '127.0.0.1'),
  165. $task->getParam('www_port', 'Port of Xinc web-application', 'string', '8080'),
  166. )
  167. );
  168. $package->addPostinstallTask($task, 'Xinc/Postinstall/Nix.php');
  169. $taskWin = new PEAR_Task_Postinstallscript_rw(
  170. $package, $config, $log,
  171. array('name' => 'Xinc/Postinstall/Win.php', 'role' => 'php')
  172. );
  173. $taskWin->addParamGroup(
  174. 'daemoninstall',
  175. array(
  176. $taskWin->getParam('etc_dir', 'Directory to keep the Xinc config files', 'string', 'C:\\xinc\\etc'),
  177. $taskWin->getParam('xinc_dir', 'Directory to keep the Xinc Projects and Status information', 'string', 'C:\\xinc'),
  178. $taskWin->getParam('log_dir', 'Directory to keep the Xinc log files', 'string', 'C:\\xinc\\log'),
  179. $taskWin->getParam('initd_dir', 'Directory to install the Xinc start/stop script', 'string', 'C:\\xinc\\init.d'),
  180. $taskWin->getParam('tmp_dir', 'Directory for xinc`s temporary files', 'string', 'C:\\xinc\\temp'),
  181. $taskWin->getParam('install_examples', 'Do you want to install the SimpleProject example', 'string', 'yes'),
  182. $taskWin->getParam('www_dir', 'Directory to install the Xinc web-application', 'string', 'C:\\xinc\\www'),
  183. $taskWin->getParam('www_ip', 'IP of Xinc web-application', 'string', '127.0.0.1'),
  184. $taskWin->getParam('www_port', 'Port of Xinc web-application', 'string', '8080'),
  185. )
  186. );
  187. $package->addPostinstallTask($taskWin, 'Xinc/Postinstall/Win.php');
  188. // now we run this weird generateContents() method that apparently
  189. // is necessary before we can add replacements ... ?
  190. $package->generateContents();
  191. $e = $package->writePackageFile();
  192. if (PEAR::isError($e)) {
  193. throw new BuildException(
  194. 'Unable to write package file.',
  195. new Exception($e->getMessage())
  196. );
  197. }
  198. }
  199. /**
  200. * Checks if needed parts are available. If not it throws an exception.
  201. *
  202. * @return void
  203. * @throws BuildException
  204. */
  205. private function checkPreConditions()
  206. {
  207. if (empty($this->arFilesets)) {
  208. throw new BuildException(
  209. 'You must use a <fileset> tag to specify the files'
  210. . 'to include in the package.xml'
  211. );
  212. }
  213. if ($this->dir === null) {
  214. throw new BuildException(
  215. 'You must specify the "dir" attribute for PEAR package task.'
  216. );
  217. }
  218. if ($this->version === null) {
  219. throw new BuildException(
  220. 'You must specify the "version" attribute for PEAR package task.'
  221. );
  222. }
  223. }
  224. /**
  225. * Sets the options in the package manager
  226. *
  227. * @return array Option array for package manager.
  228. */
  229. private function getOptions()
  230. {
  231. $arOptions = array(
  232. 'baseinstalldir' => '/',
  233. 'packagedirectory' => $this->dir->getAbsolutePath(),
  234. 'filelistgenerator' => 'Fileset',
  235. 'dir_roles' => array(
  236. 'bin' => 'script',
  237. 'templates' => 'data',
  238. 'examples' => 'data',
  239. 'resources' => 'data',
  240. 'etc' => 'data',
  241. 'scripts' => 'data',
  242. 'web' => 'data',
  243. 'tests' => 'test',
  244. ),
  245. // options needed by phing Fileset reader
  246. 'phing_project' => $this->getProject(),
  247. 'phing_filesets' => $this->arFilesets,
  248. );
  249. if ($this->packageFile !== null) {
  250. // create one w/ full path
  251. $f = new PhingFile($this->packageFile->getAbsolutePath());
  252. $arOptions['packagefile'] = $f->getName();
  253. // must end in trailing slash
  254. $arOptions['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
  255. $this->log("Creating package file: " . $f->getPath(), PROJECT_MSG_INFO);
  256. } else {
  257. $this->log("Creating [default] package.xml file in base directory.", PROJECT_MSG_INFO);
  258. }
  259. return $arOptions;
  260. }
  261. /**
  262. * Adds Windows release to the package manager
  263. *
  264. * @param PEAR_PackageFileManager2 $package The package manager.
  265. *
  266. * @return void
  267. */
  268. private function addSubsectionWindows(PEAR_PackageFileManager2 $package)
  269. {
  270. // windows release
  271. $package->addRelease();
  272. $package->setOSInstallCondition('windows');
  273. $package->addInstallAs('bin/xinc.bat', 'xinc.bat');
  274. $package->addInstallAs('bin/xinc.php', 'xinc.php');
  275. $package->addInstallAs('bin/xinc-settings.bat', 'xinc-settings.bat');
  276. $package->addInstallAs('bin/xinc-settings.php', 'xinc-settings.php');
  277. $package->addIgnoreToRelease('Xinc/Postinstall/Nix.php');
  278. $package->addIgnoreToRelease('bin/xinc');
  279. $package->addIgnoreToRelease('bin/xinc-settings');
  280. $package->addIgnoreToRelease('scripts/xinc-uninstall');
  281. $package->addIgnoreToRelease('bin/xinc-builds');
  282. $package->addIgnoreToRelease('etc/init.d/xinc');
  283. }
  284. /**
  285. * Adds Others release to the package manager
  286. *
  287. * @param PEAR_PackageFileManager2 $package The package manager.
  288. *
  289. * @return void
  290. */
  291. private function addSubsectionOthers(PEAR_PackageFileManager2 $package)
  292. {
  293. // Linux release
  294. $package->addRelease();
  295. $package->addInstallAs('bin/xinc', 'xinc');
  296. $package->addInstallAs('bin/xinc-settings', 'xinc-settings');
  297. $package->addInstallAs('bin/xinc-builds', 'xinc-builds');
  298. $package->addIgnoreToRelease('Xinc/Postinstall/Win.php');
  299. $package->addIgnoreToRelease('bin/xinc.bat');
  300. $package->addIgnoreToRelease('bin/xinc.php');
  301. $package->addIgnoreToRelease('etc/init.d/xinc.bat');
  302. $package->addIgnoreToRelease('scripts/winserv.exe');
  303. $package->addIgnoreToRelease('scripts/xinc-uninstall.bat');
  304. }
  305. /**
  306. * Used by the PEAR_PackageFileManager_FileSet lister.
  307. *
  308. * @return array FileSet[]
  309. */
  310. public function getFileSets()
  311. {
  312. return $this->arFilesets;
  313. }
  314. // -------------------------------
  315. // Set properties from XML
  316. // -------------------------------
  317. /**
  318. * Nested creator, creates a FileSet for this task
  319. *
  320. * @return FileSet The created fileset object
  321. */
  322. function createFileSet()
  323. {
  324. $fileset = new FileSet();
  325. array_push($this->arFilesets, $fileset);
  326. return $fileset;
  327. }
  328. /**
  329. * Set the version we are building.
  330. *
  331. * @param string $v
  332. *
  333. * @return void
  334. */
  335. public function setVersion($v)
  336. {
  337. $this->version = $v;
  338. }
  339. /**
  340. * Set the state we are building.
  341. *
  342. * @param string $v
  343. *
  344. * @return void
  345. */
  346. public function setState($v)
  347. {
  348. $this->state = $v;
  349. }
  350. /**
  351. * Sets release notes field.
  352. *
  353. * @param string $v
  354. *
  355. * @return void
  356. */
  357. public function setNotes($v)
  358. {
  359. $this->notes = $v;
  360. }
  361. /**
  362. * Sets "dir" property from XML.
  363. *
  364. * @param PhingFile $f
  365. *
  366. * @return void
  367. */
  368. public function setDir(PhingFile $f)
  369. {
  370. $this->dir = $f;
  371. }
  372. /**
  373. * Sets the file to use for generated package.xml
  374. *
  375. * @param PhingFile $f
  376. *
  377. * @return void
  378. */
  379. public function setDestFile(PhingFile $f)
  380. {
  381. $this->packageFile = $f;
  382. }
  383. }