PageRenderTime 58ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/Xinc.Server/Classes/Xinc.php

https://gitlab.com/Tiger66639/xinc
PHP | 335 lines | 179 code | 32 blank | 124 comment | 9 complexity | 31242ff0555037864731eebe4ddecb5d MD5 | raw file
  1. <?php
  2. /**
  3. * Xinc - Continuous Integration.
  4. * The main control class.
  5. *
  6. * PHP version 5
  7. *
  8. * @category Development
  9. * @package Xinc.Server
  10. * @author David Ellis <username@example.org>
  11. * @author Gavin Foster <username@example.org>
  12. * @author Jamie Talbot <username@example.org>
  13. * @author Alexander Opitz <opitz.alexander@gmail.com>
  14. * @copyright 2007 David Ellis, One Degree Square
  15. * @license http://www.gnu.org/copyleft/lgpl.html GNU/LGPL, see license.php
  16. * This file is part of Xinc.
  17. * Xinc is free software; you can redistribute it and/or modify
  18. * it under the terms of the GNU Lesser General Public License as
  19. * published by the Free Software Foundation; either version 2.1 of
  20. * the License, or (at your option) any later version.
  21. *
  22. * Xinc is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU Lesser General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU Lesser General Public
  28. * License along with Xinc, write to the Free Software Foundation,
  29. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30. * @link http://code.google.com/p/xinc/
  31. */
  32. namespace Xinc\Server;
  33. class Xinc
  34. {
  35. const VERSION = '2.3.90';
  36. const DEFAULT_PROJECT_DIR = 'projects';
  37. const DEFAULT_STATUS_DIR = 'status';
  38. /**
  39. * Current working directory
  40. * containing the default xinc projects
  41. *
  42. * @var string
  43. */
  44. private $workingDir;
  45. /**
  46. * Directory holding the projects
  47. *
  48. * @var string
  49. */
  50. private $projectDir;
  51. /**
  52. * The directory to drop xml status files
  53. *
  54. * @var string
  55. */
  56. private $statusDir;
  57. /**
  58. * @var array Holding the merged cli parameters.
  59. */
  60. private $options = array();
  61. /**
  62. * Handle command line arguments.
  63. *
  64. * @return void
  65. */
  66. protected function parseCliOptions()
  67. {
  68. $workingDir = dirname($_SERVER['argv'][0]);
  69. $opts = getopt(
  70. 'r:w:s:f:l:v:o',
  71. array(
  72. 'project-dir:',
  73. 'working-dir:',
  74. 'status-dir:',
  75. 'project-file:',
  76. 'log-file:',
  77. 'pid-file:', // not easy in Core_Daemon
  78. 'verbose:', // not easy in Core_Daemon
  79. 'once', // done
  80. 'version', // done
  81. 'help', // done
  82. 'deamon', // not easy in Core_Daemon
  83. '::',
  84. )
  85. );
  86. if (isset($opts['version'])) {
  87. $this->logVersion();
  88. exit();
  89. }
  90. if (isset($opts['help'])) {
  91. $this->showHelp();
  92. exit();
  93. }
  94. $this->options = $this->mergeOpts(
  95. $opts,
  96. array(
  97. 'w' => 'working-dir',
  98. 'r' => 'project-dir',
  99. 's' => 'status-dir',
  100. 'f' => 'project-file',
  101. 'l' => 'log-file',
  102. 'v' => 'verbose',
  103. 'o' => 'once',
  104. ),
  105. array (
  106. 'working-dir' => $workingDir,
  107. 'project-dir' => $workingDir . DIRECTORY_SEPARATOR . self::DEFAULT_PROJECT_DIR . DIRECTORY_SEPARATOR,
  108. 'status-dir' => $workingDir . DIRECTORY_SEPARATOR . self::DEFAULT_STATUS_DIR . DIRECTORY_SEPARATOR,
  109. 'log-file' => $workingDir . DIRECTORY_SEPARATOR . 'xinc.log',
  110. 'verbose' => \Xinc\Core\Logger::DEFAULT_LOG_LEVEL,
  111. )
  112. );
  113. }
  114. /**
  115. * Validates the given options (working-dir, status-dir, project-dir)
  116. *
  117. * @throws Xinc\Core\Exception\IOException
  118. */
  119. protected function validateCliOptions()
  120. {
  121. $this->checkDirectory($this->options['working-dir']);
  122. $this->checkDirectory($this->options['project-dir']);
  123. $this->checkDirectory($this->options['status-dir']);
  124. }
  125. /**
  126. * Merges the default config and the short/long arguments given by mapping together.
  127. * TODO: It doesn't respect options which aren't in the mapping.
  128. *
  129. * @param array $opts The options after php getopt function call.
  130. * @param array $mapping Mapping from short to long argument names.
  131. * @param array $default The default values for some arguments.
  132. *
  133. * @return array Mapping of the long arguments to the given values.
  134. */
  135. protected function mergeOpts($opts, $mapping, $default)
  136. {
  137. $merge = $default;
  138. foreach ($mapping as $keyShort => $keyLong) {
  139. if (isset($opts[$keyShort])) {
  140. $merge[$keyLong] = $opts[$keyShort];
  141. }
  142. if (isset($opts[$keyLong])) {
  143. $merge[$keyLong] = $opts[$keyLong];
  144. }
  145. }
  146. return $merge;
  147. }
  148. /**
  149. * Checks if the directory is available otherwise tries to create it.
  150. * Returns the realpath of the directory afterwards.
  151. *
  152. * @param string $strDirectory Directory to check for.
  153. *
  154. * @return string The realpath of given directory.
  155. * @throws Xinc\Core\Exception\IOException
  156. */
  157. protected function checkDirectory($strDirectory)
  158. {
  159. if (!is_dir($strDirectory)) {
  160. \Xinc\Core\Logger::getInstance()->verbose(
  161. 'Directory "' . $strDirectory . '" does not exist. Trying to create'
  162. );
  163. $bCreated = @mkdir($strDirectory, 0755, true);
  164. if (!$bCreated) {
  165. $arError = error_get_last();
  166. \Xinc\Core\Logger::getInstance()->verbose(
  167. 'Directory "' . $strDirectory . '" could not be created.'
  168. );
  169. throw new \Xinc\Core\Exception\IOException($strDirectory, null, $arError['message']);
  170. }
  171. } elseif (!is_writeable($strDirectory)) {
  172. \Xinc\Core\Logger::getInstance()->verbose(
  173. 'Directory "' . $strDirectory . '" is not writeable.'
  174. );
  175. throw new \Xinc\Core\Exception\IOException(
  176. $strDirectory,
  177. null,
  178. null,
  179. \Xinc\Core\Exception\IOException::FAILURE_NOT_WRITEABLE
  180. );
  181. }
  182. return realpath($strDirectory);
  183. }
  184. /**
  185. * TODO: Needs to be somewhere else?
  186. * returns the builtin properties that can be used
  187. * in all xinc config files
  188. *
  189. * @return array
  190. */
  191. // public function getBuiltinProperties()
  192. // {
  193. // $properties = array();
  194. // $properties['workingdir'] = $this->getWorkingDir();
  195. // $properties['statusdir'] = $this->getStatusDir();
  196. // $properties['projectdir'] = $this->getProjectDir();
  197. //
  198. // return $properties;
  199. // }
  200. /**
  201. * prints help message, describing different parameters to run xinc
  202. *
  203. * @return void
  204. */
  205. protected function showHelp()
  206. {
  207. echo 'Usage: xinc [switches]' . "\n\n";
  208. echo ' -f --project-file=<file> The project file to use.' . "\n"
  209. . ' -l --log-file=<file> The log file to use.' . "\n"
  210. . ' -p --pid-file=<file> The directory to put the PID file' . "\n"
  211. . ' -r --project-dir=<dir> The project directory.' . "\n"
  212. . ' -s --status-dir=<dir> The status directory to use.' . "\n"
  213. . ' -w --working-dir=<dir> The working directory.' . "\n"
  214. . ' -v --verbose=<level> The level of information to log (default 2).' . "\n"
  215. . ' -o --once Run once and exit.' . "\n"
  216. . ' -d --daemon Daemon, detach and run in the background' . "\n"
  217. . ' --version Prints the version of Xinc.' . "\n"
  218. . ' -h --help Prints this help message.' . "\n";
  219. }
  220. /**
  221. * Prints the startup information of xinc
  222. *
  223. * @return void
  224. */
  225. public function logStartupSettings()
  226. {
  227. $logger = \Xinc\Core\Logger::getInstance();
  228. $logger->info('Starting up Xinc');
  229. $logger->info('- Version: ' . Xinc::VERSION);
  230. $logger->info('- Workingdir: ' . $this->options['working-dir']);
  231. $logger->info('- Projectdir: ' . $this->options['project-dir']);
  232. $logger->info('- Statusdir: ' . $this->options['status-dir']);
  233. $logger->info('- Log Level: ' . $this->options['verbose']);
  234. }
  235. /**
  236. * Prints the version of xinc
  237. */
  238. public function logVersion()
  239. {
  240. \Xinc\Core\Logger::getInstance()->info('Xinc version ' . Xinc::VERSION);
  241. }
  242. /**
  243. * Initialize the logger with path to file and verbosity
  244. *
  245. * @return void
  246. */
  247. public function initLogger()
  248. {
  249. $logger = \Xinc\Core\Logger::getInstance();
  250. $logger->setLogLevel($this->options['verbose']);
  251. $logger->setXincLogFile($this->options['log-file']);
  252. }
  253. /**
  254. * Initialize the Plugins
  255. * TODO: Not yet done only Sunrise is registered as engine by hand.
  256. *
  257. * @return void
  258. * @TODO Needs work.
  259. */
  260. protected function initPlugins()
  261. {
  262. \Xinc\Core\Plugin\Repository::getInstance()->loadPluginConfig();
  263. }
  264. /**
  265. * Initialize the daemon
  266. *
  267. * @return void
  268. */
  269. protected function initDaemon()
  270. {
  271. $daemon = Daemon::getInstance();
  272. if (!$daemon) {
  273. throw new \Exception(
  274. 'Couldn\'t create instance, hopefully you got some error messages on console or in the log file.'
  275. );
  276. }
  277. if (isset($this->options['once'])) {
  278. $daemon->setRunOnce();
  279. }
  280. $daemon->setWorkingDir($this->options['working-dir']);
  281. $daemon->setProjectDir($this->options['project-dir']);
  282. $daemon->setStatusDir($this->options['status-dir']);
  283. if (isset($this->options['project-file'])) {
  284. $daemon->addProjectFiles($this->options['project-file']);
  285. }
  286. return $daemon;
  287. }
  288. public static function execute()
  289. {
  290. try {
  291. $xinc = new self();
  292. $xinc->parseCliOptions();
  293. $xinc->initLogger();
  294. $xinc->initPlugins();
  295. $xinc->validateCliOptions();
  296. $daemon = $xinc->initDaemon();
  297. $daemon->run();
  298. } catch (\Exception $e) {
  299. echo $e->getMessage();
  300. exit(1);
  301. }
  302. }
  303. }