CLI::run()   F
last analyzed

Complexity

Conditions 23
Paths 4123

Size

Total Lines 131
Code Lines 84

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 552

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 84
c 7
b 0
f 0
dl 0
loc 131
ccs 0
cts 99
cp 0
rs 0
cc 23
nc 4123
nop 1
crap 552

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
namespace TheSeer\phpDox;
3
4
use TheSeer\fDOM\fDOMException;
5
6
class CLI {
7
    public const ExitOK = 0;
8
9
    public const ExitExecError = 1;
10
11
    public const ExitEnvError = 2;
12
13
    public const ExitParamError = 3;
14
15
    public const ExitConfigError = 4;
16
17
    public const ExitException = 5;
18
19
    /**
20
     * @var Environment
21
     */
22
    private $environment;
23
24
    /**
25
     * @var Version
26
     */
27
    private $version;
28
29
    /**
30
     * Factory instance
31
     *
32
     * @var Factory
33
     */
34
    private $factory;
35
36
    public function __construct(Environment $env, Version $version, Factory $factory) {
37
        $this->environment = $env;
38
        $this->version     = $version;
39
        $this->factory     = $factory;
40
    }
41
42
    /**
43
     * Main executor for CLI process.
44
     */
45
    public function run(CLIOptions $options) {
46
        $errorHandler = $this->factory->getErrorHandler();
47
        $errorHandler->register();
48
49
        try {
50
            $this->environment->ensureFitness();
51
52
            if ($options->showHelp() === true) {
53
                $this->showVersion();
54
                print $options->getHelpScreen();
55
56
                return self::ExitOK;
57
            }
58
59
            if ($options->showVersion() === true) {
60
                $this->showVersion();
61
62
                return self::ExitOK;
63
            }
64
65
            if ($options->generateSkel() === true) {
66
                $this->showSkeletonConfig($options->generateStrippedSkel());
67
68
                return self::ExitOK;
69
            }
70
71
            $config = $this->loadConfig($options);
72
73
            if ($config->isSilentMode()) {
74
                $this->factory->activateSilentMode();
75
            } else {
76
                $this->showVersion();
77
            }
78
79
            $logger = $this->factory->getLogger();
80
            $logger->log("Using config file '" . $config->getConfigFile()->getPathname() . "'");
81
82
            $app = $this->factory->getApplication();
83
84
            $defBootstrapFiles = new FileInfoCollection();
85
            $defBootstrapFiles->add(new FileInfo(__DIR__ . '/../bootstrap/backends.php'));
86
            $defBootstrapFiles->add(new FileInfo(__DIR__ . '/../bootstrap/enrichers.php'));
87
            $defBootstrapFiles->add(new FileInfo(__DIR__ . '/../bootstrap/engines.php'));
88
89
            $bootstrap = $app->runBootstrap($defBootstrapFiles);
90
            $bootstrap->load($config->getCustomBootstrapFiles(), false);
91
92
            if ($options->listEngines()) {
93
                $this->showVersion();
94
                $this->showList('engines', $bootstrap->getEngines());
95
            }
96
97
            if ($options->listEnrichers()) {
98
                $this->showVersion();
99
                $this->showList('enrichers', $bootstrap->getEnrichers());
100
            }
101
102
            if ($options->listBackends()) {
103
                $this->showVersion();
104
                $this->showList('backends', $bootstrap->getBackends());
105
            }
106
107
            if ($options->listBackends() || $options->listEngines() || $options->listEnrichers()) {
108
                return self::ExitOK;
109
            }
110
111
            foreach ($config->getProjects() as $projectName => $projectConfig) {
112
                $logger->log("Starting to process project '$projectName'");
113
114
                $app->runConfigChangeDetection(
115
                    $projectConfig->getWorkDirectory(),
116
                    $config->getConfigFile()
117
                );
118
119
                if (!$options->generatorOnly()) {
120
                    $app->runCollector($projectConfig->getCollectorConfig());
121
                }
122
123
                if (!$options->collectorOnly()) {
124
                    $app->runGenerator($projectConfig->getGeneratorConfig());
125
                }
126
127
                $logger->log("Processing project '$projectName' completed.");
128
            }
129
130
            $logger->buildSummary();
131
132
            return self::ExitOK;
133
        } catch (EnvironmentException $e) {
134
            $this->showVersion();
135
            \fwrite(\STDERR, 'Sorry, but your PHP environment is currently not able to run phpDox due to');
136
            \fwrite(\STDERR, "\nthe following issue(s):\n\n" . $e->getMessage() . "\n\n");
137
            \fwrite(\STDERR, "Please adjust your PHP configuration and try again.\n\n");
138
139
            return self::ExitEnvError;
140
        } catch (CLIOptionsException $e) {
141
            $this->showVersion();
142
            \fwrite(\STDERR, $e->getMessage() . "\n\n");
143
            \fwrite(\STDERR, $options->getHelpScreen());
144
145
            return self::ExitParamError;
146
        } catch (ConfigLoaderException $e) {
147
            $this->showVersion();
148
            \fwrite(\STDERR, "\nAn error occured while trying to load the configuration file:\n\n" . $e->getMessage() . "\n\n");
149
150
            if ($e->getCode() == ConfigLoaderException::NeitherCandidateExists) {
151
                \fwrite(\STDERR, "Using --skel might get you started.\n\n");
152
            }
153
154
            return self::ExitConfigError;
155
        } catch (ConfigException $e) {
156
            \fwrite(\STDERR, "\nYour configuration seems to be corrupted:\n\n\t" . $e->getMessage() . "\n\nPlease verify your configuration xml file.\n\n");
157
158
            return self::ExitConfigError;
159
        } catch (ApplicationException $e) {
160
            \fwrite(\STDERR, "\nAn application error occured while processing:\n\n\t" . $e->getMessage() . "\n\nPlease verify your configuration.\n\n");
161
162
            return self::ExitExecError;
163
        } catch (\Exception $e) {
164
            if ($e instanceof fDOMException) {
165
                $e->toggleFullMessage(true);
166
            }
167
            $this->showVersion();
168
            $errorHandler->handleException($e);
169
170
            return self::ExitException;
171
        } catch (\Throwable $e) {
172
            $this->showVersion();
173
            $errorHandler->handleException($e);
174
175
            return self::ExitException;
176
        }
177
    }
178
179
    /**
180
     * Helper to output version information.
181
     */
182
    private function showVersion(): void {
183
        static $shown = false;
184
185
        if ($shown) {
186
            return;
187
        }
188
        $shown = true;
189
        print $this->version->getInfoString() . "\n\n";
190
    }
191
192
    private function showSkeletonConfig($strip): void {
193
        $skel = $this->factory->getConfigSkeleton();
194
        print $strip ? $skel->renderStripped() : $skel->render();
195
    }
196
197
    private function showList($title, array $list): void {
198
        print "\nThe following $title are registered:\n\n";
199
200
        foreach ($list as $name => $desc) {
201
            \printf("   %s \t %s\n", $name, $desc);
202
        }
203
        print "\n\n";
204
    }
205
206
    /**
207
     * @throws ConfigLoaderException
208
     */
209
    private function loadConfig(CLIOptions $options): GlobalConfig {
210
        $cfgLoader = $this->factory->getConfigLoader();
211
        $cfgFile   = $options->configFile();
212
213
        if ($cfgFile != '') {
214
            return $cfgLoader->load($cfgFile);
215
        }
216
217
        return $cfgLoader->autodetect();
218
    }
219
}
220