Completed
Push — master ( 3260ca...0c0ec5 )
by Christian
02:12
created

Application::doRunCommand()   F

Complexity

Conditions 14
Paths 2451

Size

Total Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 62
rs 2.1
c 0
b 0
f 0
cc 14
nc 2451
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace N98\Magento;
4
5
use BadMethodCallException;
6
use Composer\Autoload\ClassLoader;
7
use Exception;
8
use Magento\Framework\ObjectManagerInterface;
9
use N98\Magento\Application\ApplicationAwareInterface;
10
use N98\Magento\Application\Config;
11
use N98\Magento\Application\ConfigurationLoader;
12
use N98\Magento\Application\Console\Events;
13
use N98\Magento\Application\DetectionResult;
14
use N98\Magento\Application\Magento1Initializer;
15
use N98\Magento\Application\Magento2Initializer;
16
use N98\Magento\Application\MagentoDetector;
17
use N98\Util\Console\Helper\TwigHelper;
18
use Symfony\Component\Console\Application as BaseApplication;
19
use Symfony\Component\Console\Command\Command;
20
use Symfony\Component\Console\Event\ConsoleEvent;
21
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
22
use Symfony\Component\Console\Input\ArgvInput;
23
use Symfony\Component\Console\Input\InputDefinition;
24
use Symfony\Component\Console\Input\InputInterface;
25
use Symfony\Component\Console\Input\InputOption;
26
use Symfony\Component\Console\Output\ConsoleOutput;
27
use Symfony\Component\Console\Output\OutputInterface;
28
use Symfony\Component\EventDispatcher\EventDispatcher;
29
use UnexpectedValueException;
30
31
/**
32
 * Class Application
33
 * @package N98\Magento
34
 */
35
class Application extends BaseApplication
36
{
37
    /**
38
     * @var string
39
     */
40
    const APP_NAME = 'n98-magerun2';
41
42
    /**
43
     * @var string
44
     */
45
    const APP_VERSION = '4.0.0';
46
47
    /**
48
     * @var int
49
     */
50
    const MAGENTO_MAJOR_VERSION_1 = 1;
51
    const MAGENTO_MAJOR_VERSION_2 = 2;
52
53
    /**
54
     * @var string
55
     */
56
    private static $logo = "
57
     ___ ___                                       ___
58
 _ _/ _ ( _ )___ _ __  __ _ __ _ ___ _ _ _  _ _ _ |_  )
59
| ' \\_, / _ \\___| '  \\/ _` / _` / -_) '_| || | ' \\ / /
60
|_||_/_/\\___/   |_|_|_\\__,_\\__, \\___|_|  \\_,_|_||_/___|
61
                           |___/
62
";
63
    /**
64
     * @var ClassLoader
65
     */
66
    protected $autoloader;
67
68
    /**
69
     * @var Config
70
     */
71
    protected $config;
72
73
    /**
74
     * @var bool
75
     */
76
    protected $_isPharMode = false;
77
78
    /**
79
     * @var bool
80
     */
81
    protected $_isInitialized = false;
82
83
    /**
84
     * @var EventDispatcher
85
     */
86
    protected $dispatcher;
87
88
    /**
89
     * @var ObjectManagerInterface
90
     */
91
    protected $_objectManager;
92
93
    /**
94
     * @see \N98\Magento\Application::setConfigurationLoader()
95
     * @var ConfigurationLoader
96
     */
97
    private $configurationLoaderInjected;
98
99
    /**
100
     * @var string [optional] root folder not detected, but set via public setter
101
     * @see setMagentoRootFolder()
102
     */
103
    private $magentoRootFolderInjected;
104
105
    /**
106
     * @var int Magento Major Version to operate on by this Magerun application
107
     */
108
    private $magerunMajorVersion = self::MAGENTO_MAJOR_VERSION_2;
109
110
    /**
111
     * @var DetectionResult of the Magento application (e.g. v1/v2, Enterprise/Community, root-path)
112
     */
113
    private $detectionResult;
114
115
    /**
116
     * @var boolean
117
     */
118
    private $autoExit = true;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
119
120
    /**
121
     * @param ClassLoader $autoloader
0 ignored issues
show
Documentation introduced by
Should the type for parameter $autoloader not be ClassLoader|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
122
     */
123
    public function __construct($autoloader = null)
124
    {
125
        $this->autoloader = $autoloader;
126
        parent::__construct(self::APP_NAME, self::APP_VERSION);
127
    }
