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 ( 971843...0fc630 )
by Anton
05:02
created

Deployer::__construct()   B

Complexity

Conditions 4
Paths 1

Size

Total Lines 95
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 43
CRAP Score 4.0293

Importance

Changes 0
Metric Value
cc 4
eloc 48
nc 1
nop 1
dl 0
loc 95
ccs 43
cts 49
cp 0.8776
crap 4.0293
rs 8.2763
c 0
b 0
f 0

How to fix   Long Method   

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