GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 64f5bb...5f2d07 )
by Anton
02:44
created

Deployer::collectAnonymousStats()   F

Complexity

Conditions 11
Paths 257

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
cc 11
eloc 23
nc 257
nop 1
dl 0
loc 35
ccs 0
cts 0
cp 0
crap 132
rs 3.8181
c 0
b 0
f 0

How to fix   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
/* (c) Anton Medvedev <[email protected]>
3
 *
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
8
namespace Deployer;
9
10
use Deployer\Collection\Collection;
11
use Deployer\Console\Application;
12
use Deployer\Console\CommandEvent;
13
use Deployer\Console\InitCommand;
14
use Deployer\Console\Output\Informer;
15
use Deployer\Console\Output\OutputWatcher;
16
use Deployer\Console\SshCommand;
17
use Deployer\Console\TaskCommand;
18
use Deployer\Console\WorkerCommand;
19
use Deployer\Executor\ParallelExecutor;
20
use Deployer\Executor\SeriesExecutor;
21
use Deployer\Logger\Handler\FileHandler;
22
use Deployer\Logger\Handler\NullHandler;
23
use Deployer\Logger\Logger;
24
use Deployer\Task;
25
use Deployer\Utility\ProcessOutputPrinter;
26
use Deployer\Utility\ProcessRunner;
27
use Deployer\Utility\Reporter;
28
use Deployer\Utility\Rsync;
29
use Pimple\Container;
30
use Symfony\Component\Console;
31
use Symfony\Component\Console\Input\ArgvInput;
32
use Symfony\Component\Console\Output\ConsoleOutput;
33
use Symfony\Component\Console\Style\SymfonyStyle;
34
use function Deployer\Support\array_merge_alternate;
35
36
/**
37
 * Deployer class represents DI container for configuring
38
 *
39
 * @property Application console
40
 * @property Task\TaskCollection|Task\Task[] tasks
41
 * @property Host\HostCollection|Collection|Host\Host[] hosts
42
 * @property Collection config
43
 * @property Rsync rsync
44
 * @property Ssh\Client sshClient
45
 * @property ProcessRunner processRunner
46
 * @property Task\ScriptManager scriptManager
47
 * @property Host\HostSelector hostSelector
48
 * @property SeriesExecutor seriesExecutor
49
 * @property ParallelExecutor parallelExecutor
50
 * @property Informer informer
51
 * @property Logger logger
52
 */
