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 ( 017822...ad8e77 )
by Anton
03:32
created

functions.php ➔ isQuiet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
ccs 1
cts 1
cp 1
crap 1
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\Exception\RuntimeException;
11
use Deployer\Host\FileLoader;
12
use Deployer\Host\Host;
13
use Deployer\Host\Localhost;
14
use Deployer\Host\Range;
15
use Deployer\Support\Proxy;
16
use Deployer\Task\Context;
17
use Deployer\Task\GroupTask;
18
use Deployer\Task\Task as T;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
use Symfony\Component\Console\Question\ChoiceQuestion;
24
use Symfony\Component\Console\Question\ConfirmationQuestion;
25
use Symfony\Component\Console\Question\Question;
26
use function Deployer\Support\array_to_string;
27
28
// There are two types of functions: Deployer dependent and Context dependent.
29
// Deployer dependent function uses in definition stage of recipe and may require Deployer::get() method.
30
// Context dependent function uses while task execution and must require only Context::get() method.
31
// But there is also a third type of functions: mixed. Mixed function uses in definition stage and in task
32
// execution stage. They are acts like two different function, but have same name. Example of such function
33
// is set() func. This function determine in which stage it was called by Context::get() method.
34
35
/**
36
 * @param array ...$hostnames
37
 * @return Host|Host[]|Proxy
38
 */
39
function host(...$hostnames)
40
{
41 2
    $deployer = Deployer::get();
42 2
    $hostnames = Range::expand($hostnames);
43
44
    // Return hosts if has
45 2
    if ($deployer->hosts->has($hostnames[0])) {
46 2
        if (count($hostnames) === 1) {
47 1
            return $deployer->hosts->get($hostnames[0]);
48
        } else {
49 1
            return array_map([$deployer->hosts, 'get'], $hostnames);
50
        }
51
    }
52
53
    // Add otherwise
54 1
    if (count($hostnames) === 1) {
55 1
        $host = new Host($hostnames[0]);
56 1
        $deployer->hosts->set($hostnames[0], $host);
57 1
        return $host;
58
    } else {
59
        $hosts = array_map(function ($hostname) use ($deployer) {
60 1
            $host = new Host($hostname);
61 1
            $deployer->hosts->set($hostname, $host);
62 1
            return $host;
63 1
        }, $hostnames);
64 1
        return new Proxy($hosts);
65
    }
66
}
67
68
/**
69
 * @param array ...$hostnames
70
 * @return Localhost|Localhost[]|Proxy
71
 */
72
function localhost(...$hostnames)
73
{
74 16
    $deployer = Deployer::get();
75 16
    $hostnames = Range::expand($hostnames);
76
77 16
    if (count($hostnames) <= 1) {
78 10
        $host = count($hostnames) === 1 ? new Localhost($hostnames[0]) : new Localhost();
79 10
        $deployer->hosts->set($host->getHostname(), $host);
80 10
        return $host;
81
    } else {
82
        $hosts = array_map(function ($hostname) use ($deployer) {
83 6
            $host = new Localhost($hostname);
84 6
            $deployer->hosts->set($host->getHostname(), $host);
85 6
            return $host;
86 6
        }, $hostnames);
87 6
        return new Proxy($hosts);
88
    }
89
}
90
91
/**
92
 * Load list of hosts from file
93
 *
94
 * @param string $file
95
 * @return Proxy
96
 */
97
function inventory($file)
98
{
99 1
    $deployer = Deployer::get();
100 1
    $fileLoader = new FileLoader();
101 1
    $fileLoader->load($file);
102
103 1
    $hosts = $fileLoader->getHosts();
104 1
    foreach ($hosts as $host) {
105 1
        $deployer->hosts->set($host->getHostname(), $host);
106
    }
107
108 1
    return new Proxy($hosts);
109
}
110
111
/**
112
 * Set task description.
113
 *
114
 * @param string $title
115
 * @return string
116
 */
117
function desc($title = null)
118
{
119 18
    static $store = null;
120
121 18
    if ($title === null) {
122 18
        return $store;
123
    } else {
124 10
        return $store = $title;
125
    }
126
}
127
128
/**
129
 * Define a new task and save to tasks list.
130
 *
131
 * Alternatively get a defined task.
132
 *
133
 * @param string $name Name of current task.
134
 * @param callable|array|string|null $body Callable task, array of other tasks names or nothing to get a defined tasks
135
 * @return Task\Task
136
 * @throws \InvalidArgumentException
137
 */