128
129
    /**
130
     * Sets whether to automatically exit after a command execution or not.
131
     *
132
     * Implemented on this level to allow early exit on configuration exceptions
133
     *
134
     * @see run()
135
     *
136
     * @param bool $boolean Whether to automatically exit after a command execution or not
137
     */
138
    public function setAutoExit($boolean)
139
    {
140
        $this->autoExit = (bool) $boolean;
141
        parent::setAutoExit($boolean);
142
    }
143
144
    /**
145
     * @param bool $mode
146
     */
147
    public function setPharMode($mode)
148
    {
149
        $this->_isPharMode = $mode;
150
    }
151
152
    /**
153
     * @return string
154
     */
155
    public function getHelp()
156
    {
157
        return self::$logo . parent::getHelp();
158
    }
159
160
    public function getLongVersion()
161
    {
162
        return parent::getLongVersion() . ' by <info>netz98 GmbH</info>';
163
    }
164
165
    /**
166
     * @return boolean
167
     */
168
    public function isMagentoEnterprise()
169
    {
170
        return $this->detectionResult->isEnterpriseEdition();
171
    }
172
173
    /**
174
     * @param string $magentoRootFolder
175
     */
176
    public function setMagentoRootFolder($magentoRootFolder)
177
    {
178
        $this->magentoRootFolderInjected = $magentoRootFolder;
179
    }
180
181
    /**
182
     * @return int|null
183
     */
184
    public function getMagentoMajorVersion()
185
    {
186
        return $this->detectionResult ? $this->detectionResult->getMajorVersion() : null;
187
    }
188
189
    /**
190
     * @return array
191
     */
192
    public function getConfig()
193
    {
194
        // TODO(TK) getter for config / getter for config array
195
        return $this->config->getConfig();
196
    }
197
198
    /**
199
     * @param array $config
200
     */
201
    public function setConfig($config)
202
    {
203
        $this->config->setConfig($config);
204
    }
205
206
    /**
207
     * Runs the current application with possible command aliases
208
     *
209
     * @param InputInterface $input An Input instance
210
     * @param OutputInterface $output An Output instance
211
     *
212
     * @return int 0 if everything went fine, or an error code
213
     * @throws \Magento\Framework\Exception\FileSystemException
214
     * @throws \Exception
215
     * @throws \Throwable
216
     */
217
    public function doRun(InputInterface $input, OutputInterface $output)
218
    {
219
        $input = $this->config->checkConfigCommandAlias($input);
220
221
        $event = new ConsoleEvent(new \N98\Magento\Command\DummyCommand(), $input, $output);
222
        $this->dispatcher->dispatch($event, Events::RUN_BEFORE);
223
224
        return parent::doRun($input, $output);
225
    }
226
227
    /**
228
     * Loads and initializes the Magento application
229
     *
230
     * @param bool $soft
231
     *
232
     * @return bool false if magento root folder is not set, true otherwise
233
     * @throws \Exception
234
     */
235
    public function initMagento($soft = false)
0 ignored issues
show
Unused Code introduced by
The parameter $soft is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
236
    {
237
        if ($this->getMagentoRootFolder(true) === null) {
238
            return false;
239
        }
240
241
        $isMagento2 = $this->detectionResult->getMajorVersion() === self::MAGENTO_MAJOR_VERSION_2;
242
        if ($isMagento2) {
243
            $magento2Initializer = new Magento2Initializer($this->getAutoloader());
244
            $app = $magento2Initializer->init($this->getMagentoRootFolder());
245
            $this->_objectManager = $app->getObjectManager();
246
        } else {
247
            $magento1Initializer = new Magento1Initializer($this->getHelperSet());
248
            $magento1Initializer->init();
249
        }
250
251
        return true;
252
    }
253
254
    /**
255
     * @param bool $preventException [optional] on uninitialized magento root folder (returns null then, caution!)
256
     * @return string|null
257
     */
258
    public function getMagentoRootFolder($preventException = false)
259
    {
260
        if (null !== $this->magentoRootFolderInjected) {
261
            return $this->magentoRootFolderInjected;
262
        }
263
264
        if ($preventException) {
265
            return $this->detectionResult ? $this->detectionResult->getRootFolder() : null;
266
        }
267
268
        if (!$this->detectionResult) {
269
            throw new BadMethodCallException('Magento-root-folder is not yet detected (nor set)');
270
        }
271
272
        return $this->detectionResult->getRootFolder();
273
    }
