bootstrap.inc

  1. 8.0.x tests/bootstrap.inc
  2. 8.0.x includes/bootstrap.inc
  3. 6.x includes/bootstrap.inc
  4. 7.x tests/bootstrap.inc
  5. 7.x includes/bootstrap.inc
  6. 5.x includes/bootstrap.inc
  7. master includes/bootstrap.inc
  8. master tests/bootstrap.inc

Functions

Namesort ascending Description
_drush_bootstrap_selected_uri Find the URI that has been selected by the cwd if it was not previously set via the --uri / -l option
_drush_bootstrap_phases Helper function listing phases.
_drush_bootstrap_output_prepare
drush_select_bootstrap_class Select the bootstrap class to use. If this is called multiple times, the bootstrap class returned might change on subsequent calls, if the root directory changes. Once the bootstrap object starts changing the state of the system, however, it will be…
drush_load_bootstrap_commandfile_at_path Check to see if there is a bootstrap class available at the specified location; if there is, load it.
drush_latch_bootstrap_object Don't allow the bootstrap object to change once we start bootstrapping
drush_has_boostrapped Determine whether a given bootstrap phase has been completed
drush_get_bootstrap_object Get the appropriate bootstrap object. We'll search for a new bootstrap object every time someone asks for one until we start bootstrapping; then we'll returned the same cached one every time.
drush_get_bootstrap_candidate_classnames Find the list of bootstrap classnames available for initializing a CMS with Drush.
drush_get_bootstrap_candidates Return the list of bootstrap objects that are available for initializing a CMS with Drush. We insure that any given candidate class is instantiated only once.
drush_bootstrap_value Helper function to store any context settings that are being validated.
drush_bootstrap_validate Validate whether a bootstrap phase can be reached.
drush_bootstrap_to_phase Bootstrap to the specified phase.
drush_bootstrap_max_to_sitealias Bootstrap the specified site alias. The site alias must be a valid alias to a local site.
drush_bootstrap_max Bootstrap to the highest level possible, without triggering any errors.
drush_bootstrap_error Helper function to collect any errors that occur during the bootstrap process. Always returns FALSE, for convenience.
drush_bootstrap_class_for_root Look up the best bootstrap class for the given location from the set of available candidates.
drush_bootstrap Bootstrap Drush to the desired phase.
drush_autoload Used by a Drush extension to request that its Composer autoload files be loaded by Drush, if they have not already been.

Constants

Namesort ascending Description
DRUSH_BOOTSTRAP_NONE No bootstrap.
DRUSH_BOOTSTRAP_MAX Use drush_bootstrap_max instead of drush_bootstrap_to_phase
DRUSH_BOOTSTRAP_DRUSH @deprecated
DRUSH_BOOTSTRAP_DRUPAL_SITE Set up a Drupal site directory and the correct environment variables to allow Drupal to find the configuration file.
DRUSH_BOOTSTRAP_DRUPAL_ROOT Set up and test for a valid drupal root, either through the -r/--root options, or evaluated based on the current working directory.
DRUSH_BOOTSTRAP_DRUPAL_LOGIN Log in to the initialiased Drupal site.
DRUSH_BOOTSTRAP_DRUPAL_FULL Fully initialize Drupal.
DRUSH_BOOTSTRAP_DRUPAL_DATABASE Connect to the Drupal database using the database credentials loaded during the previous bootstrap phase.
DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION Load the settings from the Drupal sites directory.

File

