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 ( 26c340...9e24cf )
by Anton
02:30
created

Parser::acceptEmptyLine()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 0
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 5
rs 9.5555
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\Support\Changelog;
9
10
class Parser
11
{
12
    /**
13
     * @var string[]
14
     */
15
    private $tokens;
16
17
    /**
18
     * @var string[]
19
     */
20
    private $span;
21
22
    /**
23
     * @var int
24
     */
25
    private $lineNumber = 0;
26
27
    /**
28
     * @var bool
29
     */
30
    private $strict;
31
32 2
    public function __construct(string $changelog, bool $strict = true)
33
    {
34 2
        $this->tokens = preg_split("/\n/", $changelog);
35 2
        $this->strict = $strict;
36 2
    }
37
38 2
    private function current(): string
39
    {
40 2
        if (count($this->tokens) === 0) {
41 1
            return "";
42
        }
43 2
        return $this->tokens[0];
44
    }
45
46 2
    private function next(): string
47
    {
48 2
        if (count($this->tokens) === 0) {
49
            throw $this->error('Unexpected end of file');
50
        }
51
52 2
        $n = ++$this->lineNumber;
53 2
        $line = array_shift($this->tokens);
54
55 2
        $this->span[] = "    {$n}: $line";
56
57 2
        if (count($this->span) > 4) {
58 2
            array_shift($this->span);
59
        }
60
61 2
        return $line;
62
    }
63
64 2
    private function acceptEmptyLine()
65
    {
66 2
        if ($this->strict) {
67 1
            if ("" !== $this->next()) {
68 1
                throw $this->error("Expected an empty line");
69
            }
70
        } else {
71 1
            while (preg_match('/^\s*$/', $this->current()) && count($this->tokens) > 0) {
72 1
                $this->next();
73
            }
74
        }
75 2
    }
76
77 2
    private function acceptEof()
78
    {
79 2
        if (count($this->tokens) !== 0) {
80
            $this->next();
81
            throw $this->error("Expected EOF");
82
        }
83 2
    }
84
85 2
    private function matchVersion($line, &$m = null)
86
    {
87 2
        return preg_match('/^\#\# \s ( v\d+\.\d+\.\d+(-[\d\w\.]+)? | master )$/x', $line, $m);
88
    }
89
90
    private function error($message): ParseException
91
    {
92
        $c = count($this->span) - 1;
93
        $this->span[$c] = preg_replace('/^\s{4}/', ' -> ', $this->span[$c]);
94
95
        if (count($this->tokens) > 0) {
96
            $this->next();
97
        }
98
99
        return new ParseException($message, join("\n", $this->span));
100
    }
101
102 2
    public function parse(): Changelog
103
    {
104 2
        $changelog = $this->parseTitle();
105
106 2
        $this->acceptEmptyLine();
107 2
        $this->acceptEmptyLine();
108
109 2
        while ($this->matchVersion($this->current())) {
110 2
            $version = $this->parseVersion();
111 2
            $changelog->addVersion($version);
112
        }
113
114 2
        $refs = $this->parseReferences();
115 2
        $changelog->setReferences($refs);
116
117 2
        $this->acceptEmptyLine();
118 2
        $this->acceptEof();
119
120 2
        return $changelog;
121
    }
122
123 2
    private function parseTitle(): Changelog
124
    {
125 2
        if (preg_match('/# (.+)/', $this->next(), $m)) {
126 2
            $c = new Changelog();
127 2
            $c->setTitle($m[1]);
128 2
            return $c;
129
        }
130
131
        throw $this->error("Expected title");
132
    }
133
134 2
    private function parseVersion(): Version
135
    {
136 2
        if ($this->matchVersion($this->next(), $m)) {
137 2
            $version = new Version();
138 2
            $version->setVersion($curr = $m[1]);
139
140 2
            $compareLink = $this->next();
141 2
            if (!preg_match('/^\[/', $compareLink)) {
142
                throw $this->error("Expected link to compare page with previous version");
143
            }
144
145 2
            $prev = 'v\d+\.\d+\.\d+(-[\d\w\.]+)?';
146
            $regexp = "/
147 2
                ^ \[($prev)\.\.\.$curr\]
148 2
                \(https\:\/\/github\.com\/deployphp\/deployer\/compare\/$prev\.\.\.$curr\) $
149 2
                /x";
150
151 2
            if (preg_match($regexp, $compareLink, $m)) {
152 2
                $version->setPrevious($m[1]);
153
            } else {
154
                throw $this->error("Error in compare link syntax");
155
            }
156
157 2
            $this->acceptEmptyLine();
158
159 2
            $sections = ['Added', 'Changed', 'Fixed', 'Removed'];
160 2
            $sectionsCount = count($sections);
161
162 2
            for ($i = 0; $i < $sectionsCount; $i++) {
163 2
                foreach ($sections as $key => $section) {
164 2
                    if (preg_match('/^\#\#\# \s ' . $section . ' $/x', $this->current())) {
165 2
                        $this->next();
166
167 2
                        $version->{"set$section"}($this->parseItems());
168 2
                        unset($sections[$key]);
169
170 2
                        $this->acceptEmptyLine();
171
172 2
                        break;
173
                    }
174
                }
175
            }
176
177 2
            $this->acceptEmptyLine();
178
179 2
            return $version;
180
        }
181
182
        throw $this->error("Expected version");
183
    }
184
185 2
    private function parseItems()
186
    {
187 2
        $items = [];
188 2
        while (preg_match('/^\- (.+) $/x', $this->current(), $m)) {
189 2
            $this->next();
190
191 2
            $item = new Item();
192 2
            $message = $m[1];
193 2
            $ref = '/\[ \#(\d+) \]/x';
194
195 2
            preg_match_all($ref, $message, $matches);
196 2
            foreach ($matches[1] as $m) {
197 2
                $item->addReference($m);
198
            }
199
200 2
            $message = trim(preg_replace($ref, '', $message));
201 2
            $item->setMessage($message);
202 2
            $items[] = $item;
203
        }
204 2
        return $items;
205
    }
206
207 2
    private function parseReferences()
208
    {
209 2
        $refs = [];
210 2
        while (preg_match('/^\[/', $this->current())) {
211 2
            if (preg_match('/^ \[\#(\d+)\]\: \s (https\:\/\/github\.com\/deployphp\/deployer\/(issues|pull)\/\d+)$/x', $this->next(), $m)) {
212 2
                $refs[$m[1]] = $m[2];
213
            } else {
214
                throw $this->error('Error parsing reference');
215
            }
216
        }
217 2
        return $refs;
218
    }
219
}
220