Completed
Pull Request — master (#552)
by Greg
03:18
created

Robo::loadConfiguration()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 4
nop 2
1
<?php
2
namespace Robo;
3
4
use League\Container\Container;
5
use League\Container\ContainerInterface;
6
use Robo\Common\ProcessExecutor;
7
use Robo\Config\ConfigProcessor;
8
use Robo\Config\YamlConfigLoader;
9
use Symfony\Component\Console\Input\StringInput;
10
use Symfony\Component\Console\Application as SymfonyApplication;
11
use Symfony\Component\Process\Process;
12
13
/**
14
 * Manages the container reference and other static data.  Favor
15
 * using dependency injection wherever possible.  Avoid using
16
 * this class directly, unless setting up a custom DI container.
17
 */
18
class Robo
19
{
20
    const APPLICATION_NAME = 'Robo';
21
    const VERSION = '1.0.6-dev';
22
23
    /**
24
     * The currently active container object, or NULL if not initialized yet.
25
     *
26
     * @var ContainerInterface|null
27
     */
28
    protected static $container;
29
30
    /**
31
     * Entrypoint for standalone Robo-based tools.  See docs/framework.md.
32
     *
33
     * @param string[] $argv
34
     * @param string $commandClasses
35
     * @param null|string $appName
36
     * @param null|string $appVersion
37
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
38
     *
39
     * @return int
40
     */
41
    public static function run($argv, $commandClasses, $appName = null, $appVersion = null, $output = null)
42
    {
43
        $runner = new \Robo\Runner($commandClasses);
44
        $statusCode = $runner->execute($argv, $appName, $appVersion, $output);
45
        return $statusCode;
46
    }
47
48
    /**
49
     * Sets a new global container.
50
     *
51
     * @param ContainerInterface $container
52
     *   A new container instance to replace the current.
53
     */
54
    public static function setContainer(ContainerInterface $container)
55
    {
56
        static::$container = $container;
57
    }
58
59
    /**
60
     * Unsets the global container.
61
     */
62
    public static function unsetContainer()
63
    {
64
        static::$container = null;
65
    }
66
67
    /**
68
     * Returns the currently active global container.
69
     *
70
     * @return \League\Container\ContainerInterface
71
     *
72
     * @throws \RuntimeException
73
     */
74
    public static function getContainer()
75
    {
76
        if (static::$container === null) {
77
            throw new \RuntimeException('container is not initialized yet. \Robo\Robo::setContainer() must be called with a real container.');
78
        }
79
        return static::$container;
80
    }
81
82
    /**
83
     * Returns TRUE if the container has been initialized, FALSE otherwise.
84
     *
85
     * @return bool
86
     */
87
    public static function hasContainer()
88
    {
89
        return static::$container !== null;
90
    }
91
92
    /**
93
     * Create a config object and load it from the provided paths.
94
     */
95
    public static function createConfiguration($paths)
96
    {
97
        $config = new \Robo\Config\Config();
98
        static::loadConfiguration($paths, $config);
99
        return $config;
100
    }
101
102
    /**
103
     * Use a simple config loader to load configuration values from specified paths
104
     */
105
    public static function loadConfiguration($paths, $config = null)
106
    {
107
        if ($config == null) {
108
            $config = static::config();
109
        }
110
        $loader = new YamlConfigLoader();
111
        $processor = new ConfigProcessor();
112
        $processor->add($config->export());
113
        foreach ($paths as $path) {
114
            $processor->extend($loader->load($path));
115
        }
116
        $config->import($loader->export());
117
    }
118
119
    /**
120
     * Create a container and initiailze it.  If you wish to *change*
121
     * anything defined in the container, then you should call
122
     * \Robo::configureContainer() instead of this function.
123
     *
124
     * @param null|\Symfony\Component\Console\Input\InputInterface $input
125
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
126
     * @param null|\Robo\Application $app
127
     * @param null|\Robo\Config\Config $config
128
     *
129
     * @return \League\Container\Container|\League\Container\ContainerInterface
130
     */
131
    public static function createDefaultContainer($input = null, $output = null, $app = null, $config = null)
132
    {
133
        // Do not allow this function to be called more than once.
134
        if (static::hasContainer()) {
135
            return static::getContainer();
136
        }
137
138
        if (!$app) {
139
            $app = static::createDefaultApplication();
140
        }
141
142
        if (!$config) {
143
            $config = new \Robo\Config\Config();
144
        }
145
146
        // Set up our dependency injection container.
147
        $container = new Container();
148
        static::configureContainer($container, $app, $config, $input, $output);
149
150
        // Set the application dispatcher
151
        $app->setDispatcher($container->get('eventDispatcher'));
152
153
        return $container;
154
    }
155
156
    /**
157
     * Initialize a container with all of the default Robo services.
158
     * IMPORTANT:  after calling this method, clients MUST call:
159
     *
160
     * $dispatcher = $container->get('eventDispatcher');
161
     * $app->setDispatcher($dispatcher);
162
     *
163
     * Any modification to the container should be done prior to fetching
164
     * objects from it.
165
     *
166
     * It is recommended to use \Robo::createDefaultContainer()
167
     * instead, which does all required setup for the caller, but has
168
     * the limitation that the container it creates can only be
169
     * extended, not modified.
170
     *
171
     * @param \League\Container\ContainerInterface $container
172
     * @param \Symfony\Component\Console\Application $app
173
     * @param \Robo\Config\Config $config
174
     * @param null|\Symfony\Component\Console\Input\InputInterface $input
175
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
176
     */
177
    public static function configureContainer(ContainerInterface $container, SymfonyApplication $app, \Robo\Config\Config $config, $input = null, $output = null)
178
    {
179
        // Self-referential container refernce for the inflector
180
        $container->add('container', $container);
181
        static::setContainer($container);
182
183
        // Create default input and output objects if they were not provided
184
        if (!$input) {
185
            $input = new StringInput('');
186
        }
187
        if (!$output) {
188
            $output = new \Symfony\Component\Console\Output\ConsoleOutput();
189
        }
190
        $config->setDecorated($output->isDecorated());
191
192
        $container->share('application', $app);
193
        $container->share('config', $config);
194
        $container->share('input', $input);
195
        $container->share('output', $output);
196
        $container->share('outputAdapter', \Robo\Common\OutputAdapter::class);
197
198
        // Register logging and related services.
199
        $container->share('logStyler', \Robo\Log\RoboLogStyle::class);
200
        $container->share('logger', \Robo\Log\RoboLogger::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
201
            ->withArgument('output')
202
            ->withMethodCall('setLogOutputStyler', ['logStyler']);
203
        $container->add('progressBar', \Symfony\Component\Console\Helper\ProgressBar::class)
204
            ->withArgument('output');
205
        $container->share('progressIndicator', \Robo\Common\ProgressIndicator::class)
206
            ->withArgument('progressBar')
207
            ->withArgument('output');
208
        $container->share('resultPrinter', \Robo\Log\ResultPrinter::class);
209
        $container->add('simulator', \Robo\Task\Simulator::class);
210
        $container->share('globalOptionsEventListener', \Robo\GlobalOptionsEventListener::class);
211
        $container->share('injectConfigEventListener', \Robo\InjectConfigEventListener::class);
212
        $container->share('collectionProcessHook', \Robo\Collection\CollectionProcessHook::class);
213
        $container->share('hookManager', \Consolidation\AnnotatedCommand\Hooks\HookManager::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
214
            ->withMethodCall('addResultProcessor', ['collectionProcessHook', '*']);
215
        $container->share('alterOptionsCommandEvent', \Consolidation\AnnotatedCommand\Options\AlterOptionsCommandEvent::class)
216
            ->withArgument('application');
217
        $container->share('eventDispatcher', \Symfony\Component\EventDispatcher\EventDispatcher::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
218
            ->withMethodCall('addSubscriber', ['injectConfigEventListener'])
219
            ->withMethodCall('addSubscriber', ['globalOptionsEventListener'])
220
            ->withMethodCall('addSubscriber', ['alterOptionsCommandEvent'])
221
            ->withMethodCall('addSubscriber', ['hookManager']);
222
        $container->share('formatterManager', \Consolidation\OutputFormatters\FormatterManager::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
223
            ->withMethodCall('addDefaultFormatters', [])
224
            ->withMethodCall('addDefaultSimplifiers', []);
225
        $container->share('prepareTerminalWidthOption', \Consolidation\AnnotatedCommand\Options\PrepareTerminalWidthOption::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
226
            ->withMethodCall('setApplication', ['application']);
227
        $container->share('commandProcessor', \Consolidation\AnnotatedCommand\CommandProcessor::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
228
            ->withArgument('hookManager')
229
            ->withMethodCall('setFormatterManager', ['formatterManager'])
230
            ->withMethodCall('addPrepareFormatter', ['prepareTerminalWidthOption'])
231
            ->withMethodCall(
232
                'setDisplayErrorFunction',
233
                [
234
                    function ($output, $message) use ($container) {
235
                        $logger = $container->get('logger');
236
                        $logger->error($message);
237
                    }
238
                ]
239
            );
240
        $container->share('commandFactory', \Consolidation\AnnotatedCommand\AnnotatedCommandFactory::class)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface League\Container\Definition\DefinitionInterface as the method withMethodCall() does only exist in the following implementations of said interface: League\Container\Definition\ClassDefinition.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
241
            ->withMethodCall('setCommandProcessor', ['commandProcessor']);
242
243
        // Deprecated: favor using collection builders to direct use of collections.
244
        $container->add('collection', \Robo\Collection\Collection::class);
245
        // Deprecated: use CollectionBuilder::create() instead -- or, better
246
        // yet, BuilderAwareInterface::collectionBuilder() if available.
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
247
        $container->add('collectionBuilder', \Robo\Collection\CollectionBuilder::class);
248
249
        static::addInflectors($container);
250
251
        // Make sure the application is appropriately initialized.
252
        $app->setAutoExit(false);
253
    }
254
255
    /**
256
     * @param null|string $appName
257
     * @param null|string $appVersion
258
     *
259
     * @return \Robo\Application
260
     */
261
    public static function createDefaultApplication($appName = null, $appVersion = null)
262
    {
263
        $appName = $appName ?: self::APPLICATION_NAME;
264
        $appVersion = $appVersion ?: self::VERSION;
265
266
        $app = new \Robo\Application($appName, $appVersion);
267
        $app->setAutoExit(false);
268
        return $app;
269
    }
270
271
    /**
272
     * Add the Robo League\Container inflectors to the container
273
     *
274
     * @param \League\Container\ContainerInterface $container
275
     */
276
    public static function addInflectors($container)
277
    {
278
        // Register our various inflectors.
279
        $container->inflector(\Robo\Contract\ConfigAwareInterface::class)
280
            ->invokeMethod('setConfig', ['config']);
281
        $container->inflector(\Psr\Log\LoggerAwareInterface::class)
282
            ->invokeMethod('setLogger', ['logger']);
283
        $container->inflector(\League\Container\ContainerAwareInterface::class)
284
            ->invokeMethod('setContainer', ['container']);
285
        $container->inflector(\Symfony\Component\Console\Input\InputAwareInterface::class)
286
            ->invokeMethod('setInput', ['input']);
287
        $container->inflector(\Robo\Contract\OutputAwareInterface::class)
288
            ->invokeMethod('setOutput', ['output']);
289
        $container->inflector(\Robo\Contract\ProgressIndicatorAwareInterface::class)
290
            ->invokeMethod('setProgressIndicator', ['progressIndicator']);
291
        $container->inflector(\Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface::class)
292
            ->invokeMethod('setHookManager', ['hookManager']);
293
        $container->inflector(\Robo\Contract\VerbosityThresholdInterface::class)
294
            ->invokeMethod('setOutputAdapter', ['outputAdapter']);
295
    }
296
297
    /**
298
     * Retrieves a service from the container.
299
     *
300
     * Use this method if the desired service is not one of those with a dedicated
301
     * accessor method below. If it is listed below, those methods are preferred
302
     * as they can return useful type hints.
303
     *
304
     * @param string $id
305
     *   The ID of the service to retrieve.
306
     *
307
     * @return mixed
308
     *   The specified service.
309
     */
310
    public static function service($id)
311
    {
312
        return static::getContainer()->get($id);
313
    }
314
315
    /**
316
     * Indicates if a service is defined in the container.
317
     *
318
     * @param string $id
319
     *   The ID of the service to check.
320
     *
321
     * @return bool
322
     *   TRUE if the specified service exists, FALSE otherwise.
323
     */
324
    public static function hasService($id)
325
    {
326
        // Check hasContainer() first in order to always return a Boolean.
327
        return static::hasContainer() && static::getContainer()->has($id);
328
    }
329
330
    /**
331
     * Return the result printer object.
332
     *
333
     * @return \Robo\Log\ResultPrinter
334
     */
335
    public static function resultPrinter()
336
    {
337
        return static::service('resultPrinter');
338
    }
339
340
    /**
341
     * @return \Robo\Config\Config
342
     */
343
    public static function config()
344
    {
345
        return static::service('config');
346
    }
347
348
    /**
349
     * @return \Consolidation\Log\Logger
350
     */
351
    public static function logger()
352
    {
353
        return static::service('logger');
354
    }
355
356
    /**
357
     * @return \Robo\Application
358
     */
359
    public static function application()
360
    {
361
        return static::service('application');
362
    }
363
364
    /**
365
     * Return the output object.
366
     *
367
     * @return \Symfony\Component\Console\Output\OutputInterface
368
     */
369
    public static function output()
370
    {
371
        return static::service('output');
372
    }
373
374
    /**
375
     * Return the input object.
376
     *
377
     * @return \Symfony\Component\Console\Input\InputInterface
378
     */
379
    public static function input()
380
    {
381
        return static::service('input');
382
    }
383
384
    public static function process(Process $process)
385
    {
386
        return ProcessExecutor::create(static::getContainer(), $process);
387
    }
388
}
389