Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / vendor / drush / drush / src / Drush.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drush.
6  */
7 namespace Drush;
8
9 use Consolidation\SiteAlias\SiteAliasManager;
10 use League\Container\ContainerInterface;
11 use Psr\Log\LoggerInterface;
12 use Symfony\Component\Console\Application;
13 use Symfony\Component\Console\Input\InputInterface;
14 use Symfony\Component\Console\Output\OutputInterface;
15
16 // TODO: Not sure if we should have a reference to PreflightArgs here.
17 // Maybe these constants should be in config, and PreflightArgs can
18 // reference them from there as well.
19 use Drush\Preflight\PreflightArgs;
20
21 /**
22  * Static Service Container wrapper.
23  *
24  * This code is analogous to the \Drupal class in Drupal 8.
25  *
26  * We would like to move Drush towards the model of using constructor
27  * injection rather than globals. This class serves as a unified global
28  * accessor to arbitrary services for use by legacy Drush code.
29  *
30  * Advice from Drupal 8's 'Drupal' class:
31  *
32  * This class exists only to support legacy code that cannot be dependency
33  * injected. If your code needs it, consider refactoring it to be object
34  * oriented, if possible. When this is not possible, and your code is more
35  * than a few non-reusable lines, it is recommended to instantiate an object
36  * implementing the actual logic.
37  *
38  * @code
39  *   // Legacy procedural code.
40  *   $object = drush_get_context('DRUSH_CLASS_LABEL');
41  *
42  * Better:
43  *   $object = Drush::service('label');
44  *
45  * @endcode
46  */
47 class Drush
48 {
49
50     /**
51      * The version of Drush from the drush.info file, or FALSE if not read yet.
52      *
53      * @var string|FALSE
54      */
55     protected static $version = false;
56     protected static $majorVersion = false;
57     protected static $minorVersion = false;
58
59     /**
60      * The currently active container object, or NULL if not initialized yet.
61      *
62      * @var \League\Container\ContainerInterface|null
63      */
64     protected static $container;
65
66     /**
67      * The Robo Runner -- manages and constructs all commandfile classes
68      *
69      * @var \Robo\Runner
70      */
71     protected static $runner;
72
73     /**
74      * Return the current Drush version.
75      *
76      * n.b. Called before the DI container is initialized.
77      * Do not log, etc. here.
78      */
79     public static function getVersion()
80     {
81         if (!static::$version) {
82             $drush_info = static::drushReadDrushInfo();
83             static::$version = $drush_info['drush_version'];
84         }
85         return static::$version;
86     }
87
88     public static function getMajorVersion()
89     {
90         if (!static::$majorVersion) {
91             $drush_version = static::getVersion();
92             $version_parts = explode('.', $drush_version);
93             static::$majorVersion = $version_parts[0];
94         }
95         return static::$majorVersion;
96     }
97
98     public static function getMinorVersion()
99     {
100         if (!static::$minorVersion) {
101             $drush_version = static::getVersion();
102             $version_parts = explode('.', $drush_version);
103             static::$minorVersion = $version_parts[1];
104         }
105         return static::$minorVersion;
106     }
107
108     /**
109      * Sets a new global container.
110      *
111      * @param \League\Container\Container $container
112      *   A new container instance to replace the current.
113      */
114     public static function setContainer(ContainerInterface $container)
115     {
116         static::$container = $container;
117     }
118
119     /**
120      * Unsets the global container.
121      */
122     public static function unsetContainer()
123     {
124         static::$container = null;
125     }
126
127     /**
128      * Returns the currently active global container.
129      *
130      * @return \League\Container\ContainerInterface|null
131      *
132      * @throws RuntimeException
133      */
134     public static function getContainer()
135     {
136         if (static::$container === null) {
137             debug_print_backtrace();
138             throw new \RuntimeException('Drush::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.');
139         }
140         return static::$container;
141     }
142
143     /**
144      * Returns TRUE if the container has been initialized, FALSE otherwise.
145      *
146      * @return bool
147      */
148     public static function hasContainer()
149     {
150         return static::$container !== null;
151     }
152
153     /**
154      * Get the current Symfony Console Application.
155      *
156      * @return Application
157      */
158     public static function getApplication()
159     {
160         return self::getContainer()->get('application');
161     }
162
163     /**
164      * Return the Robo runner.
165      *
166      * @return \Robo\Runner
167      */
168     public static function runner()
169     {
170         if (!isset(static::$runner)) {
171             static::$runner = new \Robo\Runner();
172         }
173         return static::$runner;
174     }
175
176     /**
177      * Retrieves a service from the container.
178      *
179      * Use this method if the desired service is not one of those with a dedicated
180      * accessor method below. If it is listed below, those methods are preferred
181      * as they can return useful type hints.
182      *
183      * @param string $id
184      *   The ID of the service to retrieve.
185      *
186      * @return mixed
187      *   The specified service.
188      */
189     public static function service($id)
190     {
191         return static::getContainer()->get($id);
192     }
193
194     /**
195      * Indicates if a service is defined in the container.
196      *
197      * @param string $id
198      *   The ID of the service to check.
199      *
200      * @return bool
201      *   TRUE if the specified service exists, FALSE otherwise.
202      */
203     public static function hasService($id)
204     {
205         // Check hasContainer() first in order to always return a Boolean.
206         return static::hasContainer() && static::getContainer()->has($id);
207     }
208
209     /**
210      * Return command factory
211      *
212      * @return \Consolidation\AnnotatedCommand\AnnotatedCommandFactory
213      */
214     public static function commandFactory()
215     {
216         return static::service('commandFactory');
217     }
218
219     /**
220      * Return the Drush logger object.
221      *
222      * @return LoggerInterface
223      */
224     public static function logger()
225     {
226         return static::service('logger');
227     }
228
229     /**
230      * Return the configuration object
231      *
232      * @return \Drush\Config\DrushConfig
233      */
234     public static function config()
235     {
236         return static::service('config');
237     }
238
239     /**
240      * @return SiteAliasManager
241      */
242     public static function aliasManager()
243     {
244         return static::service('site.alias.manager');
245     }
246
247     /**
248      * Return the input object
249      *
250      * @return InputInterface
251      */
252     public static function input()
253     {
254         return static::service('input');
255     }
256
257     /**
258      * Return the output object
259      *
260      * @return OutputInterface
261      */
262     public static function output()
263     {
264         return static::service('output');
265     }
266
267     /**
268      * Return 'true' if we are in simulated mode
269      */
270     public static function simulate()
271     {
272         return \Drush\Drush::config()->get(\Robo\Config\Config::SIMULATE);
273     }
274
275     /**
276      * Return 'true' if we are in backend mode
277      */
278     public static function backend()
279     {
280         return \Drush\Drush::config()->get(PreflightArgs::BACKEND);
281     }
282
283     /**
284      * Return 'true' if we are in affirmative mode
285      */
286     public static function affirmative()
287     {
288         if (!static::hasService('input')) {
289             throw new \Exception('No input service available.');
290         }
291         return Drush::input()->getOption('yes') || (Drush::backend() && !Drush::negative());
292     }
293
294     /**
295      * Return 'true' if we are in negative mode
296      */
297     public static function negative()
298     {
299         if (!static::hasService('input')) {
300             throw new \Exception('No input service available.');
301         }
302         return Drush::input()->getOption('no');
303     }
304
305     /**
306      * Return 'true' if we are in verbose mode
307      */
308     public static function verbose()
309     {
310         if (!static::hasService('output')) {
311             return false;
312         }
313         return \Drush\Drush::output()->isVerbose();
314     }
315
316     /**
317      * Return 'true' if we are in debug mode
318      */
319     public static function debug()
320     {
321         if (!static::hasService('output')) {
322             return false;
323         }
324         return \Drush\Drush::output()->isDebug();
325     }
326
327     /**
328      * Return the Bootstrap Manager.
329      *
330      * @return \Drush\Boot\BootstrapManager
331      */
332     public static function bootstrapManager()
333     {
334         return static::service('bootstrap.manager');
335     }
336
337     /**
338      * Return the Bootstrap object.
339      *
340      * @return \Drush\Boot\Boot
341      */
342     public static function bootstrap()
343     {
344         return static::bootstrapManager()->bootstrap();
345     }
346
347     public static function redispatchOptions($input = null)
348     {
349         $input = $input ?: static::input();
350
351         // $input->getOptions() returns an associative array of option => value
352         $options = $input->getOptions();
353
354         // The 'runtime.options' config contains a list of option names on th cli
355         $optionNamesFromCommandline = static::config()->get('runtime.options');
356
357         // Remove anything in $options that was not on the cli
358         $options = array_intersect_key($options, array_flip($optionNamesFromCommandline));
359
360         // Add in the 'runtime.context' items, which includes --include, --alias-path et. al.
361         return $options + array_filter(static::config()->get(PreflightArgs::DRUSH_RUNTIME_CONTEXT_NAMESPACE));
362     }
363
364     /**
365      * Read the drush info file.
366      */
367     private static function drushReadDrushInfo()
368     {
369         $drush_info_file = dirname(__FILE__) . '/../drush.info';
370
371         return parse_ini_file($drush_info_file);
372     }
373 }