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 ( d5146c...657698 )
by Anton
02:34
created

Deployer::getHelper()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
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 23
    public function __construct(Application $console)
67
    {
68 23
        parent::__construct();
69
70
        /******************************
71
         *           Console          *
72
         ******************************/
73
74
        $this['console'] = function () use ($console) {
75
            $console->catchIO(function ($input, $output) {
76 8
                $this['input'] = $input;
77 8
                $this['output'] =  new OutputWatcher($output);
78 8
                return [$this['input'], $this['output']];
79 8
            });
80 8
            return $console;
81
        };
82
83
        /******************************
84
         *           Config           *
85
         ******************************/
86
87
        $this['config'] = function () {
88 23
            return new Collection();
89
        };
90 23
        $this->config['ssh_multiplexing'] = true;
91 23
        $this->config['default_stage'] = null;
92
93
        /******************************
94
         *            Core            *
95
         ******************************/
96
97
        $this['pop'] = function ($c) {
98 7
            return new ProcessOutputPrinter($c['output'], $c['logger']);
99
        };
100
        $this['sshClient'] = function ($c) {
101 6
            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
        $this['processRunner'] = function ($c) {
107 7
            return new ProcessRunner($c['pop']);
108
        };
109
        $this['tasks'] = function () {
110 12
            return new Task\TaskCollection();
111
        };
112
        $this['hosts'] = function () {
113 12
            return new Host\HostCollection();
114
        };
115
        $this['scriptManager'] = function ($c) {
116 10
            return new Task\ScriptManager($c['tasks']);
117
        };
118
        $this['hostSelector'] = function ($c) {
119 8
            $defaultStage = $c['config']['default_stage'];
120 8
            if (is_object($defaultStage) && ($defaultStage instanceof \Closure)) {
121
                $defaultStage = call_user_func($defaultStage);
122
            }
123 8
            return new Host\HostSelector($c['hosts'], $defaultStage);
124
        };
125
        $this['fail'] = function () {
126 7
            return new Collection();
127
        };
128
        $this['informer'] = function ($c) {
129 8
            return new Informer($c['output']);
130
        };
131
        $this['seriesExecutor'] = function ($c) {
132 5
            return new SeriesExecutor($c['input'], $c['output'], $c['informer']);
133
        };
134
        $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
        $this['log_handler'] = function () {
143 7
            return !empty($this->config['log_file'])
144
                ? new FileHandler($this->config['log_file'])
145 7
                : new NullHandler();
146
        };
147
        $this['logger'] = function () {
148 7
            return new Logger($this['log_handler']);
149
        };
150
151
        /******************************
152
         *        Init command        *
153
         ******************************/
154
155
        $this['init_command'] = function () {
156 8
            return new InitCommand();
157
        };
158
159 23
        self::$instance = $this;
160 23
    }
161
162
    /**
163
     * @return Deployer
164
     */
165 24
    public static function get()
166
    {
167 24
        return self::$instance;
168
    }
169
170
    /**
171
     * @param string $name
172
     * @param mixed $value
173
     */
174 11
    public static function setDefault($name, $value)
175
    {
176 11
        Deployer::get()->config[$name] = $value;
177 11
    }
178
179
    /**
180
     * @param string $name
181
     * @param mixed $default
182
     * @return mixed
183
     */
184 7
    public static function getDefault($name, $default = null)
185
    {
186 7
        return self::hasDefault($name) ? Deployer::get()->config[$name] : $default;
187
    }
188
189
    /**
190
     * @param string $name
191
     * @return boolean
192
     */
193 10
    public static function hasDefault($name)
194
    {
195 10
        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 8
    public function init()
219
    {
220 8
        $this->addConsoleCommands();
221 8
        $this->getConsole()->add(new WorkerCommand($this));
222 8
        $this->getConsole()->add($this['init_command']);
223 8
        $this->getConsole()->add(new SshCommand($this));
224 8
        $this->getConsole()->add(new RunCommand($this));
225 8
        $this->getConsole()->add(new AutocompleteCommand());
226 8
        $this->getConsole()->afterRun([$this, 'collectAnonymousStats']);
227 8
    }
228
229
    /**
230
     * Transform tasks to console commands.
231
     */
232 8
    public function addConsoleCommands()
233
    {
234 8
        $this->getConsole()->addUserArgumentsAndOptions();
235
236 8
        foreach ($this->tasks as $name => $task) {
237 8
            if ($task->isPrivate()) {
238 7
                continue;
239
            }
240
241 8
            $this->getConsole()->add(new TaskCommand($name, $task->getDescription(), $this));
242
        }
243 8
    }
244
245
    /**
246
     * @param string $name
247
     * @return mixed
248
     * @throws \InvalidArgumentException
249
     */
250 27
    public function __get($name)
251
    {
252 27
        if (isset($this[$name])) {
253 27
            return $this[$name];
254
        } else {
255 1
            throw new \InvalidArgumentException("Property \"$name\" does not exist.");
256
        }
257
    }
258
259
    /**
260
     * @return Application
261
     */
262 8
    public function getConsole()
263
    {
264 8
        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