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.
Completed
Push — master ( c08840...bd0247 )
by Anton
02:55
created

Deployer   C

Complexity

Total Complexity 35

Size/Duplication

Total Lines 312
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 18

Test Coverage

Coverage 72.09%

Importance

Changes 0
Metric Value
dl 0
loc 312
ccs 31
cts 43
cp 0.7209
rs 6.6
c 0
b 0
f 0
wmc 35
lcom 1
cbo 18

17 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 4 1
A setDefault() 0 4 1
A getDefault() 0 4 2
A hasDefault() 0 4 1
A addDefault() 0 12 3
A run() 0 10 1
A addConsoleCommands() 0 12 3
A __get() 0 8 2
A getConsole() 0 4 1
A getInput() 0 4 1
A getOutput() 0 4 1
A getHelper() 0 4 1
A getStageStrategy() 0 4 1
A getScriptManager() 0 4 1
A getLogger() 0 4 1
B __construct() 0 78 3
C collectAnonymousStats() 0 58 11
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\TaskCommand;
15
use Deployer\Console\WorkerCommand;
16
use Deployer\Server;
17
use Deployer\Stage\StageStrategy;
18
use Deployer\Task;
19
use Deployer\Type\Config;
20
use Monolog\Handler\NullHandler;
21
use Monolog\Handler\StreamHandler;
22
use Monolog\Logger;
23
use Pimple\Container;
24
use Psr\Log\LoggerInterface;
25
use Symfony\Component\Console;
26
27
/**
28
 * @property Task\TaskCollection|Task\Task[] tasks
29
 * @property Server\ServerCollection|Server\ServerInterface[] servers
30
 * @property Server\EnvironmentCollection|Server\Environment[] environments
31
 * @property Collection config
32
 */
