4cf30527c638a4b158fd8f7a0debf5f3898113e0
[yaffs-website] / vendor / drush / drush / src / Preflight / RedispatchToSiteLocal.php
1 <?php
2
3 namespace Drush\Preflight;
4
5 use Webmozart\PathUtil\Path;
6
7 /**
8  * RedispatchToSiteLocal forces an `exec` to the site-local Drush if it
9  * exist.  We must do this super-early, before loading Drupal's autoload
10  * file.  If we do not, we will crash unless the site-local Drush and the
11  * global Drush are using the exact same versions of all dependencies, which
12  * will rarely line up sufficiently to prevent problems.
13  */
14 class RedispatchToSiteLocal
15 {
16
17     /**
18      * Determine if a local redispatch is needed, and do so if it is.
19      *
20      * @param array $argv The commandline arguments
21      * @param string $root The selected site root or false if none
22      * @param string $vendor The path to the vendor directory
23      * @param PreflightLog $preflightLog A basic logger.
24      *
25      * @return bool
26      *   True if redispatch occurred, and was returned successfully.
27      */
28     public static function redispatchIfSiteLocalDrush($argv, $root, $vendor, PreflightLog $preflightLog)
29     {
30         // Special check for the SUT, which is always a site-local install.
31         // The symlink that Composer sets up can make it challenging to
32         // detect that the vendor directory is in the same place. Do not
33         // set DRUSH_AUTOLOAD_PHP unless you know what you are doing! This
34         // mechanism should be reserved for use with test fixtures.
35         if (getenv('DRUSH_AUTOLOAD_PHP')) {
36             return false;
37         }
38
39         // Try to find the site-local Drush. If there is none, we are done.
40         $siteLocalDrush = static::findSiteLocalDrush($root);
41         if (!$siteLocalDrush) {
42             return false;
43         }
44
45         // If the site-local Drush is us, then we do not need to redispatch.
46         if (Path::isBasePath($vendor, $siteLocalDrush)) {
47             return false;
48         }
49
50         // Do another special check to detect symlinked Drush folder similar
51         // to what the SUT sets up for Drush functional tests.
52         if (dirname($vendor) == dirname($siteLocalDrush)) {
53             return false;
54         }
55
56         // Redispatch!
57         $command = $siteLocalDrush;
58         $preflightLog->log(dt('Redispatch to site-local Drush: !cmd.', ['!cmd' => $command]));
59         array_shift($argv);
60         $args = array_map(
61             function ($item) {
62                 return escapeshellarg($item);
63             },
64             $argv
65         );
66         $command .= ' ' . implode(' ', $args);
67         passthru($command, $status);
68         return $status;
69     }
70
71     /**
72      * Find a site-local Drush, if there is one in the selected site's
73      * vendor directory.
74      *
75      * @param string $root The selected site root
76      */
77     protected static function findSiteLocalDrush($root)
78     {
79         $candidates = [
80             "$root/vendor/drush/drush/drush",
81             dirname($root) . '/vendor/drush/drush/drush',
82         ];
83         foreach ($candidates as $candidate) {
84             if (file_exists($candidate)) {
85                 return $candidate;
86             }
87         }
88     }
89 }