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 ( aaa283...38e978 )
by Anton
02:16
created

functions.php ➔ run()   D

Complexity

Conditions 9
Paths 12

Size

Total Lines 38
Code Lines 26

Duplication

Lines 14
Ratio 36.84 %

Code Coverage

Tests 9
CRAP Score 17.4419

Importance

Changes 0
Metric Value
cc 9
eloc 26
nc 12
nop 1
dl 14
loc 38
ccs 9
cts 17
cp 0.5294
crap 17.4419
rs 4.909
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
namespace Deployer;
8
9
use Deployer\Builder\BuilderInterface;
10
use Deployer\Server\Local;
11
use Deployer\Server\Remote;
12
use Deployer\Server\Builder;
13
use Deployer\Server\Configuration;
14
use Deployer\Server\Environment;
15
use Deployer\Task\Task as T;
16
use Deployer\Task\Context;
17
use Deployer\Task\GroupTask;
18
use Deployer\Task\Scenario\GroupScenario;
19
use Deployer\Task\Scenario\Scenario;
20
use Deployer\Type\Result;
21
use Symfony\Component\Console\Question\ConfirmationQuestion;
22
use Symfony\Component\Console\Question\Question;
23
use Symfony\Component\Finder\Finder;
24
use Symfony\Component\Process\Process;
25
use Deployer\Cluster\ClusterFactory;
26
use Symfony\Component\Console\Input\InputArgument;
27
use Symfony\Component\Console\Input\InputInterface;
28
use Symfony\Component\Console\Input\InputOption;
29
use Symfony\Component\Console\Output\OutputInterface;
30
31
// There are two types of functions: Deployer dependent and Context dependent.
32
// Deployer dependent function uses in definition stage of recipe and may require Deployer::get() method.
33
// Context dependent function uses while task execution and must require only Context::get() method.
34
// But there is also a third type of functions: mixed. Mixed function uses in definition stage and in task
35
// execution stage. They are acts like two different function, but have same name. Example of such function
36
// is set() func. This function determine in which stage it was called by Context::get() method.
37
38
/**
39
 * @param string $name
40
 * @param string|null $host
41 2
 * @param int $port
42
 * @return BuilderInterface
43 2
 */
44 2
function server($name, $host = null, $port = 22)
45
{
46 2
    $deployer = Deployer::get();
47
48
    $env = new Environment();
49 2
    $config = new Configuration($name, $host, $port);
50
51
    if (get('ssh_type') === 'ext-ssh2') {
52 2
        $server = new Remote\SshExtension($config);
53 2
    } elseif (get('ssh_type') && get('ssh_type') === 'native') {
54
        $server = new Remote\NativeSsh($config);
55 2
    } else {
56
        $server = new Remote\PhpSecLib($config);
57
    }
58
59
    $deployer->servers->set($name, $server);
60
    $deployer->environments->set($name, $env);
61
62
    return new Builder($config, $env);
63
}
64
65 15
66
/**
67 15
 * @param string $name
68 15
 * @return BuilderInterface
69 15
 */
70
function localServer($name)
71 15
{
72 15
    $deployer = Deployer::get();
73
74 15
    $env = new Environment();
75
    $config = new Configuration($name, 'localhost'); // Builder requires server configuration.
76
    $server = new Local($config);
77
78
    $deployer->servers->set($name, $server);
79
    $deployer->environments->set($name, $env);
80
81
    return new Builder($config, $env);
82
}
83
84
/**
85
 * @param string $name Name of the cluster
86
 * @param array $nodes An array of nodes' host/ip
87
 * @param int $port Ssh port of the nodes
88
 *
89
 * Example:
90
 * You should pass a cluster name and nodes array.
91 2
 * Nodes array should be as following:
92
 * [ '192.168.1.1', 'example.com', '192.168.1.5' ]
93 2
 * @return BuilderInterface
94
 */
95 2
function cluster($name, $nodes, $port = 22)
96
{
97
    $deployer = Deployer::get();
98
99
    $cluster = ClusterFactory::create($deployer, $name, $nodes, $port);
100
101
    return $cluster->getBuilder();
102
}
103
104
105 1
/**
106 1
 * Load server list file.
107 1
 * @param string $file
108 1
 */
109 1
function serverList($file)
110 1
{
111
    $bootstrap = new Bootstrap\BootstrapByConfigFile();
112
    $bootstrap->setConfig($file);
113
    $bootstrap->parseConfig();
114
    $bootstrap->initServers();
115
    $bootstrap->initClusters();
116
}
117
118
/**
119
 * Set task description.
120
 *
121
 * @param ?string $title
0 ignored issues
show
Documentation introduced by
The doc-type ?string could not be parsed: Unknown type name "?string" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
122 17
 * @return ?string
0 ignored issues
show
Documentation introduced by
The doc-type ?string could not be parsed: Unknown type name "?string" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
123
 */
