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 ( 4c31fa...fc44b2 )
by Anton
27s
created

functions.php ➔ ask()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 6
nop 3
dl 0
loc 22
ccs 1
cts 1
cp 1
crap 6
rs 8.6737
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\Type\Result;
19
use Monolog\Logger;
20
use Symfony\Component\Console\Question\ConfirmationQuestion;
21
use Symfony\Component\Console\Question\Question;
22
use Symfony\Component\Finder\Finder;
23
use Symfony\Component\Process\Exception\ProcessFailedException;
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|string $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);
151 2
    } elseif (is_string($body)) {
152 2
        $task = new T($name, function () use ($body) {
153
            run($body);
154 1
        });
155 1
    } else {
156
        throw new \InvalidArgumentException('Task should be an closure or array of other tasks.');
157
    }
158
159
    $deployer->tasks->set($name, $task);
160
161
    if (!empty(desc())) {
162
        $task->desc(desc());
163
        desc(''); // Clear title.
164
    }
165 1
166 1
    return $task;
167 1
}
168
169 1
/**
170 1
 * Call that task before specified task runs.
171
 *
172
 * @param string $it
173
 * @param string $that
174
 */
175
function before($it, $that)
176
{
177
    $deployer = Deployer::get();
178
    $beforeTask = $deployer->tasks->get($it);
179
180
    $beforeTask->addBefore($that);
181
}
182
183
/**
184 14
 * Call that task after specified task runs.
185 14
 *
186 14
 * @param string $it
187 14
 * @param string $that
188
 */
189
function after($it, $that)
190
{
191
    $deployer = Deployer::get();
192
    $afterTask = $deployer->tasks->get($it);
193
194
    $afterTask->addAfter($that);
195
}
196
197
/**
198
 * Setup which task run on failure of first.
199
 *
200 14
 * @param string $it
201 14
 * @param string $that
202 14
 */
203 14
function onFailure($it, $that)
204
{
205
    $deployer = Deployer::get();
206
    $deployer['onFailure']->set($it, $that);
207
}
208
209
/**
210
 * Add users arguments.
211
 *
212 2
 * Note what Deployer already has one argument: "stage".
213 2
 *
214
 * @param string $name
215
 * @param int $mode
216
 * @param string $description
217
 * @param mixed $default
218
 */
219
function argument($name, $mode = null, $description = '', $default = null)
220
{
221
    Deployer::get()->getConsole()->getUserDefinition()->addArgument(
222
        new InputArgument($name, $mode, $description, $default)
223
    );
224
}
225
226
/**
227
 * Add users options.
228
 *
229
 * @param string $name
230
 * @param string $shortcut
231
 * @param int $mode
232
 * @param string $description
233
 * @param mixed $default
234
 */
235
function option($name, $shortcut = null, $mode = null, $description = '', $default = null)
236 12
{
237
    Deployer::get()->getConsole()->getUserDefinition()->addOption(
238
        new InputOption($name, $shortcut, $mode, $description, $default)
239
    );
240
}
241
242
/**
243
 * Change the current working directory.
244
 *
245
 * @param string $path
246
 */
247 12
function cd($path)
248 12
{
249 12
    set('working_path', parse($path));
250
}
251 12
252 11
/**
253 11
 * Execute a callback within a specific directory and revert back to the initial working directory.
254
 *
255 12
 * @param string $path
256
 * @param callable $callback
257
 */
258
function within($path, $callback)
259 12
{
260
    $lastWorkingPath = workingPath();
261 12
    set('working_path', $path);
262
    $callback();
263
    set('working_path', $lastWorkingPath);
264
}
265
266
/**
267 12
 * Return the current working path.
268
 *
269
 * @return string
270
 */
271
function workingPath()
272
{
273
    return get('working_path', get(Environment::DEPLOY_PATH, ''));
274
}
275
276
/**
277
 * Run command on server.
278
 *
279 5
 * @param string $command
280
 * @return Result
281 5
 */
282
function run($command)
283
{
284
    $server = Context::get()->getServer();
285 5
    $serverName = $server->getConfiguration()->getName();
286 5
    $command = parse($command);
287
    $workingPath = workingPath();
288 4
289
    if (!empty($workingPath)) {
290
        $command = "cd $workingPath && ($command)";
291
    }
292
293
    if (isVeryVerbose()) {
294
        writeln("[$serverName] <fg=red>></fg=red> $command");
295 5
    }
296
297 5
    logger("[$serverName] > $command");
298
299
    if ($server instanceof Local) {
300
        $output = $server->mustRun($command, function ($type, $buffer) use ($serverName) {
301 5 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...
302
                output()->writeln(array_map(function ($line) use ($serverName) {
303
                    return output()->isDecorated()
304
                        ? "[$serverName] \033[1;30m< $line\033[0m"
305
                        : "[$serverName] < $line";
306
                }, explode("\n", rtrim($buffer))), OutputInterface::OUTPUT_RAW);
307
            }
308
        });
309
    } else {
310
        $output = $server->run($command);
311 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...
312 1
            output()->writeln(array_map(function ($line) use ($serverName) {
313 1
                return output()->isDecorated()
314 1
                    ? "[$serverName] \033[1;30m< $line\033[0m"
315
                    : "[$serverName] < $line";
316 1
            }, explode("\n", rtrim($output))), OutputInterface::OUTPUT_RAW);
317 1
        }