274
275
    /**
276
     * @return ClassLoader
277
     */
278
    public function getAutoloader()
279
    {
280
        return $this->autoloader;
281
    }
282
283
    /**
284
     * @param ClassLoader $autoloader
285
     */
286
    public function setAutoloader(ClassLoader $autoloader)
287
    {
288
        $this->autoloader = $autoloader;
289
    }
290
291
    /**
292
     * @param InputInterface $input [optional]
293
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
294
     *
295
     * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be null|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
296
     * @throws \Exception
297
     */
298
    public function run(InputInterface $input = null, OutputInterface $output = null)
299
    {
300
        if (null === $input) {
301
            $input = new ArgvInput();
302
        }
303
304
        if (null === $output) {
305
            $output = new ConsoleOutput();
306
        }
307
        $this->_addOutputStyles($output);
308
        if ($output instanceof ConsoleOutput) {
309
            $this->_addOutputStyles($output->getErrorOutput());
310
        }
311
312
        $this->configureIO($input, $output);
313
314
        try {
315
            $this->init([], $input, $output);
316
        } catch (Exception $e) {
317
            $output = new ConsoleOutput();
318
            $this->renderThrowable($e, $output->getErrorOutput());
319
            $exitCode = max(1, min(255, (int) $e->getCode()));
320
            if ($this->autoExit) {
321
                die($exitCode);
322
            }
323
324
            return $exitCode;
325
        }
326
327
        $return = parent::run($input, $output);
328
329
        // Fix for no return values -> used in interactive shell to prevent error output
330
        if ($return === null) {
331
            return 0;
332
        }
333
334
        return $return;
335
    }
336
337
    /**
338
     * @param OutputInterface $output
339
     */
340
    protected function _addOutputStyles(OutputInterface $output)
341
    {
342
        $output->getFormatter()->setStyle('debug', new OutputFormatterStyle('magenta', 'white'));
343
        $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('red', 'yellow', ['bold']));
344
    }
345
346
    /**
347
     * @param array $initConfig [optional]
348
     * @param InputInterface $input [optional]
349
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
350
     *
351
     * @return void
352
     * @throws \Exception
353
     */
354
    public function init(array $initConfig = [], InputInterface $input = null, OutputInterface $output = null)
355
    {
356
        if ($this->_isInitialized) {
357
            return;
358
        }
359
360
        // Suppress DateTime warnings
361
        date_default_timezone_set(@date_default_timezone_get());
362
363
        // Initialize EventDispatcher early
364
        $this->dispatcher = new EventDispatcher();
365
        $this->setDispatcher($this->dispatcher);
366
367
        $input = $input ?: new ArgvInput();
368
        $output = $output ?: new ConsoleOutput();
369
370
        if (null !== $this->config) {
371
            throw new UnexpectedValueException(sprintf('Config already initialized'));
372
        }
373
374
        $loadExternalConfig = !$this->_checkSkipConfigOption($input);
375
376
        $this->config = new Config($initConfig, $this->isPharMode(), $output);
377
        if ($this->configurationLoaderInjected) {
378
            $this->config->setLoader($this->configurationLoaderInjected);
379
        }
380
        $this->config->loadPartialConfig($loadExternalConfig);
381
        $this->detectMagento($input, $output);
382
383
        $configLoader = $this->config->getLoader();
384
        $configLoader->loadStageTwo(
385
            $this->getMagentoRootFolder(true),
386
            $loadExternalConfig,
387
            $this->detectionResult->getMagerunStopFileFolder()
388
        );
389
        $this->config->load();
390
391
        if ($autoloader = $this->autoloader) {
392
            /**
393
             * Include commands shipped by Magento 2 core
394
             */
395
            if (!$this->_checkSkipMagento2CoreCommandsOption($input)) {
396
                $this->registerMagentoCoreCommands($output);
397
            }
398
            $this->config->registerCustomAutoloaders($autoloader);
399
            $this->registerEventSubscribers($input, $output);
400
            $this->config->registerCustomCommands($this);
401
        }
402
403
        $this->registerHelpers();
404
405
        $this->_isInitialized = true;
406
    }
407
408
    /**
409
     * @param InputInterface $input
410
     * @return bool
411
     */
412
    protected function _checkSkipConfigOption(InputInterface $input)
413
    {
414
        return $input->hasParameterOption('--skip-config');
415
    }