124 17
function desc($title = null)
125 17
{
126 17
    static $store = null;
127 17
128 3
    if ($title === null) {
129
        return $store;
130 3
    } else {
131 3
        return $store = $title;
132 3
    }
133 1
}
134
135
/**
136 17
 * Define a new task and save to tasks list.
137 17
 *
138
 * @param string $name Name of current task.
139 17
 * @param callable|array $body Callable task or array of other tasks names.
140
 * @return Task\Task
141
 * @throws \InvalidArgumentException
142
 */
143
function task($name, $body)
144
{
145
    $deployer = Deployer::get();
146
147
    if ($body instanceof \Closure) {
148
        $task = new T($name, $body);
149 14
    } elseif (is_array($body)) {
150 1
        $task = new GroupTask($name, $body);
0 ignored issues
show
Documentation introduced by
$body is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151 2
    } else {
152 2
        throw new \InvalidArgumentException('Task should be an closure or array of other tasks.');
153
    }
154 1
155 1
    $deployer->tasks->set($name, $task);
156
157
    if (!empty(desc())) {
158
        $task->desc(desc());
159
        desc(''); // Clear title.
160
    }
161
162
    return $task;
163
}
164
165 1
/**
166 1
 * Call that task before specified task runs.
167 1
 *
168
 * @param string $it
169 1
 * @param string $that
170 1
 */
171
function before($it, $that)
172
{
173
    $deployer = Deployer::get();
174
    $beforeTask = $deployer->tasks->get($it);
175
176
    $beforeTask->addBefore($that);
177
}
178
179
/**
180
 * Call that task after specified task runs.
181
 *
182
 * @param string $it
183
 * @param string $that
184 14
 */
185 14
function after($it, $that)
186 14
{
187 14
    $deployer = Deployer::get();
188
    $afterTask = $deployer->tasks->get($it);
189
190
    $afterTask->addAfter($that);
191
}
192
193
/**
194
 * Add users arguments.
195
 *
196
 * Note what Deployer already has one argument: "stage".
197
 *
198
 * @param string $name
199
 * @param int $mode
200 14
 * @param string $description
201 14
 * @param mixed $default
202 14
 */
203 14
function argument($name, $mode = null, $description = '', $default = null)
204
{
205
    Deployer::get()->getConsole()->getUserDefinition()->addArgument(
206
        new InputArgument($name, $mode, $description, $default)
207
    );
208
}
209
210
/**
211
 * Add users options.
212 2
 *
213 2
 * @param string $name
214
 * @param string $shortcut
215
 * @param int $mode
216
 * @param string $description
217
 * @param mixed $default
218
 */
219
function option($name, $shortcut = null, $mode = null, $description = '', $default = null)
220
{
221
    Deployer::get()->getConsole()->getUserDefinition()->addOption(
222
        new InputOption($name, $shortcut, $mode, $description, $default)
223
    );
224
}
225
226
/**
227
 * Change the current working directory.
228
 *
229
 * @param string $path
230
 */
231
function cd($path)
232
{
233
    set('working_path', Context::get()->getEnvironment()->parse($path));
234
}
235
236 12
/**
237
 * Execute a callback within a specific directory and revert back to the initial working directory.
238
 *
239
 * @param string $path
240
 * @param callable $callback
241
 */
242
function within($path, $callback)
243
{
244
    $lastWorkingPath = workingPath();
245
    set('working_path', $path);
246
    $callback();
247 12
    set('working_path', $lastWorkingPath);
248 12
}
249 12
250
/**
251 12
 * Return the current working path.
252 11
 *
253 11
 * @return string
254
 */
255 12
function workingPath()
256
{
257
    return get('working_path', get(Environment::DEPLOY_PATH, ''));
258
}
259 12
260
/**
261 12
 * Run command on server.
262
 *
263
 * @param string $command
264
 * @return Result
265
 */
