xref: /PHP-8.4/benchmark/shared.php (revision afbc71d8)
1<?php
2
3class ProcessResult {
4    public $stdout;
5    public $stderr;
6}
7
8function runCommand(array $args, ?string $cwd = null): ProcessResult {
9    $cmd = implode(' ', array_map('escapeshellarg', $args));
10    $pipes = null;
11    $result = new ProcessResult();
12    $descriptorSpec = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
13    fwrite(STDOUT, "> $cmd\n");
14    $processHandle = proc_open($cmd, $descriptorSpec, $pipes, $cwd ?? getcwd(), null);
15
16    $stdin = $pipes[0];
17    $stdout = $pipes[1];
18    $stderr = $pipes[2];
19
20    fclose($stdin);
21
22    stream_set_blocking($stdout, false);
23    stream_set_blocking($stderr, false);
24
25    $stdoutEof = false;
26    $stderrEof = false;
27
28    do {
29        $read = [$stdout, $stderr];
30        $write = null;
31        $except = null;
32
33        stream_select($read, $write, $except, 1, 0);
34
35        foreach ($read as $stream) {
36            $chunk = fgets($stream);
37            if ($stream === $stdout) {
38                $result->stdout .= $chunk;
39            } elseif ($stream === $stderr) {
40                $result->stderr .= $chunk;
41            }
42        }
43
44        $stdoutEof = $stdoutEof || feof($stdout);
45        $stderrEof = $stderrEof || feof($stderr);
46    } while(!$stdoutEof || !$stderrEof);
47
48    fclose($stdout);
49    fclose($stderr);
50
51    $statusCode = proc_close($processHandle);
52    if ($statusCode !== 0) {
53        fwrite(STDOUT, $result->stdout);
54        fwrite(STDERR, $result->stderr);
55        fwrite(STDERR, 'Exited with status code ' . $statusCode . "\n");
56        exit($statusCode);
57    }
58
59    return $result;
60}
61
62function cloneRepo(string $path, string $url) {
63    if (is_dir($path)) {
64        return;
65    }
66    $dir = dirname($path);
67    $repo = basename($path);
68    if (!is_dir($dir)) {
69        mkdir($dir, 0755, true);
70    }
71    runCommand(['git', 'clone', '-q', '--end-of-options', $url, $repo], dirname($path));
72}
73