318
    }
319 1
320 1
    if (!empty(rtrim($output))) {
321 1
        logger("[$serverName] < $output");
322
    }
323 1
324
    return new Result($output);
325 1
}
326 1
327 1
/**
328 1
 * Execute commands on local machine.
329 1
 * @param string $command Command to run locally.
330
 * @param int $timeout (optional) Override process command timeout in seconds.
331
 * @return Result Output of command.
332 1
 * @throws \RuntimeException
333 1
 */
334
function runLocally($command, $timeout = 300)
335
{
336
    $command = parse($command);
337 1
338 1
    if (isVeryVerbose()) {
339 1
        writeln("[localhost] <fg=red>></fg=red> : $command");
340 1
    }
341 1
342 1
    logger("[localhost] > $command");
343
344
    $process = new Process($command);
345 1
    $process->setTimeout($timeout);
346
    $process->run(function ($type, $buffer) {
347
        if (isDebug()) {
348
            if ('err' === $type) {
349
                write("<fg=red>></fg=red> $buffer");
350
            } else {
351
                write("<fg=green>></fg=green> $buffer");
352
            }
353
        }
354
    });
355 2
356 2
    if (!$process->isSuccessful()) {
357 2
        throw new ProcessFailedException($process);
358
    }
359 2
360 2
    $output = $process->getOutput();
361
362
    logger("[localhost] < $output");
363
364
    return new Result($output);
365
}
366
367
/**
368 4
 * Run test command.
369 4
 * Example:
370
 *
371
 *     test('[ -d {{release_path}} ]')
372
 *
373
 * @param string $command
374
 * @return bool
375
 */
376
function test($command)
377
{
378
    return run("if $command; then echo 'true'; fi")->toBool();
379
}
380
381
/**
382
 * Run test command locally.
383
 * Example:
384
 *
385
 *     testLocally('[ -d {{local_release_path}} ]')
386 14
 *
387 14
 * @param string $command
388
 * @return bool
389
 */
390
function testLocally($command)
391
{
392
    return runLocally("if $command; then echo 'true'; fi")->toBool();
393
}
394
395 4
/**
396
 * Upload file or directory to current server.
397
 * @param string $local
398
 * @param string $remote
399
 * @throws \RuntimeException
400
 */
401
function upload($local, $remote)
402
{
403
    $server = Context::get()->getServer();
404
    $local = parse($local);
405
    $remote = parse($remote);
406
407
    if (is_file($local)) {
408
        writeln("Upload file <info>$local</info> to <info>$remote</info>");
409
410
        $server->upload($local, $remote);
411
    } elseif (is_dir($local)) {
412
        writeln("Upload from <info>$local</info> to <info>$remote</info>");
413
414
        $finder = new Finder();
415
        $files = $finder
416
            ->files()
417
            ->ignoreUnreadableDirs()
418
            ->ignoreVCS(true)
419
            ->ignoreDotFiles(false)
420
            ->in($local);
421
422
        /** @var $file \Symfony\Component\Finder\SplFileInfo */
423
        foreach ($files as $file) {
424
            if (isDebug()) {
425
                writeln("Uploading <info>{$file->getRealPath()}</info>");
426
            }
427
428
            $server->upload(
429
                $file->getRealPath(),
430
                $remote . '/' . $file->getRelativePathname()
431
            );
432
        }
433
    } else {
434
        throw new \RuntimeException("Uploading path '$local' does not exist.");
435
    }
436
}
437
438
/**
439
 * Download file from remote server.
440
 *
441
 * @param string $local
442
 * @param string $remote
443
 */
444
function download($local, $remote)
445
{
446
    $server = Context::get()->getServer();
447
    $local = parse($local);
448
    $remote = parse($remote);
449
450
    writeln("Download file <info>$remote</info> to <info>$local</info>");
451
    $server->download($local, $remote);
452
}
453
454
/**
455
 * Writes a message to the output and adds a newline at the end.
456
 * @param string|array $message
457
 */
458
function writeln($message)
459
{
460
    output()->writeln($message);
461
}
462
463
/**
464
 * Writes a message to the output.
465
 * @param string $message
466
 */
467
function write($message)
468
{
469
    output()->write($message);
470
}
471
472
/**
473
 * @param string $message
474
 * @param int $level
475
 */
476
function logger($message, $level = Logger::DEBUG)
477
{
478
    if (is_array($message)) {
479
        $message = join("\n", $message);
480
    }
481
482
    Deployer::get()->getLogger()->log($level, $message);
483
}
484
485
/**
486 17
 * Setup configuration option.
487
 *
488
 * @param string $name
489
 * @param mixed $value
490
 */
