environment.inc

  1. 8.0.x includes/environment.inc
  2. 8.0.x commands/core/drupal/environment.inc
  3. 6.x includes/environment.inc
  4. 6.x commands/core/drupal/environment.inc
  5. 7.x includes/environment.inc
  6. 7.x commands/core/drupal/environment.inc
  7. 3.x includes/environment.inc
  8. 4.x commands/core/drupal/environment.inc
  9. 4.x includes/environment.inc
  10. 5.x commands/core/drupal/environment.inc
  11. 5.x includes/environment.inc
  12. master commands/core/drupal/environment.inc
  13. master includes/environment.inc

Functions used by drush to query the environment and setting the current configuration.

Bootstrapping now occurs in bootstrap.inc.

See also

includes/bootstrap.inc

Functions

Namesort descending Description
drush_bit_bucket Checks operating system and returns supported bit bucket folder.
drush_build_drush_command Build a drush command suitable for use for Drush to call itself e.g. in backend_invoke.
drush_conf_path This is a copy of Drupal's conf_path function, taken from D7 and adjusted slightly to search from the selected Drupal Root.
drush_cwd Returns the current working directory.
drush_directory_cache The path to the global cache directory.
drush_drupal_required_modules
drush_drupal_sitewide_directory Returns the sitewide Drupal directory for extensions.
drush_error_handler Log PHP errors to the Drush log. This is in effect until Drupal's error handler takes over.
drush_extension_check_incompatibility Test compatibility of a extension with version of drupal core and php.
drush_extension_get_name Gets the extension name.
drush_extension_get_path Gets the extension path.
drush_extension_get_type Gets the extension type.
drush_file_get_private Return the path to private files directory.
drush_file_get_public Return the path to public files directory.
drush_find_drush Determine a proper way to call drush again
drush_get_drupal_core_compatibility Helper function to get core compatibility constant.
drush_get_extensions Get complete information for all available extensions (modules and themes).
drush_get_tar_executable Return tar executable name specific for the current OS
drush_get_username Return the name of the user running drush.
drush_has_bash Checks if the operating system has bash.
drush_is_cygwin Check if the operating system is Winodws running some variant of cygwin -- either Cygwin or the MSYSGIT shell. If you care which is which, test mingw first.
drush_is_local_host Make a determination whether or not the given host is local or not.
drush_is_mingw
drush_is_osx Check if the operating system is OS X. This will return TRUE for Mac OS X (Darwin).
drush_is_windows Check if the operating system is Windows. This will return TRUE under DOS, Powershell Cygwin and MSYSGIT shells, so test for the Windows variant FIRST if you care.
drush_locate_root Exhaustive depth-first search to try and locate the Drupal root directory. This makes it possible to run Drush from a subdirectory of the drupal root.
drush_read_drush_info Read the drush info file.
drush_server_home Return the user's home directory.
drush_set_environment_vars Set Env. Variables for given site-alias.
drush_site_dir_lookup_from_hostname Lookup a site's directory via the sites.php file given a hostname.
drush_site_path Like Drupal conf_path, but searching from beneath. Allows proper site uri detection in site sub-directories.
drush_theme_get_admin Return the administration theme.
drush_theme_get_default Return the default theme.
drush_valid_db_credentials Tests the currently loaded database credentials to ensure a database connection can be made.
drush_valid_root Checks whether given path qualifies as a Drupal root.
drush_verify_cli Verify that we are running PHP through the command line interface.
_drush_convert_path Converts a Windows path (dir1\dir2\dir3) into a Unix path (dir1/dir2/dir3). Also converts a cygwin "drive emulation" path (/cygdrive/c/dir1) into a proper drive path, still with Unix slashes (c:/dir1).
_drush_environment_check_php_ini Evaluate the environment before command bootstrapping begins. If the php environment is too restrictive, then notify the user that a setting change is needed and abort.
_drush_get_os Return the OS we are running under.
_drush_php_ini_loaded_file_message Returns a localizable message about php.ini that varies depending on whether the php_ini_loaded_file() is available or not.
_drush_postmortem Evalute the environment after an abnormal termination and see if we can determine any configuration settings that the user might want to adjust.
_drush_shift_path_up Returns parent directory.
_drush_test_os

File

