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 ( c538d5...8bac07 )
by Anton
02:32
created

ParallelExecutor::persistHosts()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 16
ccs 0
cts 13
cp 0
crap 6
rs 9.7333
c 0
b 0
f 0
1
<?php declare(strict_types=1);
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\Executor;
9
10
use Deployer\Collection\PersistentCollection;
11
use Deployer\Configuration\Configuration;
12
use Deployer\Console\Application;
13
use Deployer\Deployer;
14
use Deployer\Exception\Exception;
15
use Deployer\Exception\GracefulShutdownException;
16
use Deployer\Host\Host;
17
use Deployer\Host\Localhost;
18
use Deployer\Host\Storage;
19
use Deployer\Component\Ssh\Client;
20
use Deployer\Task\Context;
21
use Deployer\Task\Task;
22
use Symfony\Component\Console\Input\InputInterface;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Process\Process;
25
26
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
27
28
function spinner($message = '')
29
{
30
    $frame = FRAMES[(int)(microtime(true) * 10) % count(FRAMES)];
31
    return "  $frame $message\r";
32
}
33
34
class ParallelExecutor
35
{
36
    private $input;
37
    private $output;
38
    private $messenger;
39
    private $console;
40
    private $client;
41
    private $config;
42
43
    public function __construct(
44
        InputInterface $input,
45
        OutputInterface $output,
46
        Messenger $messenger,
47
        Application $console,
48
        Client $client,
49
        Configuration $config
50
    )
51
    {
52
        $this->input = $input;
53
        $this->output = $output;
54
        $this->messenger = $messenger;
55
        $this->console = $console;
56
        $this->client = $client;
57
        $this->config = $config;
58
    }
59
60
    /**
61
     * @param Host[] $hosts
62
     */
63
    private function connect(array $hosts)
64
    {
65 View Code Duplication
        $callback = function (string $output) {
66
            $output = preg_replace('/\n$/', '', $output);
67
            if (strlen($output) !== 0) {
68
                $this->output->writeln($output);
69
            }
70
        };
71
72
        // Connect to each host sequentially, to prevent getting locked.
73
        foreach ($hosts as $host) {
74
            if ($host instanceof Localhost) {
75
                continue;
76
            }
77
            $process = $this->getProcess($host, new Task('connect'));
78
            $process->start();
79
80
            while ($process->isRunning()) {
81
                $this->gatherOutput([$process], $callback);
82
                $this->output->write(spinner(str_pad("connect {$host->tag()}", intval(getenv('COLUMNS')) - 1)));
83
                usleep(1000);
84
            }
85
        }
86
87
        // Clear spinner.
88
        $this->output->write(str_repeat(' ', intval(getenv('COLUMNS')) - 1) . "\r");
89
    }
90
91
    /**
92
     * @param Task[] $tasks
93
     * @param Host[] $hosts
94
     */
95
    public function run(array $tasks, array $hosts): int
96
    {
97
        $this->connect($hosts);
98
99
        $localhost = new Localhost();
0 ignored issues
show
Unused Code introduced by
$localhost is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
100
        $limit = (int)$this->input->getOption('limit') ?: count($hosts);
101
102
        foreach ($tasks as $task) {
103
            $this->messenger->startTask($task);
104
105
            if ($limit === 1 || count($hosts) === 1) {
106
                foreach ($hosts as $host) {
107
                    try {
108
                        Exception::setFilepath($task->getFilepath());
109
                        $host->getConfig()->load();
110
111
                        $task->run(new Context($host, $this->input, $this->output));
112
113
                        $host->getConfig()->save();
114
                    } catch (GracefulShutdownException $exception) {
115
                        $this->messenger->renderException($exception, $host);
116
                        return GracefulShutdownException::EXIT_CODE;
117
                    } catch (\Throwable $exception) {
118
                        $this->messenger->renderException($exception, $host);
119
                        return 1;
120
                    }
121
                }
122
            } else {
123
                foreach (array_chunk($hosts, $limit) as $chunk) {
124
                    $exitCode = $this->runTask($chunk, $task);
125
                    if ($exitCode !== 0) {
126
                        return $exitCode;
127
                    }
128
                }
129
            }
130
131
            $this->messenger->endTask($task);
132
        }
133
134
        return 0;
135
    }
136
137
    private function runTask(array $hosts, Task $task): int
138
    {
139
        $processes = [];
140
        foreach ($hosts as $host) {
141
            if ($task->shouldBePerformed($host)) {
142
                $processes[] = $this->getProcess($host, $task);
143
                if ($task->isOnce()) {
144
                    $task->setHasRun();
145
                }
146
            }
147
        }
148
149 View Code Duplication
        $callback = function (string $output) {
150
            $output = preg_replace('/\n$/', '', $output);
151
            if (strlen($output) !== 0) {
152
                $this->output->writeln($output);
153
            }
154
        };
155
156
        $this->startProcesses($processes);
157
158
        while ($this->areRunning($processes)) {
159
            $this->gatherOutput($processes, $callback);
160
            $this->output->write(spinner());
161
            usleep(1000);
162
        }
163
164
        // Clear spinner.
165
        $this->output->write("    \r");
166
167
        $this->gatherOutput($processes, $callback);
168
169
        return $this->gatherExitCodes($processes);
170
    }
171
172
    protected function getProcess(Host $host, Task $task): Process
173
    {
174
        $dep = PHP_BINARY . ' ' . DEPLOYER_BIN;
175
        $configDirectory = $host->get('config_directory');
176
        $decorated = $this->output->isDecorated() ? '--decorated' : '';
177
        $command = "$dep worker $task {$host->alias()} $configDirectory {$this->input} $decorated";
178
179
        if ($this->output->isDebug()) {
180
            $this->output->writeln("[{$host->tag()}] $command");
181
        }
182
183
        return Process::fromShellCommandline($command);
184
    }
185
186
    /**
187
     * Start all of the processes.
188
     *
189
     * @param Process[] $processes
190
     * @return void
191
     */
192
    protected function startProcesses(array $processes)
193
    {
194
        foreach ($processes as $process) {
195
            $process->start();
196
        }
197
    }
198
199
    /**
200
     * Determine if any of the processes are running.
201
     *
202
     * @param Process[] $processes
203
     * @return bool
204
     */
205
    protected function areRunning(array $processes): bool
206
    {
207
        foreach ($processes as $process) {
208
            if ($process->isRunning()) {
209
                return true;
210
            }
211
        }
212
213
        return false;
214
    }
215
216
    /**
217
     * Gather the output from all of the processes.
218
     *
219
     * @param Process[] $processes
220
     * @param callable $callback
221
     * @return void
222
     */
223
    protected function gatherOutput(array $processes, callable $callback)
224
    {
225
        foreach ($processes as $process) {
226
            $output = $process->getIncrementalOutput();
227
            if (strlen($output) !== 0) {
228
                $callback($output);
229
            }
230
231
            $errorOutput = $process->getIncrementalErrorOutput();
232
            if (strlen($errorOutput) !== 0) {
233
                $callback($errorOutput);
234
            }
235
        }
236
    }
237
238
    /**
239
     * Gather the cumulative exit code for the processes.
240
     */
241
    protected function gatherExitCodes(array $processes): int
242
    {
243
        foreach ($processes as $process) {
244
            if ($process->getExitCode() > 0) {
245
                return $process->getExitCode();
246
            }
247
        }
248
249
        return 0;
250
    }
251
}
252