/classes/command.php

http://github.com/fuel/oil · PHP · 377 lines · 270 code · 73 blank · 34 comment · 25 complexity · be1cb523bfcae9213716120b88fd63a0 MD5 · raw file

  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP 5.4+ framework.
  4. *
  5. * @package Fuel
  6. * @version 1.9-dev
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2019 Fuel Development Team
  10. * @link https://fuelphp.com
  11. */
  12. namespace Oil;
  13. /**
  14. * Oil\Cli Class
  15. *
  16. * @package Fuel
  17. * @subpackage Oil
  18. * @category Core
  19. */
  20. class Command
  21. {
  22. public static function init($args)
  23. {
  24. \Config::load('oil', true);
  25. // Remove flag options from the main argument list
  26. $args = self::_clear_args($args);
  27. try
  28. {
  29. if ( ! isset($args[1]))
  30. {
  31. if (\Cli::option('v', \Cli::option('version')))
  32. {
  33. \Cli::write('Fuel: '.\Fuel::VERSION.' running in "'.\Fuel::$env.'" mode');
  34. return;
  35. }
  36. static::help();
  37. return;
  38. }
  39. switch ($args[1])
  40. {
  41. case 'g':
  42. case 'generate':
  43. $action = isset($args[2]) ? $args[2] : 'help';
  44. $subfolder = 'orm';
  45. if (is_int(strpos($action, '/')))
  46. {
  47. list($action, $subfolder)=explode('/', $action);
  48. }
  49. switch ($action)
  50. {
  51. case 'config':
  52. case 'controller':
  53. case 'model':
  54. case 'module':
  55. case 'migration':
  56. case 'task':
  57. case 'package':
  58. call_user_func('Oil\Generate::'.$action, array_slice($args, 3));
  59. break;
  60. case 'views':
  61. call_user_func('Oil\Generate::views', array_slice($args, 3), $subfolder);
  62. break;
  63. case 'admin':
  64. call_user_func('Oil\Generate_Admin::forge', array_slice($args, 3), $subfolder);
  65. break;
  66. case 'scaffold':
  67. call_user_func('Oil\Generate_Scaffold::forge', array_slice($args, 3), $subfolder);
  68. break;
  69. default:
  70. Generate::help();
  71. }
  72. break;
  73. case 'c':
  74. case 'console':
  75. if (isset($args[2]) and $args[2] == 'help')
  76. {
  77. Console::help();
  78. }
  79. else
  80. {
  81. new Console;
  82. }
  83. break;
  84. case 'p':
  85. case 'package':
  86. $action = isset($args[2]) ? $args[2] : 'help';
  87. switch ($action)
  88. {
  89. case 'install':
  90. case 'uninstall':
  91. call_fuel_func_array('Oil\Package::'.$action, array_slice($args, 3));
  92. break;
  93. default:
  94. Package::help();
  95. }
  96. break;
  97. case 'r':
  98. case 'refine':
  99. $task = isset($args[2]) ? $args[2] : null;
  100. call_user_func('Oil\Refine::run', $task, array_slice($args, 3));
  101. break;
  102. case 't':
  103. case 'test':
  104. if (isset($args[2]) and $args[2] == 'help')
  105. {
  106. $output = <<<HELP
  107. Usage:
  108. php oil [t|test]
  109. Runtime options:
  110. --file=<file> # Run a test on a specific file only.
  111. --group=<group> # Only runs tests from the specified group(s).
  112. --exclude-group=<group> # Exclude tests from the specified group(s).
  113. --testsuite=<testsuite> # Only runs tests from the specified testsuite(s).
  114. --coverage-clover=<file> # Generate code coverage report in Clover XML format.
  115. --coverage-html=<dir> # Generate code coverage report in HTML format.
  116. --coverage-php=<file> # Serialize PHP_CodeCoverage object to file.
  117. --coverage-text=<file> # Generate code coverage report in text format.
  118. --log-junit=<file> # Generate report of test execution in JUnit XML format to file.
  119. --debug # Display debugging information during test execution.
  120. Description:
  121. Run phpunit on all or a subset of tests defined for the current application.
  122. Examples:
  123. php oil test
  124. Documentation:
  125. https://fuelphp.com/docs/packages/oil/test.html
  126. HELP;
  127. \Cli::write($output);
  128. }
  129. else
  130. {
  131. $phpunit_command = \Config::get('oil.phpunit.binary_path', 'phpunit');
  132. // Check if we might be using the phar library
  133. $is_phar = false;
  134. foreach(explode(':', getenv('PATH')) as $path)
  135. {
  136. if (is_file($path.DS.$phpunit_command))
  137. {
  138. $handle = fopen($path.DS.$phpunit_command, 'r');
  139. $is_phar = fread($handle, 18) == '#!/usr/bin/env php';
  140. fclose($handle);
  141. if ($is_phar)
  142. {
  143. break;
  144. }
  145. }
  146. }
  147. // Suppressing this because if the file does not exist... well thats a bad thing and we can't really check
  148. // I know that supressing errors is bad, but if you're going to complain: shut up. - Phil
  149. $phpunit_autoload_path = \Config::get('oil.phpunit.autoload_path', 'PHPUnit/Autoload.php' );
  150. @include_once $phpunit_autoload_path;
  151. // Attempt to load PHUnit. If it fails, we are done.
  152. if ( ! $is_phar and ! (class_exists('PHPUnit_Framework_TestCase') or class_exists('PHPUnit\Framework\TestCase')))
  153. {
  154. throw new Exception('PHPUnit does not appear to be installed.'.PHP_EOL.PHP_EOL."\tPlease visit https://phpunit.de and install.");
  155. }
  156. // Check for a custom phpunit config, but default to the one from core
  157. if (is_file(APPPATH.'phpunit.xml'))
  158. {
  159. $phpunit_config = APPPATH.'phpunit.xml';
  160. }
  161. else
  162. {
  163. $phpunit_config = COREPATH.'phpunit.xml';
  164. }
  165. // CD to the root of Fuel and call up phpunit with the path to our config
  166. $command = 'cd '.DOCROOT.'; '.$phpunit_command.' -c "'.$phpunit_config.'"';
  167. // Respect the group options
  168. \Cli::option('group') and $command .= ' --group '.\Cli::option('group');
  169. \Cli::option('exclude-group') and $command .= ' --exclude-group '.\Cli::option('exclude-group');
  170. // Respect the testsuite options
  171. \Cli::option('testsuite') and $command .= ' --testsuite '.\Cli::option('testsuite');
  172. // Respect the debug options
  173. \Cli::option('debug') and $command .= ' --debug';
  174. // Respect the coverage-html option
  175. \Cli::option('coverage-html') and $command .= ' --coverage-html '.\Cli::option('coverage-html');
  176. \Cli::option('coverage-clover') and $command .= ' --coverage-clover '.\Cli::option('coverage-clover');
  177. \Cli::option('coverage-text') and $command .= ' --coverage-text='.\Cli::option('coverage-text');
  178. \Cli::option('coverage-php') and $command .= ' --coverage-php '.\Cli::option('coverage-php');
  179. \Cli::option('log-junit') and $command .= ' --log-junit '.\Cli::option('log-junit');
  180. \Cli::option('file') and $command .= ' '.\Cli::option('file');
  181. \Cli::write('Tests Running...This may take a few moments.', 'green');
  182. $return_code = 0;
  183. foreach(explode(';', $command) as $c)
  184. {
  185. passthru($c, $return_code_task);
  186. // Return failure if any subtask fails
  187. $return_code |= $return_code_task;
  188. }
  189. exit($return_code);
  190. }
  191. break;
  192. case 's':
  193. case 'server':
  194. if (isset($args[2]) and $args[2] == 'help')
  195. {
  196. $output = <<<HELP
  197. Usage:
  198. php oil [s|server]
  199. Runtime options:
  200. --php=<file> # The full pathname of your PHP-CLI binary if it's not in the path.
  201. --port=<port> # TCP port number the webserver should listen too. Defaults to 8000.
  202. --host=<host> # Hostname the webserver should run at. Defaults to "localhost".
  203. --docroot=<dir> # Your FuelPHP docroot. Defaults to "public".
  204. --router=<file> # PHP router script. Defaults to "fuel/packages/oil/phpserver.php".
  205. Description:
  206. Starts a local webserver to run your FuelPHP application, using PHP 5.4+ internal webserver.
  207. Examples:
  208. php oil server -p=8080
  209. Documentation:
  210. https://fuelphp.com/docs/packages/oil/server.html
  211. HELP;
  212. \Cli::write($output);
  213. }
  214. else
  215. {
  216. if (version_compare(PHP_VERSION, '5.4.0') < 0)
  217. {
  218. \Cli::write('The PHP built-in webserver is only available on PHP 5.4+', 'red');
  219. break;
  220. }
  221. $php = \Cli::option('php', 'php');
  222. $port = \Cli::option('p', \Cli::option('port', '8000'));
  223. $host = \Cli::option('h', \Cli::option('host', 'localhost'));
  224. $docroot = \Cli::option('d', \Cli::option('docroot', 'public'));
  225. $router = \Cli::option('r', \Cli::option('router', __DIR__.DS.'..'.DS.'phpserver.php'));
  226. \Cli::write("Listening on http://$host:$port");
  227. \Cli::write("Document root is $docroot");
  228. \Cli::write("Press Ctrl-C to quit.");
  229. passthru("$php -S $host:$port -t $docroot $router");
  230. }
  231. break;
  232. case 'create':
  233. \Cli::write('You can not use "oil create", a valid FuelPHP installation already exists in this directory', 'red');
  234. break;
  235. default:
  236. static::help();
  237. }
  238. }
  239. catch (\Exception $e)
  240. {
  241. static::print_exception($e);
  242. exit(1);
  243. }
  244. }
  245. protected static function print_exception(\Exception $ex)
  246. {
  247. // create the error message, log and display it
  248. $msg = $ex->getCode().' - '.$ex->getMessage().' in '.$ex->getFile().' on line '.$ex->getLine();
  249. logger(\Fuel::L_ERROR, $msg);
  250. \Cli::error('Uncaught exception '.get_class($ex).': '.$msg);
  251. // print a trace if not in production, don't want to spoil external logging
  252. if (\Fuel::$env != \Fuel::PRODUCTION)
  253. {
  254. \Cli::error('Callstack: ');
  255. \Cli::error($ex->getTraceAsString());
  256. }
  257. \Cli::beep();
  258. \Cli::option('speak') and `say --voice="Trinoids" "{$ex->getMessage()}"`;
  259. // print any previous exception(s) too...
  260. if (($previous = $ex->getPrevious()) != null)
  261. {
  262. \Cli::error('');
  263. \Cli::error('Previous exception: ');
  264. static::print_exception($previous);
  265. }
  266. }
  267. public static function help()
  268. {
  269. echo <<<HELP
  270. Usage:
  271. php oil [console|generate|package|refine|help|server|test]
  272. Runtime options:
  273. -f, [--force] # Overwrite files that already exist
  274. -s, [--skip] # Skip files that already exist
  275. -q, [--quiet] # Supress status output
  276. -t, [--speak] # Speak errors in a robot voice
  277. Description:
  278. The 'oil' command can be used in several ways to facilitate quick development, help with
  279. testing your application and for running Tasks.
  280. Environment:
  281. If you want to specify a specific environment oil has to run in, overload the environment
  282. variable on the commandline: FUEL_ENV=staging php oil <commands>
  283. More information:
  284. You can pass the parameter "help" to each of the defined command to get information
  285. about that specific command: php oil package help
  286. Documentation:
  287. https://docs.fuelphp.com/packages/oil/intro.html
  288. HELP;
  289. }
  290. protected static function _clear_args($actions = array())
  291. {
  292. foreach ($actions as $key => $action)
  293. {
  294. if (substr($action, 0, 1) === '-')
  295. {
  296. unset($actions[$key]);
  297. }
  298. // get rid of any junk added by Powershell on Windows...
  299. isset($actions[$key]) and $actions[$key] = trim($actions[$key]);
  300. }
  301. return $actions;
  302. }
  303. }
  304. /* End of file oil/classes/command.php */