Test Setup Failed
Pull Request — master (#11)
by Benjamin
04:12
created

Cli::lint()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 15
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 30
rs 9.7666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bdelespierre\LaravelBladeLinter\Backend;
6
7
use Bdelespierre\LaravelBladeLinter\Backend;
8
use Bdelespierre\LaravelBladeLinter\ErrorRecord;
9
10
final class Cli implements Backend
11
{
12
    private const REGEX = '/ in Standard input code on line (\d+)[\s\r\n]*/';
13
14
    /**
15
     * @param \SplFileInfo $file
16
     * @param string $code
17
     * @return list<ErrorRecord>
0 ignored issues
show
Bug introduced by
The type Bdelespierre\LaravelBladeLinter\Backend\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
     */
19
    public function analyze(\SplFileInfo $file, string $code): array
20
    {
21
        $output = '';
22
        $message = '';
23
        $result = $this->lint($code, $output, $message);
24
25
        if (!$result) {
26
            $line = null;
27
            if (false !== preg_match(self::REGEX, trim($message), $matches)) {
28
                $line = isset($matches[1]) ? (int) $matches[1] : null;
29
                $message = preg_replace(self::REGEX, '', $message) ?? '';
30
            }
31
32
            return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array(new Bdelesp...>getPathname(), $line)) returns the type array<integer,Bdelespier...ladeLinter\ErrorRecord> which is incompatible with the documented return type Bdelespierre\LaravelBladeLinter\Backend\list.
Loading history...
33
                new ErrorRecord(
34
                    trim($message),
35
                    $file->getPathname(),
36
                    $line
37
                ),
38
            ];
39
        }
40
41
        return [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return array() returns the type array which is incompatible with the documented return type Bdelespierre\LaravelBladeLinter\Backend\list.
Loading history...
42
    }
43
44
    public static function name(): string
45
    {
46
        return 'cli';
47
    }
48
49
    private function lint(string $code, string &$stdout = "", string &$stderr = ""): bool
50
    {
51
        $descriptors = [
52
            0 => ["pipe", "r"], // read from stdin
53
            1 => ["pipe", "w"], // write to stdout
54
            2 => ["pipe", "w"], // write to stderr
55
        ];
56
57
        // open linter process (php -l)
58
        $process = proc_open('php -d display_errors=stderr -l', $descriptors, $pipes);
59
60
        if (!is_resource($process)) {
61
            throw new \RuntimeException("unable to open process 'php -l'");
62
        }
63
64
        fwrite($pipes[0], $code);
65
        fclose($pipes[0]);
66
67
        $stdout = stream_get_contents($pipes[1]) ?: '';
68
        fclose($pipes[1]);
69
70
        $stderr = stream_get_contents($pipes[2]) ?: '';
71
        fclose($pipes[2]);
72
73
        // it is important that you close any pipes before calling
74
        // proc_close in order to avoid a deadlock
75
        $retval = proc_close($process);
76
77
        // zero actually means "no error"
78
        return $retval === 0;
79
    }
80
}
81