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 ( 523c4a...acaf0b )
by Anton
06:50
created

Deployer::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

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