138
function task($name, $body = null)
139
{
140 18
    $deployer = Deployer::get();
141
142 18
    if (empty($body)) {
143 1
        $task = $deployer->tasks->get($name);
144 1
        return $task;
145
    }
146
147 18
    if (is_callable($body)) {
148 16
        $task = new T($name, $body);
149 17
    } elseif (is_array($body)) {
150 15
        $task = new GroupTask($name, $body);
151 10
    } elseif (is_string($body)) {
152
        $task = new T($name, function () use ($body) {
153 1
            cd('{{release_path}}');
154 1
            run($body);
155 10
        });
156
    } else {
157
        throw new \InvalidArgumentException('Task should be an closure or array of other tasks.');
158
    }
159
160 18
    $deployer->tasks->set($name, $task);
161
162 18
    if (!empty(desc())) {
163 10
        $task->desc(desc());
164 10
        desc(''); // Clear title.
165
    }
166
167 18
    return $task;
168
}
169
170
/**
171
 * Call that task before specified task runs.
172
 *
173
 * @param string $it The task before $that should be run.
174
 * @param string $that The task to be run.
175
 */
176
function before($it, $that)
177
{
178 1
    $deployer = Deployer::get();
179 1
    $beforeTask = $deployer->tasks->get($it);
180
181 1
    $beforeTask->addBefore($that);
182 1
}
183
184
/**
185
 * Call that task after specified task runs.
186
 *
187
 * @param string $it The task after $that should be run.
188
 * @param string $that The task to be run.
189
 */
190
function after($it, $that)
191
{
192 1
    $deployer = Deployer::get();
193 1
    $afterTask = $deployer->tasks->get($it);
194
195 1
    $afterTask->addAfter($that);
196 1
}
197
198
/**
199
 * Setup which task run on failure of first.
200
 *
201
 * @param string $it The task which need to fail so $that should be run.
202
 * @param string $that The task to be run.
203
 */
204
function fail($it, $that)
205
{
206 10
    $deployer = Deployer::get();
207 10
    $deployer->fail->set($it, $that);
208 10
}
209
210
/**
211
 * Add users arguments.
212
 *
213
 * Note what Deployer already has one argument: "stage".
214
 *
215
 * @param string $name
216
 * @param int $mode
217
 * @param string $description
218
 * @param mixed $default
219
 */
220
function argument($name, $mode = null, $description = '', $default = null)
221
{
222
    Deployer::get()->getConsole()->getUserDefinition()->addArgument(
223
        new InputArgument($name, $mode, $description, $default)
224
    );
225
}
226
227
/**
228
 * Add users options.
229
 *
230
 * @param string $name
231
 * @param string $shortcut
232
 * @param int $mode
233
 * @param string $description
234
 * @param mixed $default
235
 */
236
function option($name, $shortcut = null, $mode = null, $description = '', $default = null)
237
{
238 10
    Deployer::get()->getConsole()->getUserDefinition()->addOption(
239 10
        new InputOption($name, $shortcut, $mode, $description, $default)
240
    );
241 10
}
242
243
/**
244
 * Change the current working directory.
245
 *
246
 * @param string $path
247
 */
248
function cd($path)
249
{
250
    try {
251 7
        set('working_path', parse($path));
252
    } catch (RuntimeException $e) {
253
        throw new \Exception('Unable to change directory into "'. $path .'"', 0, $e);
254
    }
255 7
}
256
257
/**
258
 * Execute a callback within a specific directory and revert back to the initial working directory.
259
 *
260
 * @param string $path
261
 * @param callable $callback
262
 */
263
function within($path, $callback)
264
{
265
    $lastWorkingPath = get('working_path', '');
266
    try {
267
        set('working_path', parse($path));
268
        $callback();
269
    } finally {
270
        set('working_path', $lastWorkingPath);
271
    }
272
}
273
274
/**
275
 * Run command.
276
 *
277
 * @param string $command
278
 * @param array $options
279
 * @return string
280
 */