416
417
    /**
418
     * @return bool
419
     */
420
    public function isPharMode()
421
    {
422
        return $this->_isPharMode;
423
    }
424
425
    /**
426
     * Search for magento root folder
427
     *
428
     * @param InputInterface $input [optional]
429
     * @param OutputInterface $output [optional]
430
     * @return void
431
     * @throws \Exception
432
     */
433
    public function detectMagento(InputInterface $input = null, OutputInterface $output = null)
434
    {
435
        if ($this->detectionResult) {
436
            return;
437
        }
438
439
        $magentoRootDirectory = $this->getMagentoRootFolder(true);
440
441
        $detector = new MagentoDetector();
442
        $this->detectionResult = $detector->detect(
443
            $input,
0 ignored issues
show
Bug introduced by
It seems like $input defined by parameter $input on line 433 can be null; however, N98\Magento\Application\MagentoDetector::detect() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
444
            $output,
0 ignored issues
show
Bug introduced by
It seems like $output defined by parameter $output on line 433 can be null; however, N98\Magento\Application\MagentoDetector::detect() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
445
            $this->config,
446
            $this->getHelperSet(),
447
            $magentoRootDirectory
448
        );
449
450
        if ($this->detectionResult->isDetected()) {
451
            $magentoMajorVersion = $this->detectionResult->getMajorVersion();
452
            if ($magentoMajorVersion !== $this->magerunMajorVersion) {
453
                $magento1Initialiter = new Magento1Initializer($this->getHelperSet());
454
                $magento1Initialiter->init();
455
            }
456
        }
457
    }
458
459
    /**
460
     * @return bool
461
     */
462
    protected function _checkSkipMagento2CoreCommandsOption(InputInterface $input)
463
    {
464
        return $input->hasParameterOption('--skip-core-commands') || getenv('MAGERUN_SKIP_CORE_COMMANDS');
465
    }
466
467
    /**
468
     * Try to bootstrap magento 2 and load cli application
469
     *
470
     * @param OutputInterface $output
471
     */
472
    protected function registerMagentoCoreCommands(OutputInterface $output)
473
    {
474
        $magentoRootFolder = $this->getMagentoRootFolder();
475
        if (0 === strlen($magentoRootFolder)) {
476
            return;
477
        }
478
479
        // Magento was found -> register core cli commands
480
        try {
481
            $this->requireOnce($magentoRootFolder . '/app/bootstrap.php');
482
483
            // Magento 2.3.1 removes phar stream wrapper.
484
            if (!in_array('phar', \stream_get_wrappers(), true)) {
485
                \stream_wrapper_restore('phar');
486
            }
487
        } catch (\Exception $ex) {
488
            $this->renderThrowable($ex, $output);
489
            $output->writeln(
490
                '<info>Use --skip-core-commands to not require the Magento app/bootstrap.php which caused ' .
491
                'the exception.</info>'
492
            );
493
494
            return;
495
        }
496
497
        $coreCliApplication = new \Magento\Framework\Console\Cli();
498
        $coreCliApplicationCommands = $coreCliApplication->all();
499
500
        foreach ($coreCliApplicationCommands as $coreCliApplicationCommand) {
501
            if (OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity()) {
502
                $output->writeln(
503
                    sprintf(
504
                        '<debug>Add core command </debug> <info>%s</info> -> <comment>%s</comment>',
505
                        $coreCliApplicationCommand->getName(),
506
                        get_class($coreCliApplicationCommand)
507
                    )
508
                );
509
            }
510
            $this->add($coreCliApplicationCommand);
511
        }
512
    }
513
514
    /**
515
     * use require-once inside a function with it's own variable scope w/o any other variables
516
     * and $this unbound.
517
     *
518
     * @param string $path
519
     */