491
function set($name, $value)
492
{
493
    if (Context::get() === false) {
494
        Deployer::setDefault($name, $value);
495
    } else {
496
        Context::get()->getEnvironment()->set($name, $value);
497
    }
498
}
499
500
/**
501
 * Merge new config params to existing config array.
502
 *
503 1
 * @param string $name
504
 * @param array $array
505
 */
506
function add($name, $array)
507
{
508
    if (Context::get() === false) {
509
        Deployer::addDefault($name, $array);
510
    } else {
511
        Context::get()->getEnvironment()->add($name, $array);
512 16
    }
513
}
514
515
/**
516
 * Get configuration value.
517
 *
518
 * @param string $name
519
 * @param mixed|null $default
520
 * @return mixed
521 17
 */
522
function get($name, $default = null)
523
{
524
    if (Context::get() === false) {
525
        return Deployer::getDefault($name, $default);
526
    } else {
527
        return Context::get()->getEnvironment()->get($name, $default);
528
    }
529
}
530
531
/**
532
 * Check if there is such configuration option.
533
 *
534 19
 * @param string $name
535 14
 * @return boolean
536 14
 */
537 19
function has($name)
538 19
{
539 8
    if (Context::get() === false) {
540 6
        return Deployer::hasDefault($name);
541
    } else {
542 2
        return Context::get()->getEnvironment()->has($name);
543
    }
544 2
}
545
546 14
/**
547
 * @param string $message
548
 * @param string|null $default
549
 * @param string[]|null $suggestedChoices
550
 * @return string
551
 * @codeCoverageIgnore
552
 */
553
function ask($message, $default = null, $suggestedChoices = null)
554
{
555
    if (($suggestedChoices !== null) && (empty($suggestedChoices))) {
556 2
        throw new \InvalidArgumentException('Suggested choices should not be empty');
557
    }
558
559
    if (isQuiet()) {
560
        return $default;
561
    }
562
563
    $helper = Deployer::get()->getHelper('question');
564
565
    $message = "<question>$message" . (($default === null) ? "" : " [$default]") . "</question> ";
566
567
    $question = new Question($message, $default);
568
569
    if (empty($suggestedChoices) === false) {
570
        $question->setAutocompleterValues($suggestedChoices);
571
    }
572
573
    return $helper->ask(input(), output(), $question);
574
}
575
576
/**
577
 * @param string $message
578
 * @param bool $default
579
 * @return bool
580
 * @codeCoverageIgnore
581
 */
582
function askConfirmation($message, $default = false)
583
{
584
    if (isQuiet()) {
585
        return $default;
586
    }
587
588
    $helper = Deployer::get()->getHelper('question');
589
590
    $yesOrNo = $default ? 'Y/n' : 'y/N';
591
    $message = "<question>$message [$yesOrNo]</question> ";
592
593
    $question = new ConfirmationQuestion($message, $default);
594
595
    return $helper->ask(input(), output(), $question);
596
}
597
598
/**
599
 * @param string $message
600
 * @return string
601
 * @codeCoverageIgnore
602
 */
603
function askHiddenResponse($message)
604
{
605
    if (isQuiet()) {
606
        return '';
607
    }
608
609
    $helper = Deployer::get()->getHelper('question');
610
611
    $message = "<question>$message</question> ";
612
613
    $question = new Question($message);
614
    $question->setHidden(true);
615
    $question->setHiddenFallback(false);
616
617
    return $helper->ask(input(), output(), $question);
618
}
619
620
/**
621
 * @return InputInterface
622
 */
623
function input()
624
{
625
    return Context::get()->getInput();
626
}
627
628
629
/**
630
 * @return OutputInterface
631
 */
632
function output()
633
{
634
    return Context::get()->getOutput();
635
}
636
637
/**
638
 * @return bool
639
 */
640
function isQuiet()
641
{
642
    return OutputInterface::VERBOSITY_QUIET === output()->getVerbosity();
643
}
644
645
646
/**
647
 * @return bool
648
 */
649
function isVerbose()
650
{
651
    return OutputInterface::VERBOSITY_VERBOSE <= output()->getVerbosity();
652
}
653
654
655
/**
656
 * @return bool
657
 */
658
function isVeryVerbose()
659
{
660
    return OutputInterface::VERBOSITY_VERY_VERBOSE <= output()->getVerbosity();
661
}
662
663
664
/**
665
 * @return bool
666
 */
667
function isDebug()
668
{
669
    return OutputInterface::VERBOSITY_DEBUG <= output()->getVerbosity();
670
}
671
672
/**
673
 * Deprecated, use set()/get().
674
 * @deprecated
675
 */
676
function env()
677
{
678
    throw new \RuntimeException('env() function deprecated. Please, use set() or get() instead of.');
679
}
680
681
/**
682
 * Check if command exist in bash.
683
 *
684
 * @param string $command
685
 * @return bool
686
 */
687
function commandExist($command)
688
{
689
    return run("if hash $command 2>/dev/null; then echo 'true'; fi")->toBool();
690
}
691
692
/**
693
 * Parse set values.
694
 *
695
 * @param string $value
696
 * @return string
697
 */
698
function parse($value)
699
{
700
    return Context::get()->getEnvironment()->parse($value);
701
}
702