includes/environment.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Functions used by drush to query the environment and
  5. * setting the current configuration.
  6. *
  7. * Bootstrapping now occurs in bootstrap.inc.
  8. *
  9. * @see includes/bootstrap.inc
  10. */
  11. use Drush\Log\LogLevel;
  12. /**
  13. * Log PHP errors to the Drush log. This is in effect until Drupal's error
  14. * handler takes over.
  15. */
  16. function drush_error_handler($errno, $message, $filename, $line, $context) {
  17. // E_DEPRECATED was added in PHP 5.3. Drupal 6 will not fix all the
  18. // deprecated errors, but suppresses them. So we suppress them as well.
  19. if (defined('E_DEPRECATED')) {
  20. $errno = $errno & ~E_DEPRECATED;
  21. }
  22. // "error_reporting" is usually set in php.ini, but may be changed by
  23. // drush_errors_on() and drush_errors_off().
  24. if ($errno & error_reporting()) {
  25. // By default we log notices.
  26. $type = drush_get_option('php-notices', 'notice');
  27. // Bitmask value that constitutes an error needing to be logged.
  28. $error = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR;
  29. if ($errno & $error) {
  30. $type = 'error';
  31. }
  32. // Bitmask value that constitutes a warning being logged.
  33. $warning = E_WARNING | E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING;
  34. if ($errno & $warning) {
  35. $type = LogLevel::WARNING;
  36. }
  37. drush_log($message . ' ' . basename($filename) . ':' . $line, $type);
  38. return TRUE;
  39. }
  40. }
  41. /**
  42. * Returns a localizable message about php.ini that
  43. * varies depending on whether the php_ini_loaded_file()
  44. * is available or not.
  45. */
  46. function _drush_php_ini_loaded_file_message() {
  47. if (function_exists('php_ini_loaded_file')) {
  48. return dt('Please check your configuration settings in !phpini or in your drush.ini file; see examples/example.drush.ini for details.', array('!phpini' => php_ini_loaded_file()));
  49. }
  50. else {
  51. return dt('Please check your configuration settings in your php.ini file or in your drush.ini file; see examples/example.drush.ini for details.');
  52. }
  53. }
  54. /**
  55. * Evalute the environment after an abnormal termination and
  56. * see if we can determine any configuration settings that the user might
  57. * want to adjust.
  58. */
  59. function _drush_postmortem() {
  60. // Make sure that the memory limit has been bumped up from the minimum default value of 32M.
  61. $php_memory_limit = drush_memory_limit();
  62. if (($php_memory_limit > 0) && ($php_memory_limit <= 32*DRUSH_KILOBYTE*DRUSH_KILOBYTE)) {
  63. drush_set_error('DRUSH_MEMORY_LIMIT', dt('Your memory limit is set to !memory_limit; Drush needs as much memory to run as Drupal. !php_ini_msg', array('!memory_limit' => $php_memory_limit / (DRUSH_KILOBYTE*DRUSH_KILOBYTE) . 'M', '!php_ini_msg' => _drush_php_ini_loaded_file_message())));
  64. }
  65. }
  66. /**
  67. * Evaluate the environment before command bootstrapping
  68. * begins. If the php environment is too restrictive, then
  69. * notify the user that a setting change is needed and abort.
  70. */
  71. function _drush_environment_check_php_ini() {
  72. $ini_checks = array('safe_mode' => '', 'open_basedir' => '', 'disable_functions' => array('exec', 'system'), 'disable_classes' => '');
  73. // Test to insure that certain php ini restrictions have not been enabled
  74. $prohibited_list = array();
  75. foreach ($ini_checks as $prohibited_mode => $disallowed_value) {
  76. $ini_value = ini_get($prohibited_mode);
  77. $invalid_value = FALSE;
  78. if (empty($disallowed_value)) {
  79. $invalid_value = !empty($ini_value) && (strcasecmp($ini_value, 'off') != 0);
  80. }
  81. else {
  82. foreach ($disallowed_value as $test_value) {
  83. if (preg_match('/(^|,)' . $test_value . '(,|$)/', $ini_value)) {
  84. $invalid_value = TRUE;
  85. }
  86. }
  87. }
  88. if ($invalid_value) {
  89. $prohibited_list[] = $prohibited_mode;
  90. }
  91. }
  92. if (!empty($prohibited_list)) {
  93. drush_log(dt('The following restricted PHP modes have non-empty values: !prohibited_list. This configuration is incompatible with drush. !php_ini_msg', array('!prohibited_list' => implode(' and ', $prohibited_list), '!php_ini_msg' => _drush_php_ini_loaded_file_message())), LogLevel::ERROR);
  94. }
  95. return TRUE;
  96. }
  97. /**
  98. * Returns the current working directory.
  99. *
  100. * This is the directory as it was when drush was started, not the
  101. * directory we are currently in. For that, use getcwd() directly.
  102. */
  103. function drush_cwd() {
  104. if ($path = drush_get_context('DRUSH_OLDCWD')) {
  105. return $path;
  106. }
  107. // We use PWD if available because getcwd() resolves symlinks, which
  108. // could take us outside of the Drupal root, making it impossible to find.
  109. // $_SERVER['PWD'] isn't set on windows and generates a Notice.
  110. $path = isset($_SERVER['PWD']) ? $_SERVER['PWD'] : '';
  111. if (empty($path)) {
  112. $path = getcwd();
  113. }
  114. // Convert windows paths.
  115. $path = _drush_convert_path($path);
  116. // Save original working dir case some command wants it.
  117. drush_set_context('DRUSH_OLDCWD', $path);
  118. return $path;
  119. }
  120. /**
  121. * Converts a Windows path (dir1\dir2\dir3) into a Unix path (dir1/dir2/dir3).
  122. * Also converts a cygwin "drive emulation" path (/cygdrive/c/dir1) into a
  123. * proper drive path, still with Unix slashes (c:/dir1).
  124. */
  125. function _drush_convert_path($path) {
  126. $path = str_replace('\\','/', $path);
  127. if (drush_is_windows(_drush_get_os()) && !drush_is_cygwin(_drush_get_os())) {
  128. $path = preg_replace('/^\/cygdrive\/([A-Za-z])(.*)$/', '\1:\2', $path);
  129. }
  130. return $path;
  131. }
  132. /**
  133. * Returns parent directory.
  134. *
  135. * @param string
  136. * Path to start from.
  137. *
  138. * @return string
  139. * Parent path of given path.
  140. */
  141. function _drush_shift_path_up($path) {
  142. if (empty($path)) {
  143. return FALSE;
  144. }
  145. $path = explode('/', $path);
  146. // Move one directory up.
  147. array_pop($path);
  148. return implode('/', $path);
  149. }
  150. /**
  151. * Like Drupal conf_path, but searching from beneath.
  152. * Allows proper site uri detection in site sub-directories.
  153. *
  154. * Essentially looks for a settings.php file. Drush uses this
  155. * function to find a usable site based on the user's current
  156. * working directory.
  157. *
  158. * @param string
  159. * Search starting path. Defaults to current working directory.
  160. *
  161. * @return
  162. * Current site path (folder containing settings.php) or FALSE if not found.
  163. */
  164. function drush_site_path($path = NULL) {
  165. $site_path = FALSE;
  166. $path = empty($path) ? drush_cwd() : $path;
  167. // Check the current path.
  168. if (file_exists($path . '/settings.php')) {
  169. $site_path = $path;
  170. }
  171. else {
  172. // Move up dir by dir and check each.
  173. // Stop if we get to a Drupal root. We don't care
  174. // if it is DRUSH_SELECTED_DRUPAL_ROOT or some other root.
  175. while (($path = _drush_shift_path_up($path)) && !drush_valid_root($path)) {
  176. if (file_exists($path . '/settings.php')) {
  177. $site_path = $path;
  178. break;
  179. }
  180. }
  181. }
  182. $site_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
  183. if (file_exists($site_root . '/sites/sites.php')) {
  184. $sites = array();
  185. // This will overwrite $sites with the desired mappings.
  186. include($site_root . '/sites/sites.php');
  187. // We do a reverse lookup here to determine the URL given the site key.
  188. if ($match = array_search($site_path, $sites)) {
  189. $site_path = $match;
  190. }
  191. }
  192. // Last resort: try from site root
  193. if (!$site_path) {
  194. if ($site_root) {
  195. if (file_exists($site_root . '/sites/default/settings.php')) {
  196. $site_path = $site_root . '/sites/default';
  197. }
  198. }
  199. }
  200. return $site_path;
  201. }
  202. /**
  203. * Lookup a site's directory via the sites.php file given a hostname.
  204. *
  205. * @param $hostname
  206. * The hostname of a site. May be converted from URI.
  207. *
  208. * @return $dir
  209. * The directory associated with that hostname or FALSE if not found.
  210. */
  211. function drush_site_dir_lookup_from_hostname($hostname, $site_root = NULL) {
  212. if (!isset($site_root)) {
  213. $site_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
  214. }
  215. if (!empty($site_root) && file_exists($site_root . '/sites/sites.php')) {
  216. $sites = array();
  217. // This will overwrite $sites with the desired mappings.
  218. include($site_root . '/sites/sites.php');
  219. return isset($sites[$hostname]) ? $sites[$hostname] : FALSE;
  220. }
  221. else {
  222. return FALSE;
  223. }
  224. }
  225. /**
  226. * This is a copy of Drupal's conf_path function, taken from D7 and
  227. * adjusted slightly to search from the selected Drupal Root.
  228. *
  229. * Drush uses this routine to find a usable site based on a URI
  230. * passed in via a site alias record or the --uri commandline option.
  231. *
  232. * Drush uses Drupal itself (specifically, the Drupal conf_path function)
  233. * to bootstrap the site itself. If the implementation of conf_path
  234. * changes, the site should still bootstrap correctly; the only consequence
  235. * of this routine not working is that drush configuration files
  236. * (drushrc.php) stored with the site's drush folders might not be found.
  237. */
  238. function drush_conf_path($server_uri, $require_settings = TRUE) {
  239. $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
  240. if(empty($drupal_root) || empty($server_uri)) {
  241. return NULL;
  242. }
  243. $parsed_uri = parse_url($server_uri);
  244. if (is_array($parsed_uri) && !array_key_exists('scheme', $parsed_uri)) {
  245. $parsed_uri = parse_url('http://' . $server_uri);
  246. }
  247. if (!is_array($parsed_uri)) {
  248. return NULL;
  249. }
  250. $server_host = $parsed_uri['host'];
  251. if (array_key_exists('path', $parsed_uri)) {
  252. $server_uri = $parsed_uri['path'] . '/index.php';
  253. }
  254. else {
  255. $server_uri = "/index.php";
  256. }
  257. $confdir = 'sites';
  258. $sites = array();
  259. if (file_exists($drupal_root . '/' . $confdir . '/sites.php')) {
  260. // This will overwrite $sites with the desired mappings.
  261. include($drupal_root . '/' . $confdir . '/sites.php');
  262. }
  263. $uri = explode('/', $server_uri);
  264. $server = explode('.', implode('.', array_reverse(explode(':', rtrim($server_host, '.')))));
  265. for ($i = count($uri) - 1; $i > 0; $i--) {
  266. for ($j = count($server); $j > 0; $j--) {
  267. $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
  268. if (isset($sites[$dir]) && file_exists($drupal_root . '/' . $confdir . '/' . $sites[$dir])) {
  269. $dir = $sites[$dir];
  270. }
  271. if (file_exists($drupal_root . '/' . $confdir . '/' . $dir . '/settings.php') || (!$require_settings && file_exists(DRUPAL_ROOT . '/' . $confdir . '/' . $dir))) {
  272. $conf = "$confdir/$dir";
  273. return $conf;
  274. }
  275. }
  276. }
  277. $conf = "$confdir/default";
  278. return $conf;
  279. }
  280. /**
  281. * Exhaustive depth-first search to try and locate the Drupal root directory.
  282. * This makes it possible to run Drush from a subdirectory of the drupal root.
  283. *
  284. * @param
  285. * Search start path. Defaults to current working directory.
  286. * @return
  287. * A path to drupal root, or FALSE if not found.
  288. */
  289. function drush_locate_root($start_path = NULL) {
  290. $drupal_root = FALSE;
  291. $start_path = empty($start_path) ? drush_cwd() : $start_path;
  292. foreach (array(TRUE, FALSE) as $follow_symlinks) {
  293. $path = $start_path;
  294. if ($follow_symlinks && is_link($path)) {
  295. $path = realpath($path);
  296. }
  297. // Check the start path.
  298. if (drush_valid_root($path)) {
  299. $drupal_root = $path;
  300. break;
  301. }
  302. else {
  303. // Move up dir by dir and check each.
  304. while ($path = _drush_shift_path_up($path)) {
  305. if ($follow_symlinks && is_link($path)) {
  306. $path = realpath($path);
  307. }
  308. if (drush_valid_root($path)) {
  309. $drupal_root = $path;
  310. break 2;
  311. }
  312. }
  313. }
  314. }
  315. return $drupal_root;
  316. }
  317. /**
  318. * Checks whether given path qualifies as a Drupal root.
  319. *
  320. * @param string
  321. * Path to check.
  322. *
  323. * @return string
  324. * The relative path to common.inc (varies by Drupal version), or FALSE if not
  325. * a Drupal root.
  326. */
  327. function drush_valid_root($path) {
  328. $bootstrap_class = drush_bootstrap_class_for_root($path);
  329. return $bootstrap_class != NULL;
  330. }
  331. /**
  332. * Tests the currently loaded database credentials to ensure a database connection can be made.
  333. */
  334. function drush_valid_db_credentials() {
  335. try {
  336. $sql = drush_sql_get_class();
  337. if (!$sqlVersion = drush_sql_get_version()) {
  338. return FALSE;
  339. }
  340. if (!$sqlVersion->valid_credentials($sql->db_spec())) {
  341. return FALSE;
  342. }
  343. return $sql->query('SELECT 1;');
  344. }
  345. catch (Exception $e) {
  346. return FALSE;
  347. }
  348. }
  349. /**
  350. * Determine a proper way to call drush again
  351. *
  352. * This check if we were called directly or as an argument to some
  353. * wrapper command (php and sudo are checked now).
  354. *
  355. * Calling ./drush.php directly yields the following environment:
  356. *
  357. * _SERVER["argv"][0] => ./drush.php
  358. *
  359. * Calling php ./drush.php also yields the following:
  360. *
  361. * _SERVER["argv"][0] => ./drush.php
  362. *
  363. * Note that the $_ global is defined only in bash and therefore cannot
  364. * be relied upon.
  365. *
  366. * The DRUSH_COMMAND constant is initialised to the value of this
  367. * function when environment.inc is loaded.
  368. *
  369. * @see DRUSH_COMMAND
  370. */
  371. function drush_find_drush() {
  372. $drush = realpath($_SERVER['argv']['0']);
  373. // TODO: On Windows, if we leave $drush as-is, then callbacks will
  374. // be done just as we were called by the batch file: php.exe C:\path\drush.php
  375. // We could also convert drush.php to drush.bat to run the batch file again,
  376. // but this works just as well.
  377. return $drush;
  378. }
  379. /**
  380. * Verify that we are running PHP through the command line interface.
  381. *
  382. * This function is useful for making sure that code cannot be run via the web server,
  383. * such as a function that needs to write files to which the web server should not have
  384. * access to.
  385. *
  386. * @return
  387. * A boolean value that is true when PHP is being run through the command line,
  388. * and false if being run through cgi or mod_php.
  389. */
  390. function drush_verify_cli() {
  391. return (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0));
  392. }
  393. /**
  394. * Build a drush command suitable for use for Drush to call itself
  395. * e.g. in backend_invoke.
  396. */
  397. function drush_build_drush_command($drush_path = NULL, $php = NULL, $os = NULL, $remote_command = FALSE, $environment_variables = array()) {
  398. $os = _drush_get_os($os);
  399. $additional_options = '';
  400. $prefix = '';
  401. if (!$drush_path) {
  402. if (!$remote_command) {
  403. $drush_path = DRUSH_COMMAND;
  404. }
  405. else {
  406. $drush_path = drush_is_windows($os) ? 'drush.bat' : 'drush';
  407. }
  408. }
  409. // If the path to drush points to drush.php, then we will need to
  410. // run it via php rather than direct execution. By default, we
  411. // will use 'php' unless something more specific was passed in
  412. // via the --php flag.
  413. if (substr($drush_path, -4) == ".php") {
  414. if (!isset($php)) {
  415. $php = drush_get_option('php');
  416. if (!isset($php)) {
  417. $php = 'php';
  418. }
  419. }
  420. if (isset($php) && ($php != "php")) {
  421. $additional_options .= ' --php=' . drush_escapeshellarg($php, $os);
  422. }
  423. // We will also add in the php options from --php-options
  424. $prefix .= drush_escapeshellarg($php, $os);
  425. $php_options = implode(' ', drush_get_context_options('php-options'));
  426. if (!empty($php_options)) {
  427. $prefix .= ' ' . $php_options;
  428. $additional_options .= ' --php-options=' . drush_escapeshellarg($php_options, $os);
  429. }
  430. }
  431. else {
  432. // Set environment variables to propogate config to redispatched calls.
  433. if (drush_has_bash($os)) {
  434. if ($php) {
  435. $environment_variables['DRUSH_PHP'] = $php;
  436. }
  437. if ($php_options_alias = drush_get_option('php-options', NULL, 'alias')) {
  438. $environment_variables['PHP_OPTIONS'] = $php_options_alias;
  439. }
  440. $columns = drush_get_context('DRUSH_COLUMNS');
  441. if (($columns) && ($columns != 80)) {
  442. $environment_variables['COLUMNS'] = $columns;
  443. }
  444. }
  445. }
  446. // Add environmental variables, if present
  447. if (!empty($environment_variables)) {
  448. $prefix .= ' env';
  449. foreach ($environment_variables as $key=>$value) {
  450. $prefix .= ' ' . drush_escapeshellarg($key, $os) . '=' . drush_escapeshellarg($value, $os);
  451. }
  452. }
  453. return trim($prefix . ' ' . drush_escapeshellarg($drush_path, $os) . $additional_options);
  454. }
  455. /**
  456. * Check if the operating system is Windows.
  457. * This will return TRUE under DOS, Powershell
  458. * Cygwin and MSYSGIT shells, so test for the
  459. * Windows variant FIRST if you care.
  460. */
  461. function drush_is_windows($os = NULL) {
  462. return _drush_test_os($os, array("WIN","CYGWIN","CWRSYNC","MINGW"));
  463. }
  464. /**
  465. * Check if the operating system is Winodws
  466. * running some variant of cygwin -- either
  467. * Cygwin or the MSYSGIT shell. If you care
  468. * which is which, test mingw first.
  469. */
  470. function drush_is_cygwin($os = NULL) {
  471. return _drush_test_os($os, array("CYGWIN","CWRSYNC","MINGW"));
  472. }
  473. function drush_is_mingw($os = NULL) {
  474. return _drush_test_os($os, array("MINGW"));
  475. }
  476. /**
  477. * Return tar executable name specific for the current OS
  478. */
  479. function drush_get_tar_executable() {
  480. return drush_is_windows() ? (drush_is_mingw() ? "tar.exe" : "bsdtar.exe") : "tar";
  481. }
  482. /**
  483. * Check if the operating system is OS X.
  484. * This will return TRUE for Mac OS X (Darwin).
  485. */
  486. function drush_is_osx($os = NULL) {
  487. return _drush_test_os($os, array("DARWIN"));
  488. }
  489. /**
  490. * Checks if the operating system has bash.
  491. *
  492. * MinGW has bash, but PHP isn't part of MinGW and hence doesn't run in bash.
  493. */
  494. function drush_has_bash($os = NULL) {
  495. return (drush_is_cygwin($os) && !drush_is_mingw($os)) || !drush_is_windows($os);
  496. }
  497. /**
  498. * Checks operating system and returns
  499. * supported bit bucket folder.
  500. */
  501. function drush_bit_bucket() {
  502. if (drush_has_bash()) {
  503. return '/dev/null';
  504. }
  505. else {
  506. return 'nul';
  507. }
  508. }
  509. /**
  510. * Return the OS we are running under.
  511. *
  512. * @return string
  513. * Linux
  514. * WIN* (e.g. WINNT)
  515. * CYGWIN
  516. * MINGW* (e.g. MINGW32)
  517. */
  518. function _drush_get_os($os = NULL) {
  519. // The special os "CWRSYNC" can be used to indicate that we are testing
  520. // a path that will be passed as an argument to cwRsync, which requires
  521. // that the path be converted to /cygdrive/c/path, even on DOS or Powershell.
  522. // The special os "RSYNC" can be used to indicate that we want to assume
  523. // "CWRSYNC" when cwrsync is installed, or default to the local OS otherwise.
  524. if (strtoupper($os) == "RSYNC") {
  525. $os = _drush_get_os("LOCAL");
  526. // For now we assume that cwrsync is always installed on Windows, and never installed son any other platform.
  527. return drush_is_windows($os) ? "CWRSYNC" : $os;
  528. }
  529. // We allow "LOCAL" to document, in instances where some parameters are being escaped
  530. // for use on a remote machine, that one particular parameter will always be used on
  531. // the local machine (c.f. drush_backend_invoke).
  532. if (isset($os) && ($os != "LOCAL")) {
  533. return $os;
  534. }
  535. if (_drush_test_os(getenv("MSYSTEM"), array("MINGW"))) {
  536. return getenv("MSYSTEM");
  537. }
  538. // QUESTION: Can we differentiate between DOS and POWERSHELL? They appear to have the same environment.
  539. // At the moment, it does not seem to matter; they behave the same from PHP.
  540. // At this point we will just return PHP_OS.
  541. return PHP_OS;
  542. }
  543. function _drush_test_os($os, $os_list_to_check) {
  544. $os = _drush_get_os($os);
  545. foreach ($os_list_to_check as $test) {
  546. if (strtoupper(substr($os, 0, strlen($test))) == strtoupper($test)) {
  547. return TRUE;
  548. }
  549. }
  550. return FALSE;
  551. }
  552. /**
  553. * Read the drush info file.
  554. */
  555. function drush_read_drush_info() {
  556. $drush_info_file = dirname(__FILE__) . '/../drush.info';
  557. return parse_ini_file($drush_info_file);
  558. }
  559. /**
  560. * Make a determination whether or not the given
  561. * host is local or not.
  562. *
  563. * @param host
  564. * A hostname, 'localhost' or '127.0.0.1'.
  565. * @return
  566. * True if the host is local.
  567. */
  568. function drush_is_local_host($host) {
  569. // Check to see if the provided host is "local".
  570. // @see hook_drush_sitealias_alter() in drush.api.php.
  571. if (
  572. ($host == 'localhost') ||
  573. ($host == '127.0.0.1')
  574. ) {
  575. return TRUE;
  576. }
  577. return FALSE;
  578. }
  579. /**
  580. * Return the user's home directory.
  581. */
  582. function drush_server_home() {
  583. // Cannot use $_SERVER superglobal since that's empty during UnitUnishTestCase
  584. // getenv('HOME') isn't set on Windows and generates a Notice.
  585. $home = getenv('HOME');
  586. if (!empty($home)) {
  587. // home should never end with a trailing slash.
  588. $home = rtrim($home, '/');
  589. }
  590. elseif (!empty($_SERVER['HOMEDRIVE']) && !empty($_SERVER['HOMEPATH'])) {
  591. // home on windows
  592. $home = $_SERVER['HOMEDRIVE'] . $_SERVER['HOMEPATH'];
  593. // If HOMEPATH is a root directory the path can end with a slash. Make sure
  594. // that doesn't happen.
  595. $home = rtrim($home, '\\/');
  596. }
  597. return empty($home) ? NULL : $home;
  598. }
  599. /**
  600. * Return the name of the user running drush.
  601. */
  602. function drush_get_username() {
  603. $name = NULL;
  604. if (!$name = getenv("username")) { // Windows
  605. if (!$name = getenv("USER")) {
  606. // If USER not defined, use posix
  607. if (function_exists('posix_getpwuid')) {
  608. $processUser = posix_getpwuid(posix_geteuid());
  609. $name = $processUser['name'];
  610. }
  611. }
  612. }
  613. return $name;
  614. }
  615. /**
  616. * The path to the global cache directory.
  617. *
  618. * @param subdir
  619. * Return the specified subdirectory inside the global
  620. * cache directory instead. The subdirectory is created.
  621. */
  622. function drush_directory_cache($subdir = '') {
  623. $cache_locations = array();
  624. if (getenv('CACHE_PREFIX')) {
  625. $cache_locations[getenv('CACHE_PREFIX')] = 'cache';
  626. }
  627. $home = drush_server_home();
  628. if ($home) {
  629. $cache_locations[$home] = '.drush/cache';
  630. }
  631. $cache_locations[drush_find_tmp()] = 'drush-' . drush_get_username() . '/cache';
  632. foreach ($cache_locations as $base => $dir) {
  633. if (!empty($base) && is_writable($base)) {
  634. $cache_dir = $base . '/' . $dir;
  635. if (!empty($subdir)) {
  636. $cache_dir .= '/' . $subdir;
  637. }
  638. if (drush_mkdir($cache_dir)) {
  639. return $cache_dir;
  640. }
  641. else {
  642. // If the base directory is writable, but the cache directory
  643. // is not, then we will get an error. The error will be displayed,
  644. // but we will still call drush_clear_error so that we can go
  645. // on and try the next location to see if we can find a cache
  646. // directory somewhere.
  647. drush_clear_error();
  648. }
  649. }
  650. }
  651. return drush_set_error('DRUSH_NO_WRITABLE_CACHE', dt('Drush must have a writable cache directory; please insure that one of the following locations is writable: @locations',
  652. array('@locations' => implode(',', array_keys($cache_locations)))));
  653. }
  654. /**
  655. * Get complete information for all available extensions (modules and themes).
  656. *
  657. * @return
  658. * An array containing info for all available extensions. In D8, these are Extension objects.
  659. */
  660. function drush_get_extensions($include_hidden = TRUE) {
  661. drush_include_engine('drupal', 'environment');
  662. $extensions = array_merge(drush_get_modules($include_hidden), drush_get_themes($include_hidden));
  663. foreach ($extensions as $name => $extension) {
  664. if (isset($extension->info['name'])) {
  665. $extensions[$name]->label = $extension->info['name'].' ('.$name.')';
  666. }
  667. else {
  668. drush_log(dt("Extension !name provides no human-readable name in .info file.", array('!name' => $name), LogLevel::DEBUG));
  669. $extensions[$name]->label = $name.' ('.$name.')';
  670. }
  671. if (empty($extension->info['package'])) {
  672. $extensions[$name]->info['package'] = dt('Other');
  673. }
  674. }
  675. return $extensions;
  676. }
  677. /**
  678. * Gets the extension name.
  679. *
  680. * @param $info
  681. * The extension info.
  682. * @return string
  683. * The extension name.
  684. */
  685. function drush_extension_get_name($info) {
  686. drush_include_engine('drupal', 'environment');
  687. return _drush_extension_get_name($info);
  688. }
  689. /**
  690. * Gets the extension type.
  691. *
  692. * @param $info
  693. * The extension info.
  694. * @return string
  695. * The extension type.
  696. */
  697. function drush_extension_get_type($info) {
  698. drush_include_engine('drupal', 'environment');
  699. return _drush_extension_get_type($info);
  700. }
  701. /**
  702. * Gets the extension path.
  703. *
  704. * @param $info
  705. * The extension info.
  706. * @return string
  707. * The extension path.
  708. */
  709. function drush_extension_get_path($info) {
  710. drush_include_engine('drupal', 'environment');
  711. return _drush_extension_get_path($info);
  712. }
  713. /**
  714. * Test compatibility of a extension with version of drupal core and php.
  715. *
  716. * @param $file Extension object as returned by system_rebuild_module_data().
  717. * @return FALSE if the extension is compatible.
  718. */
  719. function drush_extension_check_incompatibility($file) {
  720. if (!isset($file->info['core']) || $file->info['core'] != drush_get_drupal_core_compatibility()) {
  721. return 'Drupal';
  722. }
  723. if (version_compare(phpversion(), $file->info['php']) < 0) {
  724. return 'PHP';
  725. }
  726. return FALSE;
  727. }
  728. /**
  729. *
  730. */
  731. function drush_drupal_required_modules($modules) {
  732. drush_include_engine('drupal', 'environment');
  733. return _drush_drupal_required_modules($modules);
  734. }
  735. /**
  736. * Return the default theme.
  737. *
  738. * @return
  739. * Machine name of the default theme.
  740. */
  741. function drush_theme_get_default() {
  742. drush_include_engine('drupal', 'environment');
  743. return _drush_theme_default();
  744. }
  745. /**
  746. * Return the administration theme.
  747. *
  748. * @return
  749. * Machine name of the administration theme.
  750. */
  751. function drush_theme_get_admin() {
  752. drush_include_engine('drupal', 'environment');
  753. return _drush_theme_admin();
  754. }
  755. /**
  756. * Return the path to public files directory.
  757. */
  758. function drush_file_get_public() {
  759. drush_include_engine('drupal', 'environment');
  760. return _drush_file_public_path();
  761. }
  762. /**
  763. * Return the path to private files directory.
  764. */
  765. function drush_file_get_private() {
  766. drush_include_engine('drupal', 'environment');
  767. return _drush_file_private_path();
  768. }
  769. /**
  770. * Returns the sitewide Drupal directory for extensions.
  771. */
  772. function drush_drupal_sitewide_directory($major_version = NULL) {
  773. if (!$major_version) {
  774. $major_version = drush_drupal_major_version();
  775. }
  776. return ($major_version < 8) ? 'sites/all' : '';
  777. }
  778. /**
  779. * Helper function to get core compatibility constant.
  780. *
  781. * @return string
  782. * The Drupal core compatibility constant.
  783. */
  784. function drush_get_drupal_core_compatibility() {
  785. if (defined('DRUPAL_CORE_COMPATIBILITY')) {
  786. return DRUPAL_CORE_COMPATIBILITY;
  787. }
  788. elseif (defined('Drupal::CORE_COMPATIBILITY')) {
  789. return Drupal::CORE_COMPATIBILITY;
  790. }
  791. }
  792. /**
  793. * Set Env. Variables for given site-alias.
  794. */
  795. function drush_set_environment_vars(array $site_record) {
  796. if (!empty($site_record)) {
  797. $os = drush_os($site_record);
  798. if (isset($site_record['#env-vars'])) {
  799. foreach ($site_record['#env-vars'] as $var => $value) {
  800. $env_var = drush_escapeshellarg($var, $os, TRUE) . '=' . drush_escapeshellarg($value, $os, TRUE);
  801. putenv($env_var);
  802. }
  803. }
  804. }
  805. }