Passed
Push — develop ( 30cf64...589229 )
by Guillaume
06:18 queued 04:10
created

Command::handleArguments()   F

Complexity

Conditions 59
Paths > 20000

Size

Total Lines 235
Code Lines 131

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 59
eloc 131
nc 18627866
nop 1
dl 0
loc 235
rs 0
c 0
b 0
f 0

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 declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PHPUnit\TextUI;
11
12
use PharIo\Manifest\ApplicationName;
13
use PharIo\Manifest\Exception as ManifestException;
14
use PharIo\Manifest\ManifestLoader;
15
use PharIo\Version\Version as PharIoVersion;
16
use PHPUnit\Framework\Exception;
17
use PHPUnit\Framework\TestSuite;
18
use PHPUnit\Runner\StandardTestSuiteLoader;
19
use PHPUnit\Runner\TestSuiteLoader;
20
use PHPUnit\Runner\Version;
21
use PHPUnit\TextUI\Arguments\Arguments;
22
use PHPUnit\TextUI\Arguments\ArgumentsBuilder;
23
use PHPUnit\TextUI\Arguments\ArgumentsMapper;
24
use PHPUnit\TextUI\Arguments\Exception as ArgumentsException;
25
use PHPUnit\TextUI\Configuration\Generator;
26
use PHPUnit\TextUI\Configuration\PhpHandler;
27
use PHPUnit\TextUI\Configuration\Registry;
28
use PHPUnit\TextUI\Configuration\TestSuiteMapper;
29
use PHPUnit\Util\FileLoader;
30
use PHPUnit\Util\Filesystem;
31
use PHPUnit\Util\Printer;
32
use PHPUnit\Util\TextTestListRenderer;
33
use PHPUnit\Util\XmlTestListRenderer;
34
use SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
35
36
/**
37
 * A TestRunner for the Command Line Interface (CLI)
38
 * PHP SAPI Module.
39
 */
