CommitMessage::getBodyLines()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 1
cts 1
cp 1
rs 10
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
/**
4
 * This file is part of SebastianFeldmann\Git.
5
 *
6
 * (c) Sebastian Feldmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace SebastianFeldmann\Git;
13
14
use RuntimeException;
15
16
/**
17
 * Class CommitMessage
18
 *
19
 * @package SebastianFeldmann\Git
20
 * @author  Sebastian Feldmann <[email protected]>
21
 * @link    https://github.com/sebastianfeldmann/git
22
 * @since   Class available since Release 0.9.0
23
 */
24
class CommitMessage
25
{
26
    /**
27
     * Commit Message content
28
     *
29
     * This includes lines that are comments.
30
     *
31
     * @var string
32
     */
33
    private $rawContent;
34
35
    /**
36
     * Content split lines
37
     *
38
     * This includes lines that are comments.
39
     *
40
     * @var string[]
41
     */
42
    private $rawLines;
43
44
    /**
45
     * Amount of lines
46
     *
47
     * This includes lines that are comments
48
     *
49
     * @var int
50
     */
51
    private $rawLineCount;
52
53
    /**
54
     * The comment character
55
     *
56
     * @var string
57
     */
58
    private $commentCharacter;
59
60
    /**
61
     * All non comment lines
62
     *
63
     * @var string[]
64
     */
65
    private $contentLines;
66
67
    /**
68
     * Get the number of lines
69
     *
70
     * This excludes lines which are comments.
71
     *
72
     * @var int
73
     */
74
    private $contentLineCount;
75
76
    /**
77
     * Commit Message content
78
     *
79
     * This excludes lines that are comments.
80
     *
81
     * @var string
82
     */
83
    private $content;
84
85
    /**
86
     * CommitMessage constructor
87
     *
88
     * @param string $content
89 26
     * @param string $commentCharacter
90
     */
91 26
    public function __construct(string $content, string $commentCharacter = '#')
92 26
    {
93 26
        $this->rawContent       = $content;
94 26
        $this->rawLines         = empty($content) ? [] : preg_split("/\\r\\n|\\r|\\n/", $content);
0 ignored issues
show
Documentation Bug introduced by
It seems like empty($content) ? array(...\r\n|\r|\n/', $content) can also be of type false. However, the property $rawLines is declared as type string[]. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
95 26
        $this->rawLineCount     = count($this->rawLines);
0 ignored issues
show
Bug introduced by
It seems like $this->rawLines can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        $this->rawLineCount     = count(/** @scrutinizer ignore-type */ $this->rawLines);
Loading history...
96 26
        $this->commentCharacter = $commentCharacter;
97 26
        $this->contentLines     = $this->getContentLines($this->rawLines, $commentCharacter);
0 ignored issues
show
Bug introduced by
It seems like $this->rawLines can also be of type false; however, parameter $rawLines of SebastianFeldmann\Git\Co...sage::getContentLines() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
        $this->contentLines     = $this->getContentLines(/** @scrutinizer ignore-type */ $this->rawLines, $commentCharacter);
Loading history...
98 26
        $this->contentLineCount = count($this->contentLines);
99
        $this->content          = implode(PHP_EOL, $this->contentLines);
100
    }
101
102
    /**
103
     * Is message empty.
104
     *
105 2
     * @return bool
106
     */
107 2
    public function isEmpty(): bool
108
    {
109
        return empty($this->content);
110
    }
111
112
113
    /**
114
     * Get commit message content
115
     *
116
     * This excludes lines that are comments.
117
     *
118 3
     * @return string
119
     */
120 3
    public function getContent(): string
121
    {
122
        return $this->content;
123
    }
124
125
    /**
126
     * Get complete commit message content
127
     *
128
     * This includes lines that are comments.
129
     *
130 1
     * @return string
131
     */
132 1
    public function getRawContent(): string
133
    {
134
        return $this->rawContent;
135
    }
136
137
    /**
138
     * Return all lines
139
     *
140
     * This includes lines that are comments.
141
     *
142 2
     * @return array
143
     */
144 2
    public function getLines(): array
145
    {
146
        return $this->rawLines;
147
    }
148
149
    /**
150
     * Return line count
151
     *
152
     * This includes lines that are comments.
153
     *
154 3
     * @return int
155
     */
156 3
    public function getLineCount(): int
157
    {
158
        return $this->rawLineCount;
159
    }
160
161
    /**
162
     * Return content line count
163
     *
164
     * This doesn't includes lines that are comments.
165
     *
166 2
     * @return int
167
     */
168 2
    public function getContentLineCount(): int
169
    {
170
        return $this->contentLineCount;
171
    }
172
173
    /**
174
     * Get a specific line
175
     *
176
     * @param  int $index
177 2
     * @return string
178
     */
179 2
    public function getLine(int $index): string
180
    {
181
        return $this->rawLines[$index] ?? '';
182
    }
183
184
    /**
185
     * Get a specific content line
186
     *
187
     * @param  int $index
188 1
     * @return string
189
     */
190 1
    public function getContentLine(int $index): string
191
    {
192
        return $this->contentLines[$index] ?? '';
193
    }
194
195
    /**
196
     * Return first line
197
     *
198 4
     * @return string
199
     */
200 4
    public function getSubject(): string
201
    {
202
        return $this->contentLines[0] ?? '';
203
    }
204
205
    /**
206
     * Return content from line nr. 3 to the last line
207
     *
208 3
     * @return string
209
     */
210 3
    public function getBody(): string
211
    {
212
        return implode(PHP_EOL, $this->getBodyLines());
213
    }
214
215
    /**
216
     * Return lines from line nr. 3 to the last line
217
     *
218 5
     * @return array
219
     */
220 5
    public function getBodyLines(): array
221
    {
222
        return $this->contentLineCount < 3 ? [] : array_slice($this->contentLines, 2);
223
    }
224
225
    /**
226
     * Get the comment character
227
     *
228
     * Comment character defaults to '#'.
229
     *
230 1
     * @return string
231
     */
232 1
    public function getCommentCharacter(): string
233
    {
234
        return $this->commentCharacter;
235
    }
236
237
    /**
238
     * Get the lines that are not comments
239
     *
240
     * @param  array  $rawLines
241
     * @param  string $commentCharacter
242 26
     * @return string[]
243
     */
244 26
    private function getContentLines(array $rawLines, string $commentCharacter): array
245
    {
246 26
        $lines = [];
247
248 23
        foreach ($rawLines as $line) {
249
            // if we handle a comment line
250 13
            if (isset($line[0]) && $line[0] === $commentCharacter) {
251 1
                // check if we should ignore all following lines
252
                if (strpos($line, '------------------------ >8 ------------------------') !== false) {
253
                    break;
254 13
                }
255
                // or only the current one
256 22
                continue;
257
            }
258
            $lines[] = $line;
259 26
        }
260
261
        return $lines;
262
    }
263
264
    /**
265
     * Create CommitMessage from file
266
     *
267
     * @param  string $path
268
     * @param  string $commentCharacter
269 4
     * @return \SebastianFeldmann\Git\CommitMessage
270
     */
271 4
    public static function createFromFile(string $path, $commentCharacter = '#'): CommitMessage
272 2
    {
273
        if (!file_exists($path)) {
274
            throw new RuntimeException('Commit message file not found');
275 2
        }
276
277
        return new CommitMessage(file_get_contents($path), $commentCharacter);
278
    }
279
}
280