53
class Deployer extends Container
54
{
55
    /**
56
     * Global instance of deployer. It's can be accessed only after constructor call.
57
     * @var Deployer
58
     */
59
    private static $instance;
60
61
    /**
62
     * @param Application $console
63
     */
64 23
    public function __construct(Application $console)
65
    {
66 23
        parent::__construct();
67
68
        /******************************
69
         *           Console          *
70
         ******************************/
71
72
        $this['console'] = function () use ($console) {
73
            $console->catchIO(function ($input, $output) {
74 8
                $this['input'] = $input;
75 8
                $this['output'] =  new OutputWatcher($output);
76 8
                return [$this['input'], $this['output']];
77 8
            });
78 8
            return $console;
79
        };
80
81
        /******************************
82
         *           Config           *
83
         ******************************/
84
85
        $this['config'] = function () {
86 23
            return new Collection();
87
        };
88 23
        $this->config['ssh_multiplexing'] = true;
89 23
        $this->config['default_stage'] = null;
90
91
        /******************************
92
         *            Core            *
93
         ******************************/
94
95
        $this['pop'] = function ($c) {
96 7
            return new ProcessOutputPrinter($c['output'], $c['logger']);
97
        };
98
        $this['sshClient'] = function ($c) {
99 6
            return new Ssh\Client($c['output'], $c['pop'], $c['config']['ssh_multiplexing']);
100
        };
101
        $this['rsync'] = function ($c) {
102
            return new Rsync($c['pop']);
103
        };
104
        $this['processRunner'] = function ($c) {
105 7
            return new ProcessRunner($c['pop']);
106
        };
107
        $this['tasks'] = function () {
108 12
            return new Task\TaskCollection();
109
        };
110
        $this['hosts'] = function () {
111 12
            return new Host\HostCollection();
112
        };
113
        $this['scriptManager'] = function ($c) {
114 10
            return new Task\ScriptManager($c['tasks']);
115
        };
116
        $this['hostSelector'] = function ($c) {
117 8
            return new Host\HostSelector($c['hosts'], $c['config']['default_stage']);
118
        };
119
        $this['fail'] = function () {
120 7
            return new Collection();
121
        };
122
        $this['informer'] = function ($c) {
123 8
            return new Informer($c['output']);
124
        };
125
        $this['seriesExecutor'] = function ($c) {
126 5
            return new SeriesExecutor($c['input'], $c['output'], $c['informer']);
127
        };
128
        $this['parallelExecutor'] = function ($c) {
129 3
            return new ParallelExecutor($c['input'], $c['output'], $c['informer'], $c['console']);
130
        };
131
132
        /******************************
133
         *           Logger           *
134
         ******************************/
135
136
        $this['log_handler'] = function () {
137 7
            return !empty($this->config['log_file'])
138
                ? new FileHandler($this->config['log_file'])
139 7
                : new NullHandler();
140
        };
141
        $this['logger'] = function () {
142 7
            return new Logger($this['log_handler']);
143
        };
144
145
        /******************************
146
         *        Init command        *
147
         ******************************/
148
149
        $this['init_command'] = function () {
150 8
            return new InitCommand();
151
        };
152
153 23
        self::$instance = $this;
154 23
    }
155
156
    /**
157
     * @return Deployer
158
     */
159 21
    public static function get()
160
    {
161 21
        return self::$instance;
162
    }
163
164
    /**
165
     * @param string $name
166
     * @param mixed $value
167
     */
168 11
    public static function setDefault($name, $value)
169
    {
170 11
        Deployer::get()->config[$name] = $value;
171 11
    }
172
173
    /**
174
     * @param string $name
175
     * @param mixed $default
176
     * @return mixed
177
     */
178 7
    public static function getDefault($name, $default = null)
179
    {
180 7
        return self::hasDefault($name) ? Deployer::get()->config[$name] : $default;
181
    }
182
183
    /**
184
     * @param string $name
185
     * @return boolean
186
     */
187 10
    public static function hasDefault($name)
188
    {
189 10
        return isset(Deployer::get()->config[$name]);
190
    }
191
192
    /**
193
     * @param string $name
194
     * @param array $array
195
     */
196 2
    public static function addDefault($name, $array)
197
    {
198 2
        if (self::hasDefault($name)) {
199 2
            $config = self::getDefault($name);
200 2
            if (!is_array($config)) {
201 1
                throw new \RuntimeException("Configuration parameter `$name` isn't array.");
202
            }
203 1
            self::setDefault($name, array_merge_alternate($config, $array));
204
        } else {
205
            self::setDefault($name, $array);
206
        }
207 1
    }
208
209
    /**
210
     * Init console application
211
     */
212 8
    public function init()
213
    {
214 8
        $this->addConsoleCommands();
215 8
        $this->getConsole()->add(new WorkerCommand($this));
216 8
        $this->getConsole()->add($this['init_command']);
217 8
        $this->getConsole()->add(new SshCommand($this));
218 8
        $this->getConsole()->afterRun([$this, 'collectAnonymousStats']);
219 8
    }
220
221
    /**
222
     * Transform tasks to console commands.
223
     */
224 8
    public function addConsoleCommands()
225
    {
226 8
        $this->getConsole()->addUserArgumentsAndOptions();
227
228 8
        foreach ($this->tasks as $name => $task) {
229 8
            if ($task->isPrivate()) {
230 7
                continue;
231
            }
232
233 8
            $this->getConsole()->add(new TaskCommand($name, $task->getDescription(), $this));
234
        }
235 8
    }
236
237
    /**
238
     * @param string $name
239
     * @return mixed
240
     * @throws \InvalidArgumentException
241
     */
242 24
    public function __get($name)
243
    {
244 24
        if (isset($this[$name])) {
245 24
            return $this[$name];
246
        } else {
247 1
            throw new \InvalidArgumentException("Property \"$name\" does not exist.");
248
        }
249
    }
250
251
    /**
252
     * @return Application
253
     */
254 8
    public function getConsole()
255
    {
256 8
        return $this['console'];
257
    }
258
259
    /**
260
     * @return Console\Input\InputInterface
261
     */
262
    public function getInput()
263
    {
264
        return $this['input'];
265
    }
266
267
    /**
268
     * @return Console\Output\OutputInterface
269
     */
270
    public function getOutput()
271
    {
272
        return $this['output'];
273
    }
274
275
    /**
276
     * @param string $name
277
     * @return Console\Helper\HelperInterface
278
     */
279
    public function getHelper($name)
280
    {
281
        return $this->getConsole()->getHelperSet()->get($name);
282
    }
283
284
    /**
285
     * Run Deployer
286
     *
287
     * @param string $version
288
     * @param string $deployFile
289
     */
290
    public static function run($version, $deployFile)
291
    {
292
        // Init Deployer
293
        $console = new Application('Deployer', $version);
294
        $input = new ArgvInput();
295
        $output = new ConsoleOutput();
296
        $deployer = new self($console);
297
298
        // Pretty-print uncaught exceptions in symfony-console
299
        set_exception_handler(function ($e) use ($input, $output) {
300
            $io = new SymfonyStyle($input, $output);
301
            $io->block($e->getMessage(), get_class($e), 'fg=white;bg=red', ' ', true);
302
            $io->block($e->getTraceAsString());
303
        });
304
305
        // Require deploy.php file
306
        if (is_readable($deployFile)) {
307
            // Prevent variable leak into deploy.php file
308
            call_user_func(function () use ($deployFile) {
309
                require $deployFile;
310
            });
311
        }
312
313
        // Run Deployer
314
        $deployer->init();
315
        $console->run($input, $output);
316
    }
317
318
    /**
319
     * Collect anonymous stats about Deployer usage for improving developer experience.
320
     * If you are not comfortable with this, you will always be able to disable this
321
     * by setting `allow_anonymous_stats` to false in your deploy.php file.
322
     *
323
     * @param CommandEvent $commandEvent
324
     */
325
    public function collectAnonymousStats(CommandEvent $commandEvent)
326
    {
327
        if ($this->config->has('allow_anonymous_stats') && $this->config['allow_anonymous_stats'] === false) {
328
            return;
329
        }
330
331
        $stats = [
332
            'status' => 'success',
333
            'command_name' => $commandEvent->getCommand()->getName(),
334
            'project_hash' => empty($this->config['repository']) ? null : sha1($this->config['repository']),
335
            'hosts_count' => $this->hosts->count(),
336
            'deployer_version' => $this->getConsole()->getVersion(),
337
            'deployer_phar' => $this->getConsole()->isPharArchive(),
338
            'php_version' => phpversion(),
339
            'extension_pcntl' => extension_loaded('pcntl'),
340
            'extension_curl' => extension_loaded('curl'),
341
            'os' => defined('PHP_OS_FAMILY') ? PHP_OS_FAMILY : (stristr(PHP_OS, 'DAR') ? 'OSX' : (stristr(PHP_OS, 'WIN') ? 'WIN' : (stristr(PHP_OS, 'LINUX') ? 'LINUX' : PHP_OS))),
342
            'exception' => null,
343
        ];
344
345
        if ($commandEvent->getException() !== null) {
346
            $stats['status'] = 'error';
347
            $stats['exception'] = get_class($commandEvent->getException());
348
        }
349
350
        if ($stats['command_name'] === 'init') {
351
            $stats['allow_anonymous_stats'] = $GLOBALS['allow_anonymous_stats'] ?? false;
352
        }
353
354
        if ($stats['command_name'] === 'worker') {
355
            return;
356
        }
357
358
        Reporter::report($stats);
359
    }
360
}
361