281
function run($command, $options = [])
282
{
283 9
    $host = Context::get()->getHost();
284 9
    $hostname = $host->getHostname();
285
286 9
    $command = parse($command);
287 9
    $workingPath = get('working_path', '');
288
289 9
    if (!empty($workingPath)) {
290 7
        $command = "cd $workingPath && ($command)";
291
    }
292
293 9
    $env = get('env', []) + ($options['env'] ?? []);
294 9
    if (!empty($env)) {
295 1
        $env = array_to_string($env);
296 1
        $command = "export $env; $command";
297
    }
298
299 9
    if ($host instanceof Localhost) {
300 9
        $process = Deployer::get()->processRunner;
301 9
        $output = $process->run($hostname, $command, $options);
302
    } else {
303
        $client = Deployer::get()->sshClient;
304
        $output = $client->run($host, $command, $options);
305
    }
306
307 9
    return rtrim($output);
308
}
309
310
/**
311
 * Execute commands on local machine
312
 *
313
 * @param string $command Command to run locally.
314
 * @param array $options
315
 * @return string Output of command.
316
 */
317
function runLocally($command, $options = [])
318
{
319 2
    $process = Deployer::get()->processRunner;
320 2
    $hostname = 'localhost';
321 2
    $command = parse($command);
322
323 2
    $env = get('env', []) + ($options['env'] ?? []);
324 2
    if (!empty($env)) {
325 1
        $env = array_to_string($env);
326 1
        $command = "export $env; $command";
327
    }
328
329 2
    $output = $process->run($hostname, $command, $options);
330
331 2
    return rtrim($output);
332
}
333
334
/**
335
 * Run test command.
336
 * Example:
337
 *
338
 *     test('[ -d {{release_path}} ]')
339
 *
340
 * @param string $command
341
 * @return bool
342
 */
343
function test($command)
344
{
345 7
    return run("if $command; then echo 'true'; fi") === 'true';
346
}
347
348
/**
349
 * Run test command locally.
350
 * Example:
351
 *
352
 *     testLocally('[ -d {{local_release_path}} ]')
353
 *
354
 * @param string $command
355
 * @return bool
356
 */
357
function testLocally($command)
358
{
359
    return runLocally("if $command; then echo 'true'; fi") === 'true';
360
}
361
362
/**
363
 * Iterate other hosts, allowing to call run func in callback.
364
 *
365
 * @experimental
366
 * @param Host|Host[] $hosts
367
 * @param callable $callback
368
 */
369
function on($hosts, callable $callback)
370
{
371 5
    $input = Context::has() ? input() : null;
372 5
    $output = Context::has() ? output() : null;
373
374 5
    if (!is_array($hosts) && !($hosts instanceof \Traversable)) {
375
        $hosts = [$hosts];
376
    }
377
378 5
    foreach ($hosts as $host) {
379 5
        if ($host instanceof Host) {
380 5
            Context::push(new Context($host, $input, $output));
381
            try {
382 5
                $callback($host);
383 5
            } finally {
384 5
                Context::pop();
385
            }
386
        } else {
387 5
            throw new \InvalidArgumentException("Function on can iterate only on Host instances.");
388
        }
389
    }
390 5
}
391
392
/**
393
 * Return hosts based on roles.
394
 *
395
 * @experimental
396
 * @param string[] $roles
397
 * @return Host[]
398
 */
399
function roles(...$roles)
400
{
401 1
    return Deployer::get()->hostSelector->getByRoles($roles);
402
}
403
404
/**
405
 * Run task
406
 *
407
 * @experimental
408
 * @param string $task
409
 */
410
function invoke($task)
411
{
412 2
    $hosts = [Context::get()->getHost()];
413 2
    $tasks = Deployer::get()->scriptManager->getTasks($task, $hosts);
414
415 2
    $executor = Deployer::get()->seriesExecutor;
416 2
    $executor->run($tasks, $hosts);
417 2
}
418
419
/**
420
 * Upload file or directory to host
421
 *
422
 * @param string $source
423
 * @param string $destination
424
 * @param array $config
425
 */
426 View Code Duplication
function upload($source, $destination, array $config = [])
427
{
428
    $rsync = Deployer::get()->rsync;
429
    $host = Context::get()->getHost();
430
    $source = parse($source);
431
    $destination = parse($destination);
432
433
    if ($host instanceof Localhost) {
434
        $rsync->call($host->getHostname(), $source, $destination, $config);
435
    } else {
436
        $sshArguments = $host->getSshArguments()->getCliArguments();
437
        if (empty($sshArguments) === false) {
438
            if (!isset($config['options']) || !is_array($config['options'])) {
439
                $config['options'] = [];
440
            }
441
            $config['options'][] = "-e 'ssh $sshArguments'";
442
        }
443
        $rsync->call($host->getHostname(), $source, "$host:$destination", $config);
444
    }
445
}
446
447
/**
448
 * Download file or directory from host
449
 *
450
 * @param string $destination
451
 * @param string $source
452
 * @param array $config
453
 */