40
class Command
41
{
42
    /**
43
     * @var array<string,mixed>
44
     */
45
    protected $arguments = [];
46
47
    /**
48
     * @var array<string,mixed>
49
     */
50
    protected $longOptions = [];
51
52
    /**
53
     * @var bool
54
     */
55
    private $versionStringPrinted = false;
56
57
    /**
58
     * @psalm-var list<string>
59
     */
60
    private $warnings = [];
61
62
    /**
63
     * @throws \PHPUnit\Framework\Exception
64
     */
65
    public static function main(bool $exit = true): int
66
    {
67
        return (new static)->run($_SERVER['argv'], $exit);
68
    }
69
70
    /**
71
     * @throws Exception
72
     */
73
    public function run(array $argv, bool $exit = true): int
74
    {
75
        $this->handleArguments($argv);
76
77
        $runner = $this->createRunner();
78
79
        if ($this->arguments['test'] instanceof TestSuite) {
80
            $suite = $this->arguments['test'];
81
        } else {
82
            $suite = $runner->getTest(
83
                $this->arguments['test'],
84
                $this->arguments['testSuffixes']
85
            );
86
        }
87
88
        if ($this->arguments['listGroups']) {
89
            return $this->handleListGroups($suite, $exit);
90
        }
91
92
        if ($this->arguments['listSuites']) {
93
            return $this->handleListSuites($exit);
94
        }
95
96
        if ($this->arguments['listTests']) {
97
            return $this->handleListTests($suite, $exit);
98
        }
99
100
        if ($this->arguments['listTestsXml']) {
101
            return $this->handleListTestsXml($suite, $this->arguments['listTestsXml'], $exit);
102
        }
103
104
        unset($this->arguments['test'], $this->arguments['testFile']);
105
106
        try {
107
            $result = $runner->run($suite, $this->arguments, $this->warnings, $exit);
108
        } catch (Exception $e) {
109
            print $e->getMessage() . \PHP_EOL;
110
        }
111
112
        $return = TestRunner::FAILURE_EXIT;
113
114
        if (isset($result) && $result->wasSuccessful()) {
115
            $return = TestRunner::SUCCESS_EXIT;
116
        } elseif (!isset($result) || $result->errorCount() > 0) {
117
            $return = TestRunner::EXCEPTION_EXIT;
118
        }
119
120
        if ($exit) {
121
            exit($return);
122
        }
123
124
        return $return;
125
    }
126
127
    /**
128
     * Create a TestRunner, override in subclasses.
129
     */
130
    protected function createRunner(): TestRunner
131
    {
132
        return new TestRunner($this->arguments['loader']);
133
    }
134
135
    /**
136
     * Handles the command-line arguments.
137
     *
138
     * A child class of PHPUnit\TextUI\Command can hook into the argument
139
     * parsing by adding the switch(es) to the $longOptions array and point to a
140
     * callback method that handles the switch(es) in the child class like this
141
     *
142
     * <code>
143
     * <?php
144
     * class MyCommand extends PHPUnit\TextUI\Command
145
     * {
146
     *     public function __construct()
147
     *     {
148
     *         // my-switch won't accept a value, it's an on/off
149
     *         $this->longOptions['my-switch'] = 'myHandler';
150
     *         // my-secondswitch will accept a value - note the equals sign
151
     *         $this->longOptions['my-secondswitch='] = 'myOtherHandler';
152
     *     }
153
     *
154
     *     // --my-switch  -> myHandler()
155
     *     protected function myHandler()
156
     *     {
157
     *     }
158
     *
159
     *     // --my-secondswitch foo -> myOtherHandler('foo')
160
     *     protected function myOtherHandler ($value)
161
     *     {
162
     *     }
163
     *
164
     *     // You will also need this - the static keyword in the
165
     *     // PHPUnit\TextUI\Command will mean that it'll be
166
     *     // PHPUnit\TextUI\Command that gets instantiated,
167
     *     // not MyCommand
168
     *     public static function main($exit = true)
169
     *     {
170
     *         $command = new static;
171
     *
172
     *         return $command->run($_SERVER['argv'], $exit);
173
     *     }
174
     *
175
     * }
176
     * </code>
177
     *
178
     * @throws Exception
179
     */
180
    protected function handleArguments(array $argv): void
181
    {
182
        try {
183
            $arguments = (new ArgumentsBuilder)->fromParameters($argv, \array_keys($this->longOptions));
184
        } catch (ArgumentsException $e) {
185
            $this->exitWithErrorMessage($e->getMessage());
186
        }
187
188
        \assert(isset($arguments) && $arguments instanceof Arguments);
189
190
        if ($arguments->hasGenerateConfiguration() && $arguments->generateConfiguration()) {
191
            $this->printVersionString();
192
193
            print 'Generating phpunit.xml in ' . \getcwd() . \PHP_EOL . \PHP_EOL;
194
            print 'Bootstrap script (relative to path shown above; default: vendor/autoload.php): ';
195
196
            $bootstrapScript = \trim(\fgets(\STDIN));
197
198
            print 'Tests directory (relative to path shown above; default: tests): ';
199
200
            $testsDirectory = \trim(\fgets(\STDIN));
201
202
            print 'Source directory (relative to path shown above; default: src): ';
203
204
            $src = \trim(\fgets(\STDIN));
205
206
            if ($bootstrapScript === '') {
207
                $bootstrapScript = 'vendor/autoload.php';
208
            }
209
210
            if ($testsDirectory === '') {
211
                $testsDirectory = 'tests';
212
            }
213
214
            if ($src === '') {
215
                $src = 'src';
216
            }
217
218
            $generator = new Generator;
219
220
            \file_put_contents(
221
                'phpunit.xml',
222
                $generator->generateDefaultConfiguration(
223
                    Version::series(),
224
                    $bootstrapScript,
225
                    $testsDirectory,
226
                    $src
227
                )
228
            );
229
230
            print \PHP_EOL . 'Generated phpunit.xml in ' . \getcwd() . \PHP_EOL;
231
232
            exit(TestRunner::SUCCESS_EXIT);
233
        }
234
235
        if ($arguments->hasAtLeastVersion()) {
236
            if (\version_compare(Version::id(), $arguments->atLeastVersion(), '>=')) {
237
                exit(TestRunner::SUCCESS_EXIT);
238
            }
239
240
            exit(TestRunner::FAILURE_EXIT);
241
        }
242
243
        if ($arguments->hasVersion() && $arguments->version()) {
244
            $this->printVersionString();
245
246
            exit(TestRunner::SUCCESS_EXIT);
247
        }
248
249
        if ($arguments->hasCheckVersion() && $arguments->checkVersion()) {
250
            $this->handleVersionCheck();
251
        }
252
253
        if ($arguments->hasHelp()) {
254
            $this->showHelp();
255
256
            exit(TestRunner::SUCCESS_EXIT);
257
        }
258
259
        if ($arguments->hasUnrecognizedOrderBy()) {
260
            $this->exitWithErrorMessage(
261
                \sprintf(
262
                    'unrecognized --order-by option: %s',
263
                    $arguments->unrecognizedOrderBy()
264
                )
265
            );
266
        }
267
268
        if ($arguments->hasIniSettings()) {
269
            foreach ($arguments->iniSettings() as $name => $value) {
270
                \ini_set($name, $value);
271
            }
272
        }
273
274
        if ($arguments->hasIncludePath()) {
275
            \ini_set(
276
                'include_path',
277
                $arguments->includePath() . \PATH_SEPARATOR . \ini_get('include_path')
278
            );
279
        }
280
281
        $this->arguments = (new ArgumentsMapper)->mapToLegacyArray($arguments);
282
283
        if ($arguments->hasUnrecognizedOptions()) {
284
            foreach ($arguments->unrecognizedOptions() as $name => $value) {
285
                if (isset($this->longOptions[$name])) {
286
                    $handler = $this->longOptions[$name];
287
                } elseif (isset($this->longOptions[$name . '='])) {
288
                    $handler = $this->longOptions[$name . '='];
289
                }
290
291
                if (isset($handler) && \is_callable([$this, $handler])) {
292
                    $this->{$handler}($value);
293
294
                    unset($handler);
295
                }
296
            }
297
        }
298
299
        $this->handleCustomTestSuite();
300
301
        if (!isset($this->arguments['testSuffixes'])) {
302
            $this->arguments['testSuffixes'] = ['Test.php', '.phpt'];
303
        }
304
305
        if (!isset($this->arguments['test']) && $arguments->hasArgument()) {
306
            $this->arguments['test'] = \realpath($arguments->argument());
307
308
            if ($this->arguments['test'] === false) {
309
                $this->exitWithErrorMessage(
310
                    \sprintf(
311
                        'Cannot open file "%s".',
312
                        $arguments->argument()
313
                    )
314
                );
315
            }
316
        }
317
318
        if ($this->arguments['loader'] !== null) {
319
            $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']);
320
        }
321
322
        if (isset($this->arguments['configuration']) && \is_dir($this->arguments['configuration'])) {
323
            $configurationFile = $this->arguments['configuration'] . '/phpunit.xml';
324
325
            if (\file_exists($configurationFile)) {
326
                $this->arguments['configuration'] = \realpath(
327
                    $configurationFile
328
                );
329
            } elseif (\file_exists($configurationFile . '.dist')) {
330
                $this->arguments['configuration'] = \realpath(
331
                    $configurationFile . '.dist'
332
                );
333
            }
334
        } elseif (!isset($this->arguments['configuration']) && $this->arguments['useDefaultConfiguration']) {
335
            if (\file_exists('phpunit.xml')) {
336
                $this->arguments['configuration'] = \realpath('phpunit.xml');
337
            } elseif (\file_exists('phpunit.xml.dist')) {
338
                $this->arguments['configuration'] = \realpath(
339
                    'phpunit.xml.dist'
340
                );
341
            }
342
        }
343
344
        if (isset($this->arguments['configuration'])) {
345
            try {
346
                $configuration = Registry::getInstance()->get($this->arguments['configuration']);
347
            } catch (\Throwable $e) {
348
                print $e->getMessage() . \PHP_EOL;
349
350
                exit(TestRunner::FAILURE_EXIT);
351
            }
352
353
            $phpunitConfiguration = $configuration->phpunit();
354
355
            (new PhpHandler)->handle($configuration->php());
356
357
            if (isset($this->arguments['bootstrap'])) {
358
                $this->handleBootstrap($this->arguments['bootstrap']);
359
            } elseif ($phpunitConfiguration->hasBootstrap()) {
360
                $this->handleBootstrap($phpunitConfiguration->bootstrap());
361
            }
362
363
            if (!isset($this->arguments['stderr'])) {
364
                $this->arguments['stderr'] = $phpunitConfiguration->stderr();
365
            }
366
367
            if (!isset($this->arguments['noExtensions']) && $phpunitConfiguration->hasExtensionsDirectory() && \extension_loaded('phar')) {
368
                $this->handleExtensions($phpunitConfiguration->extensionsDirectory());
369
            }
370
371
            if (!isset($this->arguments['columns'])) {
372
                $this->arguments['columns'] = $phpunitConfiguration->columns();
373
            }
374
375
            if (!isset($this->arguments['printer']) && $phpunitConfiguration->hasPrinterClass()) {
376
                $file = $phpunitConfiguration->hasPrinterFile() ? $phpunitConfiguration->printerFile() : '';
377
378
                $this->arguments['printer'] = $this->handlePrinter(
379
                    $phpunitConfiguration->printerClass(),
380
                    $file
381
                );
382
            }
383
384
            if ($phpunitConfiguration->hasTestSuiteLoaderClass()) {
385
                $file = $phpunitConfiguration->hasTestSuiteLoaderFile() ? $phpunitConfiguration->testSuiteLoaderFile() : '';
386
387
                $this->arguments['loader'] = $this->handleLoader(
388
                    $phpunitConfiguration->testSuiteLoaderClass(),
389
                    $file
390
                );
391
            }
392
393
            if (!isset($this->arguments['testsuite']) && $phpunitConfiguration->hasDefaultTestSuite()) {
394
                $this->arguments['testsuite'] = $phpunitConfiguration->defaultTestSuite();
395
            }
396
397
            if (!isset($this->arguments['test'])) {
398
                $this->arguments['test'] = (new TestSuiteMapper)->map(
399
                    $configuration->testSuite(),
400
                    $this->arguments['testsuite'] ?? ''
401
                );
402
            }
403
        } elseif (isset($this->arguments['bootstrap'])) {
404
            $this->handleBootstrap($this->arguments['bootstrap']);
405
        }
406
407
        if (isset($this->arguments['printer']) && \is_string($this->arguments['printer'])) {
408
            $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']);
409
        }
410
411
        if (!isset($this->arguments['test'])) {
412
            $this->showHelp();
413
414
            exit(TestRunner::EXCEPTION_EXIT);
415
        }
416
    }
417
418
    /**
419
     * Handles the loading of the PHPUnit\Runner\TestSuiteLoader implementation.
420
     *
421
     * @deprecated see https://github.com/sebastianbergmann/phpunit/issues/4039
422
     */
423
    protected function handleLoader(string $loaderClass, string $loaderFile = ''): ?TestSuiteLoader
424
    {
425
        $this->warnings[] = 'Using a custom test suite loader is deprecated';
426
427
        if (!\class_exists($loaderClass, false)) {
428
            if ($loaderFile == '') {
429
                $loaderFile = Filesystem::classNameToFilename(
430
                    $loaderClass
431
                );
432
            }
433
434
            $loaderFile = \stream_resolve_include_path($loaderFile);
435
436
            if ($loaderFile) {
437
                require $loaderFile;
438
            }
439
        }
440
441
        if (\class_exists($loaderClass, false)) {
442
            try {
443
                $class = new \ReflectionClass($loaderClass);
444
                // @codeCoverageIgnoreStart
445
            } catch (\ReflectionException $e) {
446
                throw new Exception(
447
                    $e->getMessage(),
448
                    (int) $e->getCode(),
449
                    $e
450
                );
451
            }
452
            // @codeCoverageIgnoreEnd
453
454
            if ($class->implementsInterface(TestSuiteLoader::class) && $class->isInstantiable()) {
455
                $object = $class->newInstance();
456
457
                \assert($object instanceof TestSuiteLoader);
458
459
                return $object;
460
            }
461
        }
462
463
        if ($loaderClass == StandardTestSuiteLoader::class) {
464
            return null;
465
        }
466
467
        $this->exitWithErrorMessage(
468
            \sprintf(
469
                'Could not use "%s" as loader.',
470
                $loaderClass
471
            )
472
        );
473
474
        return null;
475
    }
476
477
    /**
478
     * Handles the loading of the PHPUnit\Util\Printer implementation.
479
     *
480
     * @return null|Printer|string
481
     */
482
    protected function handlePrinter(string $printerClass, string $printerFile = '')
483
    {
484
        if (!\class_exists($printerClass, false)) {
485
            if ($printerFile === '') {
486
                $printerFile = Filesystem::classNameToFilename(
487
                    $printerClass
488
                );
489
            }
490
491
            $printerFile = \stream_resolve_include_path($printerFile);
492
493
            if ($printerFile) {
494
                require $printerFile;
495
            }
496
        }
497
498
        if (!\class_exists($printerClass)) {
499
            $this->exitWithErrorMessage(
500
                \sprintf(
501
                    'Could not use "%s" as printer: class does not exist',
502
                    $printerClass
503
                )
504
            );
505
        }
506
507
        try {
508
            $class = new \ReflectionClass($printerClass);
509
            // @codeCoverageIgnoreStart
510
        } catch (\ReflectionException $e) {
511
            throw new Exception(
512
                $e->getMessage(),
513
                (int) $e->getCode(),
514
                $e
515
            );
516
            // @codeCoverageIgnoreEnd
517
        }
518
519
        if (!$class->implementsInterface(ResultPrinter::class)) {
520
            $this->exitWithErrorMessage(
521
                \sprintf(
522
                    'Could not use "%s" as printer: class does not implement %s',
523
                    $printerClass,
524
                    ResultPrinter::class
525
                )
526
            );
527
        }
528
529
        if (!$class->isInstantiable()) {
530
            $this->exitWithErrorMessage(
531
                \sprintf(
532
                    'Could not use "%s" as printer: class cannot be instantiated',
533
                    $printerClass
534
                )
535
            );
536
        }
537
538
        if ($class->isSubclassOf(ResultPrinter::class)) {
539
            return $printerClass;
540
        }
541
542
        $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null;
543
544
        return $class->newInstance($outputStream);
545
    }
546
547
    /**
548
     * Loads a bootstrap file.
549
     */
550
    protected function handleBootstrap(string $filename): void
551
    {
552
        try {
553
            FileLoader::checkAndLoad($filename);
554
        } catch (Exception $e) {
555
            $this->exitWithErrorMessage($e->getMessage());
556
        }
557
    }
558
559
    protected function handleVersionCheck(): void
560
    {
561
        $this->printVersionString();
562
563
        $latestVersion = \file_get_contents('https://phar.phpunit.de/latest-version-of/phpunit');
564
        $isOutdated    = \version_compare($latestVersion, Version::id(), '>');
565
566
        if ($isOutdated) {
567
            \printf(
568
                'You are not using the latest version of PHPUnit.' . \PHP_EOL .
569
                'The latest version is PHPUnit %s.' . \PHP_EOL,
570
                $latestVersion
571
            );
572
        } else {
573
            print 'You are using the latest version of PHPUnit.' . \PHP_EOL;
574
        }
575
576
        exit(TestRunner::SUCCESS_EXIT);
577
    }
578
579
    /**
580
     * Show the help message.
581
     */
582
    protected function showHelp(): void
583
    {
584
        $this->printVersionString();
585
        (new Help)->writeToConsole();
586
    }
587
588
    /**
589
     * Custom callback for test suite discovery.
590
     */
591
    protected function handleCustomTestSuite(): void
592
    {
593
    }
594
595
    private function printVersionString(): void
596
    {
597
        if ($this->versionStringPrinted) {
598
            return;
599
        }
600
601
        print Version::getVersionString() . \PHP_EOL . \PHP_EOL;
602
603
        $this->versionStringPrinted = true;
604
    }
605
606
    private function exitWithErrorMessage(string $message): void
607
    {
608
        $this->printVersionString();
609
610
        print $message . \PHP_EOL;
611
612
        exit(TestRunner::FAILURE_EXIT);
613
    }
614
615
    private function handleExtensions(string $directory): void
616
    {
617
        foreach ((new FileIteratorFacade)->getFilesAsArray($directory, '.phar') as $file) {
618
            if (!\file_exists('phar://' . $file . '/manifest.xml')) {
619
                $this->arguments['notLoadedExtensions'][] = $file . ' is not an extension for PHPUnit';
620
621
                continue;
622
            }
623
624
            try {
625
                $applicationName = new ApplicationName('phpunit/phpunit');
626
                $version         = new PharIoVersion(Version::series());
627
                $manifest        = ManifestLoader::fromFile('phar://' . $file . '/manifest.xml');
628
629
                if (!$manifest->isExtensionFor($applicationName)) {
630
                    $this->arguments['notLoadedExtensions'][] = $file . ' is not an extension for PHPUnit';
631
632
                    continue;
633
                }
634
635
                if (!$manifest->isExtensionFor($applicationName, $version)) {
636
                    $this->arguments['notLoadedExtensions'][] = $file . ' is not compatible with this version of PHPUnit';
637
638
                    continue;
639
                }
640
            } catch (ManifestException $e) {
641
                $this->arguments['notLoadedExtensions'][] = $file . ': ' . $e->getMessage();
642
643
                continue;
644
            }
645
646
            require $file;
647
648
            $this->arguments['loadedExtensions'][] = $manifest->getName() . ' ' . $manifest->getVersion()->getVersionString();
649
        }
650
    }
651
652
    private function handleListGroups(TestSuite $suite, bool $exit): int
653
    {
654
        $this->printVersionString();
655
656
        print 'Available test group(s):' . \PHP_EOL;
657
658
        $groups = $suite->getGroups();
659
        \sort($groups);
660
661
        foreach ($groups as $group) {
662
            \printf(
663
                ' - %s' . \PHP_EOL,
664
                $group
665
            );
666
        }
667
668
        if ($exit) {
669
            exit(TestRunner::SUCCESS_EXIT);
670
        }
671
672
        return TestRunner::SUCCESS_EXIT;
673
    }
674
675
    /**
676
     * @throws \PHPUnit\Framework\Exception
677
     */
678
    private function handleListSuites(bool $exit): int
679
    {
680
        $this->printVersionString();
681
682
        print 'Available test suite(s):' . \PHP_EOL;
683
684
        $configuration = Registry::getInstance()->get($this->arguments['configuration']);
685
686
        foreach ($configuration->testSuite() as $testSuite) {
687
            \printf(
688
                ' - %s' . \PHP_EOL,
689
                $testSuite->name()
690
            );
691
        }
692
693
        if ($exit) {
694
            exit(TestRunner::SUCCESS_EXIT);
695
        }
696
697
        return TestRunner::SUCCESS_EXIT;
698
    }
699
700
    /**
701
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
702
     */
703
    private function handleListTests(TestSuite $suite, bool $exit): int
704
    {
705
        $this->printVersionString();
706
707
        $renderer = new TextTestListRenderer;
708
709
        print $renderer->render($suite);
710
711
        if ($exit) {
712
            exit(TestRunner::SUCCESS_EXIT);
713
        }
714
715
        return TestRunner::SUCCESS_EXIT;
716
    }
717
718
    /**
719
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
720
     */
721
    private function handleListTestsXml(TestSuite $suite, string $target, bool $exit): int
722
    {
723
        $this->printVersionString();
724
725
        $renderer = new XmlTestListRenderer;
726
727
        \file_put_contents($target, $renderer->render($suite));
728
729
        \printf(
730
            'Wrote list of tests that would have been run to %s' . \PHP_EOL,
731
            $target
732
        );
733
734
        if ($exit) {
735
            exit(TestRunner::SUCCESS_EXIT);
736
        }
737
738
        return TestRunner::SUCCESS_EXIT;
739
    }
740
}
741