266
function run($command)
267 12
{
268
    $server = Context::get()->getServer();
269
    $serverName = $server->getConfiguration()->getName();
270
    $command = Context::get()->getEnvironment()->parse($command);
271
    $workingPath = workingPath();
272
273
    if (!empty($workingPath)) {
274
        $command = "cd $workingPath && $command";
275
    }
276
277
    if (isVeryVerbose()) {
278
        writeln("[$serverName] <fg=red>></fg=red> $command");
279 5
    }
280
281 5
    if ($server instanceof Local) {
282
        $output = $server->mustRun($command, function ($type, $buffer) use ($serverName) {
283 View Code Duplication
            if (isDebug()) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
284
                output()->writeln(array_map(function ($line) use ($serverName) {
285 5
                    return output()->isDecorated()
286 5
                        ? "[$serverName] \033[1;30m< $line\033[0m"
287
                        : "[$serverName] < $line";
288 4
                }, explode("\n", rtrim($buffer))), OutputInterface::OUTPUT_RAW);
289
            }
290
        });
291
    } else {
292
        $output = $server->run($command);
293 View Code Duplication
        if (isDebug() && !empty($output)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
294
            output()->writeln(array_map(function ($line) use ($serverName) {
295 5
                return output()->isDecorated()
296
                    ? "[$serverName] \033[1;30m< $line\033[0m"
297 5
                    : "[$serverName] < $line";
298
            }, explode("\n", rtrim($output))), OutputInterface::OUTPUT_RAW);
299
        }
300
    }
301 5
302
    return new Result($output);
303
}
304
305
/**
306
 * Execute commands on local machine.
307
 * @param string $command Command to run locally.
308
 * @param int $timeout (optional) Override process command timeout in seconds.
309
 * @return Result Output of command.
310
 * @throws \RuntimeException
311
 */
312 1
function runLocally($command, $timeout = 60)
313 1
{
314 1
    $command = Context::get()->getEnvironment()->parse($command);
315
316 1
    if (isVeryVerbose()) {
317 1
        writeln("<comment>Run locally</comment>: $command");
318
    }
319 1
320 1
    $process = new Process($command);
321 1
    $process->setTimeout($timeout);
322
    $process->run(function ($type, $buffer) {
323 1
        if (isDebug()) {
324
            if ('err' === $type) {
325 1
                write("<fg=red>></fg=red> $buffer");
326 1
            } else {
327 1
                write("<fg=green>></fg=green> $buffer");
328 1
            }
329 1
        }
330
    });
331
332 1
    if (!$process->isSuccessful()) {
333 1
        throw new \RuntimeException($process->getErrorOutput());
334
    }
335
336
    return new Result($process->getOutput());
337 1
}
338 1
339 1
340 1
/**
341 1
 * Upload file or directory to current server.
342 1
 * @param string $local
343
 * @param string $remote
344
 * @throws \RuntimeException
345 1
 */
346
function upload($local, $remote)
347
{
348
    $server = Context::get()->getServer();
349
    $local = Context::get()->getEnvironment()->parse($local);
350
    $remote = Context::get()->getEnvironment()->parse($remote);
351
352
    if (is_file($local)) {
353
        writeln("Upload file <info>$local</info> to <info>$remote</info>");
354
355 2
        $server->upload($local, $remote);
356 2
    } elseif (is_dir($local)) {
357 2
        writeln("Upload from <info>$local</info> to <info>$remote</info>");
358
359 2
        $finder = new Finder();
360 2
        $files = $finder
361
            ->files()
362
            ->ignoreUnreadableDirs()
363
            ->ignoreVCS(true)
364
            ->ignoreDotFiles(false)
365
            ->in($local);
366
367
        /** @var $file \Symfony\Component\Finder\SplFileInfo */
368 4
        foreach ($files as $file) {
369 4
            if (isDebug()) {
370
                writeln("Uploading <info>{$file->getRealPath()}</info>");
371
            }
372
373
            $server->upload(
374
                $file->getRealPath(),
375
                $remote . '/' . $file->getRelativePathname()
376
            );
377
        }
378
    } else {
379
        throw new \RuntimeException("Uploading path '$local' does not exist.");
380
    }
381
}
382
383
/**
384
 * Download file from remote server.
385
 *
386 14
 * @param string $local
387 14
 * @param string $remote
388
 */
389
function download($local, $remote)
390
{
391
    $server = Context::get()->getServer();
392
    $local = Context::get()->getEnvironment()->parse($local);
393
    $remote = Context::get()->getEnvironment()->parse($remote);
394
395 4
    $server->download($local, $remote);
396
}
397
398
/**
399
 * Writes a message to the output and adds a newline at the end.
400
 * @param string|array $message
401
 */
402
function writeln($message)
403
{
404
    output()->writeln($message);
405
}
406
407
/**
408
 * Writes a message to the output.
409
 * @param string $message
410
 */
411
function write($message)
412
{
413
    output()->write($message);
414
}
415
416
/**
417
 * Setup configuration option.
418
 *
419
 * @param string $name
420
 * @param mixed $value
421
 */