454 View Code Duplication
function download($source, $destination, array $config = [])
455
{
456
    $rsync = Deployer::get()->rsync;
457
    $host = Context::get()->getHost();
458
    $source = parse($source);
459
    $destination = parse($destination);
460
461
    if ($host instanceof Localhost) {
462
        $rsync->call($host->getHostname(), $source, $destination, $config);
463
    } else {
464
        $sshArguments = $host->getSshArguments()->getCliArguments();
465
        if (empty($sshArguments) === false) {
466
            if (!isset($config['options']) || !is_array($config['options'])) {
467
                $config['options'] = [];
468
            }
469
            $config['options'][] = "-e 'ssh $sshArguments'";
470
        }
471
        $rsync->call($host->getHostname(), "$host:$source", $destination, $config);
472
    }
473
}
474
475
/**
476
 * Writes a message to the output and adds a newline at the end.
477
 * @param string|array $message
478
 * @param int $options
479
 */
480
function writeln($message, $options = 0)
481
{
482 10
    output()->writeln(parse($message), $options);
483 10
}
484
485
/**
486
 * Writes a message to the output.
487
 * @param string $message
488
 * @param int $options
489
 */
490
function write($message, $options = 0)
491
{
492
    output()->write(parse($message), $options);
493
}
494
495
/**
496
 * Setup configuration option.
497
 *
498
 * @param string $name
499
 * @param mixed $value
500
 */
501
function set($name, $value)
502
{
503 11
    if (!Context::has()) {
504 11
        Deployer::setDefault($name, $value);
505
    } else {
506 7
        Context::get()->getConfig()->set($name, $value);
507
    }
508 11
}
509
510
/**
511
 * Merge new config params to existing config array.
512
 *
513
 * @param string $name
514
 * @param array $array
515
 */
516
function add($name, $array)
517
{
518 1
    if (!Context::has()) {
519
        Deployer::addDefault($name, $array);
520
    } else {
521 1
        Context::get()->getConfig()->add($name, $array);
522
    }
523 1
}
524
525
/**
526
 * Get configuration value.
527
 *
528
 * @param string $name
529
 * @param mixed|null $default
530
 * @return mixed
531
 */
532
function get($name, $default = null)
533
{
534 11
    if (!Context::has()) {
535
        return Deployer::getDefault($name, $default);
536
    } else {
537 11
        return Context::get()->getConfig()->get($name, $default);
538
    }
539
}
540
541
/**
542
 * Check if there is such configuration option.
543
 *
544
 * @param string $name
545
 * @return boolean
546
 */
547
function has($name)
548
{
549 5
    if (!Context::has()) {
550
        return Deployer::hasDefault($name);
551
    } else {
552 5
        return Context::get()->getConfig()->has($name);
553
    }
554
}
555
556
/**
557
 * @param string $message
558
 * @param string|null $default
559
 * @param string[]|null $suggestedChoices
560
 * @return string
561
 * @codeCoverageIgnore
562
 */
563
function ask($message, $default = null, $suggestedChoices = null)
564
{
565
    Context::required(__FUNCTION__);
566
567
    if (($suggestedChoices !== null) && (empty($suggestedChoices))) {
568
        throw new \InvalidArgumentException('Suggested choices should not be empty');
569
    }
570
571
    if (isQuiet()) {
572
        return $default;
573
    }
574
575
    $helper = Deployer::get()->getHelper('question');
576
577
    $message = "<question>$message" . (($default === null) ? "" : " [$default]") . "</question> ";
578
579
    $question = new Question($message, $default);
580
581
    if (empty($suggestedChoices) === false) {
582
        $question->setAutocompleterValues($suggestedChoices);
583
    }
584
585
    return $helper->ask(input(), output(), $question);
586
}
587
588
/**
589
 * @param string $message
590
 * @param string[] $availableChoices
591
 * @param string|null $default
592
 * @param bool|false $multiselect
593
 * @return array
594
 * @codeCoverageIgnore
595
 */
