c9c62e63f45c0018ae95ebbef3971bc44cbbc864
[yaffs-website] / vendor / drush / drush / src / Commands / core / InitCommands.php
1 <?php
2 namespace Drush\Commands\core;
3
4 use Drush\Drush;
5 use Drush\Commands\DrushCommands;
6 use Drush\Exceptions\UserAbortException;
7 use Drush\Log\LogLevel;
8 use Robo\LoadAllTasks;
9 use Robo\Contract\IOAwareInterface;
10 use Robo\Contract\BuilderAwareInterface;
11
12 class InitCommands extends DrushCommands implements BuilderAwareInterface, IOAwareInterface
13 {
14     use LoadAllTasks;
15
16     /**
17      * Enrich the bash startup file with bash aliases and a smart command prompt.
18      *
19      * @command core:init
20      *
21      * @option $edit Open the new config file in an editor.
22      * @option $add-path Always add Drush to the $PATH in the user's .bashrc
23      *   file, even if it is already in the $PATH. Use --no-add-path to skip
24      *   updating .bashrc with the Drush $PATH. Default is to update .bashrc
25      *   only if Drush is not already in the $PATH.
26      * @optionset_get_editor
27      * @aliases init,core-init
28      * @usage core-init --edit
29      *   Enrich Bash and open drush config file in editor.
30      * @usage core-init --edit --bg
31      *   Return to shell prompt as soon as the editor window opens
32      */
33     public function initializeDrush($options = ['edit' => false, 'add-path' => ''])
34     {
35         $home = Drush::config()->home();
36         $drush_config_dir = $home . "/.drush";
37         $drush_config_file = $drush_config_dir . "/drush.yml";
38         $drush_bashrc = $drush_config_dir . "/drush.bashrc";
39         $drush_prompt = $drush_config_dir . "/drush.prompt.sh";
40         $examples_dir = DRUSH_BASE_PATH . "/examples";
41         $example_configuration = $examples_dir . "/example.drush.yml";
42         $example_bashrc = $examples_dir . "/example.bashrc";
43         $example_prompt = $examples_dir . "/example.prompt.sh";
44
45         $collection = $this->collectionBuilder();
46
47         // Create a ~/.drush directory if it does not yet exist
48         $collection->taskFilesystemStack()->mkdir($drush_config_dir);
49
50         // If there is no ~/.drush/drush.yml, copy example there.
51         if (!is_file($drush_config_file)) {
52             $collection->taskWriteToFile($drush_config_file)->textFromFile($example_configuration);
53         }
54
55         // Decide whether we want to add our Bash commands to
56         // ~/.bashrc or ~/.bash_profile, and create a task to
57         // update it with includes of the various files we write,
58         // as needed.  If it is, then we will add it to the collection.
59         $bashrc = $this->findBashrc($home);
60         $taskUpdateBashrc = $this->taskWriteToFile($bashrc)->append();
61
62         // List of Drush bash configuration files, and
63         // their source templates.
64         $drushBashFiles = [
65             $drush_bashrc => $example_bashrc,
66             $drush_prompt => $example_prompt,
67         ];
68
69         // Mapping from Drush bash configuration files
70         // to a description of what each one is.
71         $drushBashFileDescriptions = [
72             $drush_bashrc => 'Drush bash customizations',
73             $drush_prompt => 'Drush prompt customizations',
74         ];
75
76         foreach ($drushBashFiles as $destFile => $sourceFile) {
77             // If the destination file does not exist, then
78             // copy the example file there.
79             if (!is_file($destFile)) {
80                 $collection->taskWriteToFile($destFile)->textFromFile($sourceFile);
81                 $description = $drushBashFileDescriptions[$destFile];
82                 $collection->progressMessage('Copied {description} to {path}', ['description' => $description, 'path' => $destFile], LogLevel::OK);
83                 $pattern = basename($destFile);
84                 $taskUpdateBashrc->appendUnlessMatches("#$pattern#", "\n# Include $description.". $this->bashAddition($destFile));
85             }
86         }
87
88         // If Drush is not in the $PATH, then figure out which
89         // path to add so that Drush can be found globally.
90         $add_path = $options['add-path'];
91         if ((!drush_which("drush") || $add_path) && ($add_path !== false)) {
92             $drush_path = $this->findPathToDrush();
93             $drush_path = preg_replace("%^" . preg_quote($home) . "/%", '$HOME/', $drush_path);
94             $pattern = "$drush_path";
95             $taskUpdateBashrc->appendUnlessMatches("#$pattern#", "\n# Path to Drush, added by 'drush init'.\nexport PATH=\"\$PATH:$drush_path\"\n\n");
96         }
97
98         $openEditor = false;
99         if ($taskUpdateBashrc->wouldChange()) {
100             if ($this->io()->confirm(dt("Modify !file to include Drush configuration files?", ['!file' => $bashrc]))) {
101                 $collection->addTask($taskUpdateBashrc);
102                 $collection->progressMessage('Updated bash configuration file {path}', ['path' => $bashrc], LogLevel::OK);
103                 $collection->progressMessage('Start a new shell in order to experience the improvements (e.g. `{shell}`).', ['shell' => 'bash'], LogLevel::OK);
104                 $openEditor = $options['edit'];
105             } else {
106                 throw new UserAbortException();
107             }
108         } else {
109             $collection->progressMessage('No code added to {path}', ['path' => $bashrc]);
110         }
111         $result = $collection->run();
112
113         if ($result->wasSuccessful() && $openEditor) {
114             $exec = drush_get_editor();
115             drush_shell_exec_interactive($exec, $drush_config_file, $drush_config_file);
116         }
117
118         return $result;
119     }
120
121     /**
122      * Determine which .bashrc file is best to use on this platform.
123      */
124     protected function findBashrc($home)
125     {
126         # Set a default value in case nothing else exists.
127         $file = $home . '/.bashrc';
128
129         if (!empty($_ENV['SHELL']) && strstr($_ENV['SHELL'], 'zsh')) {
130             $file = $home . '/.zshrc';
131         } elseif (file_exists($home . '/.bash_profile')) {
132             $file = $home . '/.bash_profile';
133         } elseif (file_exists($home . '/.bashrc')) {
134             $file = $home . '/.bashrc';
135         } elseif (file_exists($home . '/.profile')) {
136             $file = $home . '/.profile';
137         } elseif (file_exists($home . '/.functions')) {
138             $file = $home . '/.functions';
139         }
140
141         return $file;
142     }
143
144     /**
145      * Determine where Drush is located, so that we can add
146      * that location to the $PATH.
147      */
148     protected function findPathToDrush()
149     {
150         // First test: is Drush inside a vendor directory?
151         // Does vendor/bin exist?  If so, use that.  We do
152         // not have a good way to locate the 'bin' directory
153         // if it has been relocated in the composer.json config
154         // section.
155         if ($vendor_pos = strpos(DRUSH_BASE_PATH, "/vendor/")) {
156             $vendor_dir = substr(DRUSH_BASE_PATH, 0, $vendor_pos + 7);
157             $vendor_bin = $vendor_dir . '/bin';
158             if (is_dir($vendor_bin)) {
159                 return $vendor_bin;
160             }
161         }
162
163         // Fallback is to use the directory that Drush is in.
164         return DRUSH_BASE_PATH;
165     }
166
167     protected function bashAddition($file)
168     {
169         return <<<EOD
170
171 if [ -f "$file" ] ; then
172   source $file
173 fi
174
175 EOD;
176     }
177 }