520 View Code Duplication
    private function requireOnce($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
521
    {
522
        $requireOnce = function () {
523
            require_once func_get_arg(0);
524
        };
525
        if (50400 <= PHP_VERSION_ID) {
526
            $requireOnce->bindTo(null);
527
        }
528
529
        $requireOnce($path);
530
    }
531
532
    /**
533
     * Override standard command registration. We want alias support.
534
     *
535
     * @param Command $command
536
     *
537
     * @return Command
0 ignored issues
show
Documentation introduced by
Should the return type not be Command|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
538
     */
539
    public function add(Command $command)
540
    {
541
        if ($this->config) {
542
            $this->config->registerConfigCommandAlias($command);
543
        }
544
545
        return parent::add($command);
546
    }
547
548
    /**
549
     * @return void
550
     */
551
    protected function registerEventSubscribers(InputInterface $input, OutputInterface $output)
552
    {
553
        $config = $this->config->getConfig();
554
555
        if (!isset($config['event']['subscriber'])) {
556
            return;
557
        }
558
559
        $subscriberClasses = $config['event']['subscriber'];
560
        foreach ($subscriberClasses as $subscriberClass) {
561
            $subscriber = new $subscriberClass($this, $input, $output);
562
563
            if ($subscriber instanceof ApplicationAwareInterface) {
564
                $subscriber->setApplication($this);
565
            }
566
567
            $this->dispatcher->addSubscriber($subscriber);
568
        }
569
    }
570
571
    /**
572
     * Add own helpers to helperset.
573
     *
574
     * @return void
575
     */
576
    protected function registerHelpers()
577
    {
578
        $helperSet = $this->getHelperSet();
579
        $config = $this->config->getConfig();
580
581
        if (empty($config)) {
582
            return;
583
        }
584
585
        // Twig
586
        $twigBaseDirs = [
587
            __DIR__ . '/../../../res/twig',
588
        ];
589
        if (isset($config['twig']['baseDirs']) && is_array($config['twig']['baseDirs'])) {
590
            $twigBaseDirs = array_merge(array_reverse($config['twig']['baseDirs']), $twigBaseDirs);
591
        }
592
        $helperSet->set(new TwigHelper($twigBaseDirs), 'twig');
593
594
        foreach ($config['helpers'] as $helperName => $helperClass) {
595
            if (class_exists($helperClass)) {
596
                $helperSet->set(new $helperClass(), $helperName);
597
            }
598
        }
599
    }
600
601
    /**
602
     * @param array $initConfig [optional]
603
     * @param InputInterface $input [optional]
604
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
605
     * @throws \Exception
606
     */
607
    public function reinit($initConfig = [], InputInterface $input = null, OutputInterface $output = null)
608
    {
609
        $this->_isInitialized = false;
610
        $this->detectionResult = null;
611
        $this->config = null;
612
        $this->init($initConfig, $input, $output);
613
    }
614
615
    /**
616
     * @param ConfigurationLoader $configurationLoader
617
     */
618
    public function setConfigurationLoader(ConfigurationLoader $configurationLoader)
619
    {
620
        if ($this->config) {
621
            $this->config->setLoader($configurationLoader);
622
        } else {
623
            /* inject loader to be used later when config is created in */
624
            /* @see \N98\Magento\Application::init() */
625
            $this->configurationLoaderInjected = $configurationLoader;
626
        }
627
    }
628
629
    /**
630
     * @return ObjectManagerInterface
631
     */
632
    public function getObjectManager()
633
    {
634
        return $this->_objectManager;
635
    }
636
637
    /**
638
     * @return InputDefinition
639
     */
640
    protected function getDefaultInputDefinition()
641
    {
642
        $inputDefinition = parent::getDefaultInputDefinition();
643
644
        /**
645
         * Root dir
646
         */
647
        $rootDirOption = new InputOption(
648
            '--root-dir',
649
            '',
650
            InputOption::VALUE_OPTIONAL,
651
            'Force magento root dir. No auto detection'
652
        );
653
        $inputDefinition->addOption($rootDirOption);
654
655
        /**
656
         * Skip config
657
         */
658
        $skipExternalConfig = new InputOption(
659
            '--skip-config',
660
            '',
661
            InputOption::VALUE_NONE,
662
            'Do not load any custom config.'
663
        );
664
        $inputDefinition->addOption($skipExternalConfig);
665
666
        /**
667
         * Skip root check
668
         */
669
        $skipExternalConfig = new InputOption(
670
            '--skip-root-check',
671
            '',
672
            InputOption::VALUE_NONE,
673
            'Do not check if n98-magerun runs as root'
674
        );
675
        $inputDefinition->addOption($skipExternalConfig);
676
677
        /**
678
         * Skip core commands
679
         */
680
        $skipMagento2CoreCommands = new InputOption(
681
            '--skip-core-commands',
682
            '',
683
            InputOption::VALUE_OPTIONAL,
684
            'Do not include Magento 2 core commands'
685
        );
686
        $inputDefinition->addOption($skipMagento2CoreCommands);
687
688
        return $inputDefinition;
689
    }
690
}
691