596
function askChoice($message, array $availableChoices, $default = null, $multiselect = false)
597
{
598
    Context::required(__FUNCTION__);
599
600
    if (empty($availableChoices)) {
601
        throw new \InvalidArgumentException('Available choices should not be empty');
602
    }
603
604
    if ($default !== null && !array_key_exists($default, $availableChoices)) {
605
        throw new \InvalidArgumentException('Default choice is not available');
606
    }
607
608
    if (isQuiet()) {
609
        if ($default === null) {
610
            $default = key($availableChoices);
611
        }
612
        return [$default => $availableChoices[$default]];
613
    }
614
615
    $helper = Deployer::get()->getHelper('question');
616
617
    $message = "<question>$message" . (($default === null) ? "" : " [$default]") . "</question> ";
618
619
    $question = new ChoiceQuestion($message, $availableChoices, $default);
620
    $question->setMultiselect($multiselect);
621
622
    return $helper->ask(input(), output(), $question);
623
}
624
625
/**
626
 * @param string $message
627
 * @param bool $default
628
 * @return bool
629
 * @codeCoverageIgnore
630
 */
631
function askConfirmation($message, $default = false)
632
{
633
    Context::required(__FUNCTION__);
634
635
    if (isQuiet()) {
636
        return $default;
637
    }
638
639
    $helper = Deployer::get()->getHelper('question');
640
641
    $yesOrNo = $default ? 'Y/n' : 'y/N';
642
    $message = "<question>$message [$yesOrNo]</question> ";
643
644
    $question = new ConfirmationQuestion($message, $default);
645
646
    return $helper->ask(input(), output(), $question);
647
}
648
649
/**
650
 * @param string $message
651
 * @return string
652
 * @codeCoverageIgnore
653
 */
654
function askHiddenResponse($message)
655
{
656
    Context::required(__FUNCTION__);
657
658
    if (isQuiet()) {
659
        return '';
660
    }
661
662
    $helper = Deployer::get()->getHelper('question');
663
664
    $message = "<question>$message</question> ";
665
666
    $question = new Question($message);
667
    $question->setHidden(true);
668
    $question->setHiddenFallback(false);
669
670
    return $helper->ask(input(), output(), $question);
671
}
672
673
/**
674
 * @return InputInterface
675
 */
676
function input()
677
{
678 8
    return Context::get()->getInput();
679
}
680
681
682
/**
683
 * @return OutputInterface
684
 */
685
function output()
686
{
687 14
    return Context::get()->getOutput();
688
}
689
690
/**
691
 * @return bool
692
 */
693
function isQuiet()
694
{
695 3
    return OutputInterface::VERBOSITY_QUIET === output()->getVerbosity();
696
}
697
698
699
/**
700
 * @return bool
701
 */
702
function isVerbose()
703
{
704 1
    return OutputInterface::VERBOSITY_VERBOSE <= output()->getVerbosity();
705
}
706
707
708
/**
709
 * @return bool
710
 */
711
function isVeryVerbose()
712
{
713
    return OutputInterface::VERBOSITY_VERY_VERBOSE <= output()->getVerbosity();
714
}
715
716
717
/**
718
 * @return bool
719
 */
720
function isDebug()
721
{
722
    return OutputInterface::VERBOSITY_DEBUG <= output()->getVerbosity();
723
}
724
725
/**
726
 * Check if command exists
727
 *
728
 * @param string $command
729
 * @return bool
730
 */
731
function commandExist($command)
732
{
733 3
    return test("hash $command 2>/dev/null");
734
}
735
736
function commandSupportsOption($command, $option)
737
{
738 6
    return test("[[ $(man $command 2>&1 || $command -h 2>&1 || $command --help 2>&1) =~ '$option' ]]");
739
}
740
741
/**
742
 * Parse set values.
743
 *
744
 * @param string $value
745
 * @return string
746
 */
747
function parse($value)
748
{
749 14
    return Context::get()->getConfig()->parse($value);
750
}
751
752
function locateBinaryPath($name)
753
{
754 3
    $nameEscaped = escapeshellarg($name);
755
756
    // Try `command`, should cover all Bourne-like shells
757
    // Try `which`, should cover most other cases
758
    // Fallback to `type` command, if the rest fails
759 3
    $path = run("command -v $nameEscaped || which $nameEscaped || type -p $nameEscaped");
760 3
    if ($path) {
761
        // Deal with issue when `type -p` outputs something like `type -ap` in some implementations
762 3
        return trim(str_replace("$name is", "", $path));
763
    }
764
765
    throw new \RuntimeException("Can't locate [$nameEscaped] - neither of [command|which|type] commands are available");
766
}
767