Completed
Push — master ( a20e35...2a3e96 )
by Greg
03:21
created

src/Robo.php (9 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Robo;
3
4
use Composer\Autoload\ClassLoader;
5
use League\Container\Container;
6
use League\Container\ContainerInterface;
7
use Robo\Common\ProcessExecutor;
8
use Consolidation\Config\ConfigInterface;
9
use Consolidation\Config\Loader\ConfigProcessor;
10
use Consolidation\Config\Loader\YamlConfigLoader;
11
use Symfony\Component\Console\Input\StringInput;
12
use Symfony\Component\Console\Application as SymfonyApplication;
13
use Symfony\Component\Process\Process;
14
15
/**
16
 * Manages the container reference and other static data.  Favor
17
 * using dependency injection wherever possible.  Avoid using
18
 * this class directly, unless setting up a custom DI container.
19
 */
20
class Robo
21
{
22
    const APPLICATION_NAME = 'Robo';
23
    const VERSION = '1.3.3-dev';
24
25
    /**
26
     * The currently active container object, or NULL if not initialized yet.
27
     *
28
     * @var ContainerInterface|null
29
     */
30
    protected static $container;
31
32
    /**
33
     * Entrypoint for standalone Robo-based tools.  See docs/framework.md.
34
     *
35
     * @param string[] $argv
36
     * @param string $commandClasses
37
     * @param null|string $appName
38
     * @param null|string $appVersion
39
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
40
     *
41
     * @return int
42
     */
43
    public static function run($argv, $commandClasses, $appName = null, $appVersion = null, $output = null, $repository = null)
44
    {
45
        $runner = new \Robo\Runner($commandClasses);
46
        $runner->setSelfUpdateRepository($repository);
47
        $statusCode = $runner->execute($argv, $appName, $appVersion, $output);
48
        return $statusCode;
49
    }
50
51
    /**
52
     * Sets a new global container.
53
     *
54
     * @param ContainerInterface $container
55
     *   A new container instance to replace the current.
56
     */
57
    public static function setContainer(ContainerInterface $container)
58
    {
59
        static::$container = $container;
60
    }
61
62
    /**
63
     * Unsets the global container.
64
     */
65
    public static function unsetContainer()
66
    {
67
        static::$container = null;
68
    }
69
70
    /**
71
     * Returns the currently active global container.
72
     *
73
     * @return \League\Container\ContainerInterface
74
     *
75
     * @throws \RuntimeException
76
     */
77
    public static function getContainer()
78
    {
79
        if (static::$container === null) {
80
            throw new \RuntimeException('container is not initialized yet. \Robo\Robo::setContainer() must be called with a real container.');
81
        }
82
        return static::$container;
83
    }
84
85
    /**
86
     * Returns TRUE if the container has been initialized, FALSE otherwise.
87
     *
88
     * @return bool
89
     */
90
    public static function hasContainer()
91
    {
92
        return static::$container !== null;
93
    }
94
95
    /**
96
     * Create a config object and load it from the provided paths.
97
     */
98
    public static function createConfiguration($paths)
99
    {
100
        $config = new \Robo\Config\Config();
101
        static::loadConfiguration($paths, $config);
102
        return $config;
103
    }
104
105
    /**
106
     * Use a simple config loader to load configuration values from specified paths
107
     */
108
    public static function loadConfiguration($paths, $config = null)
109
    {
110
        if ($config == null) {
111
            $config = static::config();
112
        }
113
        $loader = new YamlConfigLoader();
114
        $processor = new ConfigProcessor();
115
        $processor->add($config->export());
116
        foreach ($paths as $path) {
117
            $processor->extend($loader->load($path));
118
        }
119
        $config->import($processor->export());
120
    }
121
122
    /**
123
     * Create a container and initiailze it.  If you wish to *change*
124
     * anything defined in the container, then you should call
125
     * \Robo::configureContainer() instead of this function.
126
     *
127
     * @param null|\Symfony\Component\Console\Input\InputInterface $input
128
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
129
     * @param null|\Robo\Application $app
130
     * @param null|ConfigInterface $config
131
     * @param null|\Composer\Autoload\ClassLoader $classLoader
132
     *
133
     * @return \League\Container\Container|\League\Container\ContainerInterface
134
     */
135
    public static function createDefaultContainer($input = null, $output = null, $app = null, $config = null, $classLoader = null)
136
    {
137
        // Do not allow this function to be called more than once.
138
        if (static::hasContainer()) {
139
            return static::getContainer();
140
        }
141
142
        if (!$app) {
143
            $app = static::createDefaultApplication();
144
        }
145
146
        if (!$config) {
147
            $config = new \Robo\Config\Config();
148
        }
149
150
        // Set up our dependency injection container.
151
        $container = new Container();
152
        static::configureContainer($container, $app, $config, $input, $output, $classLoader);
153
154
        // Set the application dispatcher
155
        $app->setDispatcher($container->get('eventDispatcher'));
156
157
        return $container;
158
    }
159
160
    /**
161
     * Initialize a container with all of the default Robo services.
162
     * IMPORTANT:  after calling this method, clients MUST call:
163
     *
164
     * $dispatcher = $container->get('eventDispatcher');
165
     * $app->setDispatcher($dispatcher);
166
     *
167
     * Any modification to the container should be done prior to fetching
168
     * objects from it.
169
     *
170
     * It is recommended to use \Robo::createDefaultContainer()
171
     * instead, which does all required setup for the caller, but has
172
     * the limitation that the container it creates can only be
173
     * extended, not modified.
174
     *
175
     * @param \League\Container\ContainerInterface $container
176
     * @param \Symfony\Component\Console\Application $app
177
     * @param ConfigInterface $config
178
     * @param null|\Symfony\Component\Console\Input\InputInterface $input
179
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
180
     * @param null|\Composer\Autoload\ClassLoader $classLoader
181
     */
182
    public static function configureContainer(ContainerInterface $container, SymfonyApplication $app, ConfigInterface $config, $input = null, $output = null, $classLoader = null)
183
    {
184
        // Self-referential container refernce for the inflector
185
        $container->add('container', $container);
186
        static::setContainer($container);
187
188
        // Create default input and output objects if they were not provided
189
        if (!$input) {
190
            $input = new StringInput('');
191
        }
192
        if (!$output) {
193
            $output = new \Symfony\Component\Console\Output\ConsoleOutput();
194
        }
195
        if (!$classLoader) {
196
            $classLoader = new ClassLoader();
197
        }
198
        $config->set(Config::DECORATED, $output->isDecorated());
199
        $config->set(Config::INTERACTIVE, $input->isInteractive());
200
201
        $container->share('application', $app);
202
        $container->share('config', $config);
203
        $container->share('input', $input);
204
        $container->share('output', $output);
205
        $container->share('outputAdapter', \Robo\Common\OutputAdapter::class);
206
        $container->share('classLoader', $classLoader);
207
208
        // Register logging and related services.
209
        $container->share('logStyler', \Robo\Log\RoboLogStyle::class);
210
        $container->share('logger', \Robo\Log\RoboLogger::class)
0 ignored issues
show
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...
211
            ->withArgument('output')
212
            ->withMethodCall('setLogOutputStyler', ['logStyler']);
213
        $container->add('progressBar', \Symfony\Component\Console\Helper\ProgressBar::class)
214
            ->withArgument('output');
215
        $container->share('progressIndicator', \Robo\Common\ProgressIndicator::class)
216
            ->withArgument('progressBar')
217
            ->withArgument('output');
218
        $container->share('resultPrinter', \Robo\Log\ResultPrinter::class);
219
        $container->add('simulator', \Robo\Task\Simulator::class);
220
        $container->share('globalOptionsEventListener', \Robo\GlobalOptionsEventListener::class)
0 ignored issues
show
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...
221
            ->withMethodCall('setApplication', ['application']);
222
        $container->share('injectConfigEventListener', \Consolidation\Config\Inject\ConfigForCommand::class)
0 ignored issues
show
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
            ->withArgument('config')
224
            ->withMethodCall('setApplication', ['application']);
225
        $container->share('collectionProcessHook', \Robo\Collection\CollectionProcessHook::class);
226
        $container->share('alterOptionsCommandEvent', \Consolidation\AnnotatedCommand\Options\AlterOptionsCommandEvent::class)
227
            ->withArgument('application');
228
        $container->share('hookManager', \Consolidation\AnnotatedCommand\Hooks\HookManager::class)
0 ignored issues
show
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...
229
            ->withMethodCall('addCommandEvent', ['alterOptionsCommandEvent'])
230
            ->withMethodCall('addCommandEvent', ['injectConfigEventListener'])
231
            ->withMethodCall('addCommandEvent', ['globalOptionsEventListener'])
232
            ->withMethodCall('addResultProcessor', ['collectionProcessHook', '*']);
233
        $container->share('eventDispatcher', \Symfony\Component\EventDispatcher\EventDispatcher::class)
0 ignored issues
show
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...
234
            ->withMethodCall('addSubscriber', ['hookManager']);
235
        $container->share('formatterManager', \Consolidation\OutputFormatters\FormatterManager::class)
0 ignored issues
show
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...
236
            ->withMethodCall('addDefaultFormatters', [])
237
            ->withMethodCall('addDefaultSimplifiers', []);
238
        $container->share('prepareTerminalWidthOption', \Consolidation\AnnotatedCommand\Options\PrepareTerminalWidthOption::class)
0 ignored issues
show
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...
239
            ->withMethodCall('setApplication', ['application']);
240
        $container->share('commandProcessor', \Consolidation\AnnotatedCommand\CommandProcessor::class)
0 ignored issues
show
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
            ->withArgument('hookManager')
242
            ->withMethodCall('setFormatterManager', ['formatterManager'])
243
            ->withMethodCall('addPrepareFormatter', ['prepareTerminalWidthOption'])
244
            ->withMethodCall(
245
                'setDisplayErrorFunction',
246
                [
247
                    function ($output, $message) use ($container) {
248
                        $logger = $container->get('logger');
249
                        $logger->error($message);
250
                    }
251
                ]
252
            );
253
        $container->share('commandFactory', \Consolidation\AnnotatedCommand\AnnotatedCommandFactory::class)
0 ignored issues
show
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...
254
            ->withMethodCall('setCommandProcessor', ['commandProcessor']);
255
        $container->share('relativeNamespaceDiscovery', \Robo\ClassDiscovery\RelativeNamespaceDiscovery::class)
256
            ->withArgument('classLoader');
257
258
        // Deprecated: favor using collection builders to direct use of collections.
259
        $container->add('collection', \Robo\Collection\Collection::class);
260
        // Deprecated: use CollectionBuilder::create() instead -- or, better
261
        // yet, BuilderAwareInterface::collectionBuilder() if available.
262
        $container->add('collectionBuilder', \Robo\Collection\CollectionBuilder::class);
263
264
        static::addInflectors($container);
265
266
        // Make sure the application is appropriately initialized.
267
        $app->setAutoExit(false);
268
    }
269
270
    /**
271
     * @param null|string $appName
272
     * @param null|string $appVersion
273
     *
274
     * @return \Robo\Application
275
     */
276
    public static function createDefaultApplication($appName = null, $appVersion = null)
277
    {
278
        $appName = $appName ?: self::APPLICATION_NAME;
279
        $appVersion = $appVersion ?: self::VERSION;
280
281
        $app = new \Robo\Application($appName, $appVersion);
282
        $app->setAutoExit(false);
283
        return $app;
284
    }
285
286
    /**
287
     * Add the Robo League\Container inflectors to the container
288
     *
289
     * @param \League\Container\ContainerInterface $container
290
     */
291
    public static function addInflectors($container)
292
    {
293
        // Register our various inflectors.
294
        $container->inflector(\Robo\Contract\ConfigAwareInterface::class)
295
            ->invokeMethod('setConfig', ['config']);
296
        $container->inflector(\Psr\Log\LoggerAwareInterface::class)
297
            ->invokeMethod('setLogger', ['logger']);
298
        $container->inflector(\League\Container\ContainerAwareInterface::class)
299
            ->invokeMethod('setContainer', ['container']);
300
        $container->inflector(\Symfony\Component\Console\Input\InputAwareInterface::class)
301
            ->invokeMethod('setInput', ['input']);
302
        $container->inflector(\Robo\Contract\OutputAwareInterface::class)
303
            ->invokeMethod('setOutput', ['output']);
304
        $container->inflector(\Robo\Contract\ProgressIndicatorAwareInterface::class)
305
            ->invokeMethod('setProgressIndicator', ['progressIndicator']);
306
        $container->inflector(\Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface::class)
307
            ->invokeMethod('setHookManager', ['hookManager']);
308
        $container->inflector(\Robo\Contract\VerbosityThresholdInterface::class)
309
            ->invokeMethod('setOutputAdapter', ['outputAdapter']);
310
    }
311
312
    /**
313
     * Retrieves a service from the container.
314
     *
315
     * Use this method if the desired service is not one of those with a dedicated
316
     * accessor method below. If it is listed below, those methods are preferred
317
     * as they can return useful type hints.
318
     *
319
     * @param string $id
320
     *   The ID of the service to retrieve.
321
     *
322
     * @return mixed
323
     *   The specified service.
324
     */
325
    public static function service($id)
326
    {
327
        return static::getContainer()->get($id);
328
    }
329
330
    /**
331
     * Indicates if a service is defined in the container.
332
     *
333
     * @param string $id
334
     *   The ID of the service to check.
335
     *
336
     * @return bool
337
     *   TRUE if the specified service exists, FALSE otherwise.
338
     */
339
    public static function hasService($id)
340
    {
341
        // Check hasContainer() first in order to always return a Boolean.
342
        return static::hasContainer() && static::getContainer()->has($id);
343
    }
344
345
    /**
346
     * Return the result printer object.
347
     *
348
     * @return \Robo\Log\ResultPrinter
349
     */
350
    public static function resultPrinter()
351
    {
352
        return static::service('resultPrinter');
353
    }
354
355
    /**
356
     * @return ConfigInterface
357
     */
358
    public static function config()
359
    {
360
        return static::service('config');
361
    }
362
363
    /**
364
     * @return \Consolidation\Log\Logger
365
     */
366
    public static function logger()
367
    {
368
        return static::service('logger');
369
    }
370
371
    /**
372
     * @return \Robo\Application
373
     */
374
    public static function application()
375
    {
376
        return static::service('application');
377
    }
378
379
    /**
380
     * Return the output object.
381
     *
382
     * @return \Symfony\Component\Console\Output\OutputInterface
383
     */
384
    public static function output()
385
    {
386
        return static::service('output');
387
    }
388
389
    /**
390
     * Return the input object.
391
     *
392
     * @return \Symfony\Component\Console\Input\InputInterface
393
     */
394
    public static function input()
395
    {
396
        return static::service('input');
397
    }
398
399
    public static function process(Process $process)
400
    {
401
        return ProcessExecutor::create(static::getContainer(), $process);
402
    }
403
}
404