33
class Deployer extends Container
34
{
35
    /**
36
     * Global instance of deployer. It's can be accessed only after constructor call.
37
     * @var Deployer
38
     */
39
    private static $instance;
40
41
    /**
42
     * @param Application $console
43
     * @param Console\Input\InputInterface $input
44
     * @param Console\Output\OutputInterface $output
45
     */
46
    public function __construct(Application $console, Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
47
    {
48
        parent::__construct();
49
50
        /******************************
51
         *           Console          *
52
         ******************************/
53
54
        $this['console'] = function () use ($console) {
55
            return $console;
56
        };
57
        $this['input'] = function () use ($input) {
58
            return $input;
59
        };
60
        $this['output'] = function () use ($output) {
61
            return $output;
62
        };
63
64
        /******************************
65 35
         *           Config           *
66
         ******************************/
67 35
68 35
        $this['config'] = function () {
69 35
            return new Collection();
70
        };
71 35
        $this->config['ssh_type'] = 'phpseclib';
72 35
        $this->config['default_stage'] = null;
73 35
74 35
        /******************************
75 35
         *            Core            *
76 35
         ******************************/
77
78 35
        $this['tasks'] = function () {
79
            return new Task\TaskCollection();
80 35
        };
81 35
        $this['servers'] = function () {
82
            return new Server\ServerCollection();
83
        };
84
        $this['environments'] = function () {
85
            return new Server\EnvironmentCollection();
86 22
        };
87
        $this['scriptManager'] = function ($c) {
88 22
            return new Task\ScriptManager($c['tasks']);
89
        };
90
        $this['stageStrategy'] = function ($c) {
91
            return new StageStrategy($c['servers'], $c['environments'], $c['config']['default_stage']);
92
        };
93
        $this['onFailure'] = function () {
94
            return new Collection();
95
        };
96
97
        /******************************
98
         *           Logger           *
99
         ******************************/
100
101
        $this['log_level'] = Logger::DEBUG;
102
        $this['log_handler'] = function () {
103
            return isset($this->config['log_file'])
104
                ? new StreamHandler($this->config['log_file'], $this['log_level'])
105
                : new NullHandler($this['log_level']);
106
        };
107 14
        $this['log'] = function () {
108
            $name = isset($this->config['log_name']) ? $this->config['log_name'] : 'Deployer';
109 14
            return new Logger($name, [
110
                $this['log_handler']
111 14
            ]);
112 14
        };
113 14
114
        /******************************
115
         *        Init command        *
116 14
         ******************************/
117 14
118 14
        $this['init_command'] = function () {
119
            return new InitCommand();
120
        };
121
122
        self::$instance = $this;
123
    }
124
125
    /**
126
     * @return Deployer
127
     */
128
    public static function get()
129
    {
130
        return self::$instance;
131
    }
132
133
    /**
134
     * @param string $name
135
     * @param mixed $value
136
     */
137
    public static function setDefault($name, $value)
138
    {
139
        Deployer::get()->config[$name] = $value;
140
    }
141 35
142
    /**
143 35
     * @param string $name
144 35
     * @param mixed $default
145
     * @return mixed
146 1
     */
147
    public static function getDefault($name, $default = null)
148
    {
149
        return self::hasDefault($name) ? Deployer::get()->config[$name] : $default;
150
    }
151
152
    /**
153
     * @param string $name
154
     * @return boolean
155
     */
156
    public static function hasDefault($name)
157
    {
158
        return isset(Deployer::get()->config[$name]);
159
    }
160
161
    /**
162 14
     * @param string $name
163
     * @param array $array
164 14
     */
165
    public static function addDefault($name, $array)
166
    {
167
        if (self::hasDefault($name)) {
168
            $config = self::getDefault($name);
169
            if (!is_array($config)) {
170 15
                throw new \RuntimeException("Configuration parameter `$name` isn't array.");
171
            }
172 15
            self::setDefault($name, Config::merge($config, $array));
173
        } else {
174
            self::setDefault($name, $array);
175
        }
176
    }
177
178
    /**
179
     * Run console application.
180
     */
181
    public function run()
182
    {
183
        $this->addConsoleCommands();
184
185
        $this->getConsole()->add(new WorkerCommand($this));
186
        $this->getConsole()->add($this['init_command']);
187
        $this->getConsole()->addCallback([$this, 'collectAnonymousStats']);
188
189
        $this->getConsole()->run($this->input, $this->output);
0 ignored issues
show
Documentation introduced by
The property input does not exist on object<Deployer\Deployer>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property output does not exist on object<Deployer\Deployer>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
190
    }
191
192
    /**
193
     * Transform tasks to console commands.
194
     */
195
    public function addConsoleCommands()
196
    {
197
        $this->getConsole()->addUserArgumentsAndOptions();
198
199
        foreach ($this->tasks as $name => $task) {
200
            if ($task->isPrivate()) {
201
                continue;
202
            }
203
204
            $this->getConsole()->add(new TaskCommand($name, $task->getDescription(), $this));
205
        }
206
    }
207
208
    /**
209
     * @param string $name
210
     * @return mixed
211
     * @throws \InvalidArgumentException
212
     */
213
    public function __get($name)
214
    {
215
        if (isset($this[$name])) {
216
            return $this[$name];
217
        } else {
218
            throw new \InvalidArgumentException("Property \"$name\" does not exist.");
219
        }
220
    }
221
222
    /**
223
     * @return Application
224
     */
225
    public function getConsole()
226
    {
227
        return $this['console'];
228
    }
229
230
    /**
231
     * @return Console\Input\InputInterface
232
     */
233
    public function getInput()
234
    {
235
        return $this['input'];
236
    }
237
238
    /**
239
     * @return Console\Output\OutputInterface
240
     */
241
    public function getOutput()
242
    {
243
        return $this['output'];
244
    }
245
246
    /**
247
     * @param string $name
248
     * @return Console\Helper\HelperInterface
249
     */
250
    public function getHelper($name)
251
    {
252
        return $this->getConsole()->getHelperSet()->get($name);
253
    }
254
255
    /**
256
     * @return StageStrategy
257
     */
258
    public function getStageStrategy()
259
    {
260
        return $this['stageStrategy'];
261
    }
262
263
    /**
264
     * @return Task\ScriptManager
265
     */
266
    public function getScriptManager()
267
    {
268
        return $this['scriptManager'];
269
    }
270
271
    /**
272
     * @return LoggerInterface
273
     */
274
    public function getLogger()
275
    {
276
        return $this['log'];
277
    }
278
279
    /**
280
     * Collect anonymous stats about Deployer usage for improving developer experience.
281
     * If you are not comfortable with this, you will always be able to disable this
282
     * by setting `allow_anonymous_stats` to false in your deploy.php file.
283
     *
284
     * @param CommandEvent $commandEvent
285
     */
286
    public function collectAnonymousStats(CommandEvent $commandEvent)
287
    {
288
        if ($this->config->has('allow_anonymous_stats') && $this->config['allow_anonymous_stats'] === false) {
289
            return;
290
        }
291
292
        $stats = [
293
            'status' => 'success',
294
            'command_name' => $commandEvent->getCommand()->getName(),
295
            'servers_count' => $this->servers->count(),
296
            'deployer_version' => $this->getConsole()->getVersion(),
297
            'deployer_phar' => $this->getConsole()->isPharArchive(),
298
            'php_version' => phpversion(),
299
            'extension_pcntl' => extension_loaded('pcntl'),
300
            'extension_curl' => extension_loaded('curl'),
301
            '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))),
302
            'exception' => null,
303
        ];
304
305
        if ($commandEvent->getException() !== null) {
306
            $stats['status'] = 'error';
307
            $stats['exception'] = get_class($commandEvent->getException());
308
        }
309
310
        $send = function () use ($stats) {
311
            if (extension_loaded('curl')) {
312
                $body = json_encode($stats, JSON_PRETTY_PRINT);
313
                $ch = curl_init('https://deployer.org/api/stats');
314
                curl_setopt($ch, CURLOPT_HTTPHEADER, array(
315
                        'Content-Type: application/json',
316
                        'Content-Length: ' . strlen($body))
317
                );
318
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
319
                curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
320
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
321
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
322
                curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
323
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
324
                curl_setopt($ch, CURLOPT_TIMEOUT, 5);
325
                curl_exec($ch);
326
            } else {
327
                file_get_contents('https://deployer.org/api/stats?' . http_build_query($stats));
328
            }
329
        };
330
331
332
        if (extension_loaded('pcntl')) {
333
            declare(ticks = 1);
334
            $pid = pcntl_fork();
335
            if ($pid === 0) {
336
                posix_setsid();
337
                $send();
338
                exit(0);
0 ignored issues
show
Coding Style Compatibility introduced by
The method collectAnonymousStats() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
339
            }
340
        } else {
341
            $send();
342
        }
343
    }
344
}
345