422
function set($name, $value)
423
{
424
    if (Context::get() === false) {
425
        Deployer::setDefault($name, $value);
426
    } else {
427
        Context::get()->getEnvironment()->set($name, $value);
428
    }
429
}
430
431
/**
432
 * Merge new config params to existing config array.
433
 *
434
 * @param string $name
435
 * @param array $array
436
 */
437
function add($name, $array)
438
{
439
    if (Context::get() === false) {
440
        Deployer::addDefault($name, $array);
441
    } else {
442
        Context::get()->getEnvironment()->add($name, $array);
443
    }
444
}
445
446
/**
447
 * Get configuration value.
448
 *
449
 * @param string $name
450
 * @param mixed|null $default
451
 * @return mixed
452
 */
453
function get($name, $default = null)
454
{
455
    if (Context::get() === false) {
456
        return Deployer::getDefault($name, $default);
457
    } else {
458
        return Context::get()->getEnvironment()->get($name, $default);
459
    }
460
}
461
462
/**
463
 * Check if there is such configuration option.
464
 *
465
 * @param string $name
466
 * @return boolean
467
 */
468
function has($name)
469
{
470
    if (Context::get() === false) {
471
        return Deployer::hasDefault($name);
472
    } else {
473
        return Context::get()->getEnvironment()->has($name);
474
    }
475
}
476
477
/**
478
 * @param string $message
479
 * @param string|null $default
480
 * @return string
481
 * @codeCoverageIgnore
482
 */
483
function ask($message, $default = null)
484
{
485
    if (isQuiet()) {
486 17
        return $default;
487
    }
488
489
    $helper = Deployer::get()->getHelper('question');
490
491
    $message = "<question>$message" . (($default === null) ? "" : " [$default]") . "</question> ";
492
493
    $question = new Question($message, $default);
494
495
    return $helper->ask(input(), output(), $question);
496
}
497
498
/**
499
 * @param string $message
500
 * @param bool $default
501
 * @return bool
502
 * @codeCoverageIgnore
503 1
 */
504
function askConfirmation($message, $default = false)
505
{
506
    if (isQuiet()) {
507
        return $default;
508
    }
509
510
    $helper = Deployer::get()->getHelper('question');
511
512 16
    $yesOrNo = $default ? 'Y/n' : 'y/N';
513
    $message = "<question>$message [$yesOrNo]</question> ";
514
515
    $question = new ConfirmationQuestion($message, $default);
516
517
    return $helper->ask(input(), output(), $question);
518
}
519
520
/**
521 17
 * @param string $message
522
 * @return string
523
 * @codeCoverageIgnore
524
 */
525
function askHiddenResponse($message)
526
{
527
    if (isQuiet()) {
528
        return '';
529
    }
530
531
    $helper = Deployer::get()->getHelper('question');
532
533
    $message = "<question>$message</question> ";
534 19
535 14
    $question = new Question($message);
536 14
    $question->setHidden(true);
537 19
    $question->setHiddenFallback(false);
538 19
539 8
    return $helper->ask(input(), output(), $question);
540 6
}
541
542 2
/**
543
 * @return InputInterface
544 2
 */
545
function input()
546 14
{
547
    return Context::get()->getInput();
548
}
549
550
551
/**
552
 * @return OutputInterface
553
 */
554
function output()
555
{
556 2
    return Context::get()->getOutput();
557
}
558
559
/**
560
 * @return bool
561
 */
562
function isQuiet()
563
{
564
    return OutputInterface::VERBOSITY_QUIET === output()->getVerbosity();
565
}
566
567
568
/**
569
 * @return bool
570
 */
571
function isVerbose()
572
{
573
    return OutputInterface::VERBOSITY_VERBOSE <= output()->getVerbosity();
574
}
575
576
577
/**
578
 * @return bool
579
 */
580
function isVeryVerbose()
581
{
582
    return OutputInterface::VERBOSITY_VERY_VERBOSE <= output()->getVerbosity();
583
}
584
585
586
/**
587
 * @return bool
588
 */
589
function isDebug()
590
{
591
    return OutputInterface::VERBOSITY_DEBUG <= output()->getVerbosity();
592
}
593
594
/**
595
 * Deprecated, use set()/get().
596
 * @deprecated
597
 */
598
function env()
599
{
600
    throw new \RuntimeException('env() function deprecated. Please, use set() or get() instead of.');
601
}
602
603
/**
604
 * Check if command exist in bash.
605
 *
606
 * @param string $command
607
 * @return bool
608
 */
609
function commandExist($command)
610
{
611
    return run("if hash $command 2>/dev/null; then echo 'true'; fi")->toBool();
612
}
613