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