includes/bootstrap.inc
View source
  1. <?php
  2. use Drush\Log\LogLevel;
  3. /**
  4. * No bootstrap.
  5. *
  6. * Commands that only preflight, but do not bootstrap, should use
  7. * a bootstrap level of DRUSH_BOOTSTRAP_NONE.
  8. */
  9. define('DRUSH_BOOTSTRAP_NONE', -1);
  10. /**
  11. * Use drush_bootstrap_max instead of drush_bootstrap_to_phase
  12. *
  13. * This constant is only usable as the value of the 'bootstrap'
  14. * item of a command object, or as the parameter to
  15. * drush_bootstrap_to_phase. It is not a real bootstrap state.
  16. */
  17. define('DRUSH_BOOTSTRAP_MAX', -2);
  18. /**
  19. * @deprecated
  20. *
  21. * No longer used, but 0 remains reserved. Drush always runs preflight.
  22. * Commands may alternatively use DRUSH_BOOTSTRAP_NONE.
  23. */
  24. define('DRUSH_BOOTSTRAP_DRUSH', 0);
  25. // TODO: Move all of the constants below to a Drupal-specific file.
  26. // We can't do this until commands are declaring which CMS they work
  27. // with, because right now, commands that do not declare a 'bootstrap'
  28. // level default to DRUSH_BOOTSTRAP_DRUPAL_LOGIN, so we need this constant,
  29. // at least, available in non-Drupal contexts.
  30. /**
  31. * Set up and test for a valid drupal root, either through the -r/--root options,
  32. * or evaluated based on the current working directory.
  33. *
  34. * Any code that interacts with an entire Drupal installation, and not a specific
  35. * site on the Drupal installation should use this bootstrap phase.
  36. */
  37. define('DRUSH_BOOTSTRAP_DRUPAL_ROOT', 1);
  38. /**
  39. * Set up a Drupal site directory and the correct environment variables to
  40. * allow Drupal to find the configuration file.
  41. *
  42. * If no site is specified with the -l / --uri options, Drush will assume the
  43. * site is 'default', which mimics Drupal's behaviour.
  44. *
  45. * If you want to avoid this behaviour, it is recommended that you use the
  46. * DRUSH_BOOTSTRAP_DRUPAL_ROOT bootstrap phase instead.
  47. *
  48. * Any code that needs to modify or interact with a specific Drupal site's
  49. * settings.php file should bootstrap to this phase.
  50. */
  51. define('DRUSH_BOOTSTRAP_DRUPAL_SITE', 2);
  52. /**
  53. * Load the settings from the Drupal sites directory.
  54. *
  55. * This phase is analagous to the DRUPAL_BOOTSTRAP_CONFIGURATION bootstrap phase in Drupal
  56. * itself, and this is also the first step where Drupal specific code is included.
  57. *
  58. * This phase is commonly used for code that interacts with the Drupal install API,
  59. * as both install.php and update.php start at this phase.
  60. */
  61. define('DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION', 3);
  62. /**
  63. * Connect to the Drupal database using the database credentials loaded
  64. * during the previous bootstrap phase.
  65. *
  66. * This phase is analogous to the DRUPAL_BOOTSTRAP_DATABASE bootstrap phase in
  67. * Drupal.
  68. *
  69. * Any code that needs to interact with the Drupal database API needs to
  70. * be bootstrapped to at least this phase.
  71. */
  72. define('DRUSH_BOOTSTRAP_DRUPAL_DATABASE', 4);
  73. /**
  74. * Fully initialize Drupal.
  75. *
  76. * This is analogous to the DRUPAL_BOOTSTRAP_FULL bootstrap phase in
  77. * Drupal.
  78. *
  79. * Any code that interacts with the general Drupal API should be
  80. * bootstrapped to this phase.
  81. */
  82. define('DRUSH_BOOTSTRAP_DRUPAL_FULL', 5);
  83. /**
  84. * Log in to the initialiased Drupal site.
  85. *
  86. * This is the default bootstrap phase all commands will try to reach,
  87. * unless otherwise specified.
  88. *
  89. * This bootstrap phase is used after the site has been
  90. * fully bootstrapped.
  91. *
  92. * This phase will log you in to the drupal site with the username
  93. * or user ID specified by the --user/ -u option.
  94. *
  95. * Use this bootstrap phase for your command if you need to have access
  96. * to information for a specific user, such as listing nodes that might
  97. * be different based on who is logged in.
  98. */
  99. define('DRUSH_BOOTSTRAP_DRUPAL_LOGIN', 6);
  100. /**
  101. * Return the list of bootstrap objects that are available for
  102. * initializing a CMS with Drush. We insure that any given candidate
  103. * class is instantiated only once.
  104. *
  105. * @return \Drush\Boot\Boot[]
  106. */
  107. function drush_get_bootstrap_candidates() {
  108. $candidate_classes = drush_get_bootstrap_candidate_classnames();
  109. $cache =& drush_get_context('DRUSH_BOOTSTRAP_CANDIDATE_OBJECTS');
  110. $result = array();
  111. foreach($candidate_classes as $candidate_class) {
  112. if (array_key_exists($candidate_class, $cache)) {
  113. $result[$candidate_class] = $cache[$candidate_class];
  114. }
  115. else {
  116. $result[$candidate_class] = new $candidate_class;
  117. }
  118. }
  119. $cache = $result;
  120. return $result;
  121. }
  122. /**
  123. * Find the list of bootstrap classnames available for initializing a
  124. * CMS with Drush.
  125. *
  126. * @return array
  127. */
  128. function drush_get_bootstrap_candidate_classnames() {
  129. // Give all commandfiles a chance to return candidates. They should
  130. // return STRINGS with the class name of the bootstrap object they provide.
  131. $candidates = drush_command_invoke_all('bootstrap_candidates');
  132. // If a bootstrap class was specified on the command line, consider it first.
  133. $bootstrap_class = drush_get_option('bootstrap_class', FALSE);
  134. if ($bootstrap_class) {
  135. array_unshift($candidates, $bootstrap_class);
  136. }
  137. // Add candidate bootstrap classes for Drupal
  138. foreach (array('8', '7', '6') as $version) {
  139. $drupal_bootstrap_class = 'Drush\Boot\DrupalBoot' . $version;
  140. $candidates[] = $drupal_bootstrap_class;
  141. }
  142. // Always consider our default bootstrap class last.
  143. $candidates[] = 'Drush\Boot\EmptyBoot';
  144. return $candidates;
  145. }
  146. /**
  147. * Look up the best bootstrap class for the given location
  148. * from the set of available candidates.
  149. */
  150. function drush_bootstrap_class_for_root($path) {
  151. drush_load_bootstrap_commandfile_at_path($path);
  152. $candidates = drush_get_bootstrap_candidates();
  153. foreach ($candidates as $candidate) {
  154. if ($candidate->valid_root($path)) {
  155. return $candidate;
  156. }
  157. }
  158. return NULL;
  159. }
  160. /**
  161. * Check to see if there is a bootstrap class available
  162. * at the specified location; if there is, load it.
  163. */
  164. function drush_load_bootstrap_commandfile_at_path($path) {
  165. static $paths = array();
  166. if (!empty($path) && (!array_key_exists($path, $paths))) {
  167. $paths[$path] = TRUE;
  168. // Check to see if we have any bootstrap classes in this location.
  169. $bootstrap_class_dir = $path . '/drush/bootstrap';
  170. if (is_dir($bootstrap_class_dir)) {
  171. _drush_add_commandfiles(array($bootstrap_class_dir), DRUSH_BOOTSTRAP_NONE);
  172. }
  173. }
  174. }
  175. /**
  176. * Select the bootstrap class to use. If this is called multiple
  177. * times, the bootstrap class returned might change on subsequent
  178. * calls, if the root directory changes. Once the bootstrap object
  179. * starts changing the state of the system, however, it will
  180. * be 'latched', and further calls to drush_select_bootstrap_class()
  181. * will always return the same object.
  182. */
  183. function drush_select_bootstrap_class() {
  184. $root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
  185. // Once we have selected a Drupal root, we will reduce our bootstrap
  186. // candidates down to just the one used to select this site root.
  187. $bootstrap = drush_bootstrap_class_for_root($root);
  188. // If we have not found a bootstrap class by this point,
  189. // then take the last one and use it. This should be our
  190. // default bootstrap class. The default bootstrap class
  191. // should pass through all calls without doing anything that
  192. // changes state in a CMS-specific way.
  193. if ($bootstrap == NULL) {
  194. $candidates = drush_get_bootstrap_candidates();
  195. $bootstrap = array_pop($candidates);
  196. }
  197. return $bootstrap;
  198. }
  199. /**
  200. * Don't allow the bootstrap object to change once we start bootstrapping
  201. */
  202. function drush_latch_bootstrap_object($bootstrap) {
  203. drush_set_context('DRUSH_BOOTSTRAP_OBJECT', $bootstrap);
  204. }
  205. /**
  206. * Get the appropriate bootstrap object. We'll search for a new
  207. * bootstrap object every time someone asks for one until we start
  208. * bootstrapping; then we'll returned the same cached one every time.
  209. *
  210. * @return \Drush\Boot\Boot
  211. */
  212. function drush_get_bootstrap_object() {
  213. $bootstrap = drush_get_context('DRUSH_BOOTSTRAP_OBJECT', FALSE);
  214. if (!$bootstrap) {
  215. $bootstrap = drush_select_bootstrap_class();
  216. }
  217. return $bootstrap;
  218. }
  219. /**
  220. * Find the URI that has been selected by the cwd
  221. * if it was not previously set via the --uri / -l option
  222. */
  223. function _drush_bootstrap_selected_uri() {
  224. $uri = drush_get_context('DRUSH_SELECTED_URI');
  225. if (empty($uri)) {
  226. $site_path = drush_site_path();
  227. $elements = explode('/', $site_path);
  228. $current = array_pop($elements);
  229. if (!$current) {
  230. $current = 'default';
  231. }
  232. $uri = 'http://'. $current;
  233. $uri = drush_set_context('DRUSH_SELECTED_URI', $uri);
  234. drush_sitealias_create_self_alias();
  235. }
  236. return $uri;
  237. }
  238. /**
  239. * Helper function to store any context settings that are being validated.
  240. */
  241. function drush_bootstrap_value($context, $value = null) {
  242. $values =& drush_get_context('DRUSH_BOOTSTRAP_VALUES', array());
  243. if (isset($value)) {
  244. $values[$context] = $value;
  245. }
  246. if (array_key_exists($context, $values)) {
  247. return $values[$context];
  248. }
  249. return null;
  250. }
  251. /**
  252. * Helper function listing phases.
  253. *
  254. * For commands that need to iterate through the phases, such as help
  255. */
  256. function _drush_bootstrap_phases($function_names = FALSE) {
  257. $result = array();
  258. if ($bootstrap = drush_get_bootstrap_object()) {
  259. $result = $bootstrap->bootstrap_phases();
  260. if (!$function_names) {
  261. $result = array_keys($result);
  262. }
  263. }
  264. return $result;
  265. }
  266. /**
  267. * Bootstrap Drush to the desired phase.
  268. *
  269. * This function will sequentially bootstrap each
  270. * lower phase up to the phase that has been requested.
  271. *
  272. * @param phase
  273. * The bootstrap phase to bootstrap to. @see \Drush\Boot::bootstrap_phases
  274. */
  275. function drush_bootstrap($phase, $phase_max = FALSE) {
  276. $bootstrap = drush_get_bootstrap_object();
  277. $phases = _drush_bootstrap_phases(TRUE);
  278. $result = TRUE;
  279. // If the requested phase does not exist in the list of available
  280. // phases, it means that the command requires bootstrap to a certain
  281. // level, but no site root could be found.
  282. if (!isset($phases[$phase])) {
  283. $result = drush_bootstrap_error('DRUSH_NO_SITE', dt("We could not find an applicable site for that command."));
  284. }
  285. // Once we start bootstrapping past the DRUSH_BOOTSTRAP_DRUSH phase, we
  286. // will latch the bootstrap object, and prevent it from changing.
  287. if ($phase > DRUSH_BOOTSTRAP_DRUSH) {
  288. drush_latch_bootstrap_object($bootstrap);
  289. }
  290. drush_set_context('DRUSH_BOOTSTRAPPING', TRUE);
  291. foreach ($phases as $phase_index => $current_phase) {
  292. $bootstrapped_phase = drush_get_context('DRUSH_BOOTSTRAP_PHASE', -1);
  293. if ($phase_index > $phase) {
  294. break;
  295. }
  296. if ($phase_index > $bootstrapped_phase) {
  297. if ($result = drush_bootstrap_validate($phase_index)) {
  298. if (method_exists($bootstrap, $current_phase) && !drush_get_error()) {
  299. drush_log(dt("Drush bootstrap phase : !function()", array('!function' => $current_phase)), LogLevel::BOOTSTRAP);
  300. $bootstrap->{$current_phase}();
  301. // Reset commandfile cache and find any new command files that are available during this bootstrap phase.
  302. drush_get_commands(TRUE);
  303. _drush_find_commandfiles($phase_index, $phase_max);
  304. }
  305. drush_set_context('DRUSH_BOOTSTRAP_PHASE', $phase_index);
  306. }
  307. }
  308. }
  309. drush_set_context('DRUSH_BOOTSTRAPPING', FALSE);
  310. if (!$result || drush_get_error()) {
  311. $errors = drush_get_context('DRUSH_BOOTSTRAP_ERRORS', array());
  312. foreach ($errors as $code => $message) {
  313. drush_set_error($code, $message);
  314. }
  315. }
  316. return !drush_get_error();
  317. }
  318. /**
  319. * Determine whether a given bootstrap phase has been completed
  320. *
  321. * This function name has a typo which makes me laugh so we choose not to
  322. * fix it. Take a deep breath, and smile. See
  323. * http://en.wikipedia.org/wiki/HTTP_referer
  324. *
  325. *
  326. * @param phase
  327. * The bootstrap phase to test
  328. *
  329. * @returns
  330. * TRUE if the specified bootstrap phase has completed.
  331. */
  332. function drush_has_boostrapped($phase) {
  333. $phase_index = drush_get_context('DRUSH_BOOTSTRAP_PHASE');
  334. return isset($phase_index) && ($phase_index >= $phase);
  335. }
  336. /**
  337. * Validate whether a bootstrap phase can be reached.
  338. *
  339. * This function will validate the settings that will be used
  340. * during the actual bootstrap process, and allow commands to
  341. * progressively bootstrap to the highest level that can be reached.
  342. *
  343. * This function will only run the validation function once, and
  344. * store the result from that execution in a local static. This avoids
  345. * validating phases multiple times.
  346. *
  347. * @param phase
  348. * The bootstrap phase to validate to. @see \Drush\Boot::bootstrap_phases
  349. *
  350. * @return
  351. * True if bootstrap is possible, False if the validation failed.
  352. *
  353. */
  354. function drush_bootstrap_validate($phase) {
  355. $bootstrap = drush_get_bootstrap_object();
  356. $phases = _drush_bootstrap_phases(TRUE);
  357. static $result_cache = array();
  358. if (!array_key_exists($phase, $result_cache)) {
  359. drush_set_context('DRUSH_BOOTSTRAP_ERRORS', array());
  360. drush_set_context('DRUSH_BOOTSTRAP_VALUES', array());
  361. foreach ($phases as $phase_index => $current_phase) {
  362. $validated_phase = drush_get_context('DRUSH_BOOTSTRAP_VALIDATION_PHASE', -1);
  363. if ($phase_index > $phase) {
  364. break;
  365. }
  366. if ($phase_index > $validated_phase) {
  367. $current_phase .= '_validate';
  368. if (method_exists($bootstrap, $current_phase)) {
  369. $result_cache[$phase_index] = $bootstrap->{$current_phase}();
  370. }
  371. else {
  372. $result_cache[$phase_index] = TRUE;
  373. }
  374. drush_set_context('DRUSH_BOOTSTRAP_VALIDATION_PHASE', $phase_index);
  375. }
  376. }
  377. }
  378. return $result_cache[$phase];
  379. }
  380. /**
  381. * Bootstrap to the specified phase.
  382. *
  383. * @param $max_phase_index
  384. * Only attempt bootstrap to the specified level.
  385. */
  386. function drush_bootstrap_to_phase($max_phase_index) {
  387. // If $max_phase_index is DRUSH_BOOTSTRAP_MAX, then
  388. // we will bootstrap as far as we can. drush_bootstrap_max
  389. // is different than drush_bootstrap_to_phase in that
  390. // it is not an error if DRUSH_BOOTSTRAP_LOGIN is not reached.
  391. if ($max_phase_index == DRUSH_BOOTSTRAP_MAX) {
  392. drush_bootstrap_max();
  393. return TRUE;
  394. }
  395. drush_log(dt("Bootstrap to phase !phase.", array('!phase' => $max_phase_index)), LogLevel::BOOTSTRAP);
  396. $phases = _drush_bootstrap_phases();
  397. $result = TRUE;
  398. // Try to bootstrap to the maximum possible level, without generating errors
  399. foreach ($phases as $phase_index) {
  400. if ($phase_index > $max_phase_index) {
  401. // Stop trying, since we achieved what was specified.
  402. break;
  403. }
  404. if (drush_bootstrap_validate($phase_index)) {
  405. if ($phase_index > drush_get_context('DRUSH_BOOTSTRAP_PHASE', DRUSH_BOOTSTRAP_NONE)) {
  406. $result = drush_bootstrap($phase_index, $max_phase_index);
  407. }
  408. }
  409. else {
  410. $result = FALSE;
  411. break;
  412. }
  413. }
  414. return $result;
  415. }
  416. /**
  417. * Bootstrap to the highest level possible, without triggering any errors.
  418. *
  419. * @param $max_phase_index
  420. * Only attempt bootstrap to the specified level.
  421. *
  422. * @return int
  423. * The maximum phase to which we bootstrapped.
  424. */
  425. function drush_bootstrap_max($max_phase_index = FALSE) {
  426. $phases = _drush_bootstrap_phases();
  427. $phase_index = DRUSH_BOOTSTRAP_DRUSH;
  428. if (!$max_phase_index) {
  429. $max_phase_index = count($phases);
  430. }
  431. // Try to bootstrap to the maximum possible level, without generating errors
  432. foreach ($phases as $phase_index) {
  433. if ($phase_index > $max_phase_index) {
  434. // Stop trying, since we achieved what was specified.
  435. break;
  436. }
  437. if (drush_bootstrap_validate($phase_index)) {
  438. if ($phase_index > drush_get_context('DRUSH_BOOTSTRAP_PHASE')) {
  439. drush_bootstrap($phase_index, $max_phase_index);
  440. }
  441. }
  442. else {
  443. break;
  444. }
  445. }
  446. return drush_get_context('DRUSH_BOOTSTRAP_PHASE');
  447. }
  448. /**
  449. * Bootstrap the specified site alias. The site alias must
  450. * be a valid alias to a local site.
  451. *
  452. * @param $site_record
  453. * The alias record for the given site alias.
  454. * @see drush_sitealias_get_record().
  455. * @param $max_phase_index
  456. * Only attempt bootstrap to the specified level.
  457. * @returns TRUE if attempted to bootstrap, or FALSE
  458. * if no bootstrap attempt was made.
  459. */
  460. function drush_bootstrap_max_to_sitealias($site_record, $max_phase_index = NULL) {
  461. if ((array_key_exists('root', $site_record) && !array_key_exists('remote-host', $site_record))) {
  462. drush_sitealias_set_alias_context($site_record);
  463. drush_bootstrap_max($max_phase_index);
  464. return TRUE;
  465. }
  466. return FALSE;
  467. }
  468. /**
  469. * Helper function to collect any errors that occur during the bootstrap process.
  470. * Always returns FALSE, for convenience.
  471. */
  472. function drush_bootstrap_error($code, $message = null) {
  473. $errors = drush_get_context('DRUSH_BOOTSTRAP_ERRORS');
  474. $errors[$code] = $message;
  475. drush_set_context('DRUSH_BOOTSTRAP_ERRORS', $errors);
  476. return FALSE;
  477. }
  478. function _drush_bootstrap_output_prepare() {
  479. // Note that as soon as we set the DRUSH_BACKEND context, we change
  480. // the behavior of drush_log(). It is therefore important that we
  481. // should not set this context until immediately before we call ob_start
  482. // (i.e., in this function).
  483. $backend = drush_set_context('DRUSH_BACKEND', drush_get_option('backend'));
  484. $quiet = drush_get_context('DRUSH_QUIET');
  485. if ($backend) {
  486. // Load options passed as a JSON encoded string through STDIN.
  487. $stdin_options = _drush_backend_get_stdin();
  488. if (is_array($stdin_options)) {
  489. drush_set_context('stdin', $stdin_options);
  490. }
  491. // Add an output buffer handler to collect output/pass through backend
  492. // packets. Using a chunksize of 2 ensures that each line is flushed
  493. // straight away.
  494. if ($quiet) {
  495. // Pass through of backend packets, discard regular output.
  496. ob_start('drush_backend_output_discard', 2);
  497. }
  498. else {
  499. // Collect output.
  500. ob_start('drush_backend_output_collect', 2);
  501. }
  502. }
  503. // In non-backend quiet mode we start buffering and discards it on command
  504. // completion.
  505. if ($quiet && !$backend) {
  506. ob_start();
  507. }
  508. }
  509. /**
  510. * Used by a Drush extension to request that its Composer autoload
  511. * files be loaded by Drush, if they have not already been.
  512. *
  513. * Usage:
  514. *
  515. * function mycommandfile_drush_init() {
  516. * drush_autoload(__FILE__)
  517. * }
  518. *
  519. */
  520. function drush_autoload($commandfile) {
  521. $already_added = commandfiles_cache()->add($commandfile);
  522. $dir = dirname($commandfile);
  523. $candidates = array("vendor/autoload.php", "../../../vendor/autoload.php");
  524. $drush_autoload_file = drush_get_context('DRUSH_VENDOR_PATH', '');
  525. foreach ($candidates as $candidate) {
  526. $autoload = $dir . '/' . $candidate;
  527. if (file_exists($autoload) && (realpath($autoload) != $drush_autoload_file)) {
  528. include $autoload;
  529. }
  530. }
  531. }