Completed
Push — develop ( b29d0d...9c2be0 )
by
unknown
16s queued 11s
created

Branch::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * GitElephant - An abstraction layer for git written in PHP
4
 * Copyright (C) 2013  Matteo Giachino
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see [http://www.gnu.org/licenses/].
18
 */
19
20
namespace GitElephant\Objects;
21
22
use GitElephant\Command\BranchCommand;
23
use GitElephant\Exception\InvalidBranchNameException;
24
use GitElephant\Repository;
25
26
/**
27
 * An object representing a git branch
28
 *
29
 * @author Matteo Giachino <[email protected]>
30
 */
31
class Branch extends NodeObject implements TreeishInterface
32
{
33
    /**
34
     * current checked out branch
35
     *
36
     * @var bool
37
     */
38
    private $current = false;
39
40
    /**
41
     * branch name
42
     *
43
     * @var string
44
     */
45
    private $name;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
46
47
    /**
48
     * sha
49
     *
50
     * @var string
51
     */
52
    private $sha;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
53
54
    /**
55
     * branch comment
56
     *
57
     * @var string
58
     */
59
    private $comment;
60
61
    /**
62
     * the full branch reference
63
     *
64
     * @var string
65
     */
66
    private $fullRef;
67
68
    /**
69
     * Creates a new branch on the repository and returns it
70
     *
71
     * @param \GitElephant\Repository $repository repository instance
72
     * @param string                  $name       branch name
73
     * @param string                  $startPoint branch to start from
74
     *
75
     * @throws \RuntimeException
76
     * @throws \Symfony\Component\Process\Exception\LogicException
77
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
78
     * @throws \Symfony\Component\Process\Exception\RuntimeException
79
     * @return \GitElephant\Objects\Branch
80
     */
81 33
    public static function create(Repository $repository, string $name, string $startPoint = null): \GitElephant\Objects\Branch
82
    {
83
        $repository
84 33
            ->getCaller()
85 33
            ->execute(BranchCommand::getInstance($repository)->create($name, $startPoint));
86
87 33
        return new self($repository, $name);
88
    }
89
90
    /**
91
     * static generator to generate a single commit from output of command.show service
92
     *
93
     * @param \GitElephant\Repository $repository repository
94
     * @param string                  $outputLine output line
95
     *
96
     * @throws \InvalidArgumentException
97
     * @return Branch
98
     */
99 13
    public static function createFromOutputLine(Repository $repository, string $outputLine): \GitElephant\Objects\Branch
100
    {
101 13
        $matches = static::getMatches($outputLine);
102 13
        $branch = new self($repository, $matches[1]);
103 13
        $branch->parseOutputLine($outputLine);
104
105 13
        return $branch;
106
    }
107
108
    /**
109
     * @param \GitElephant\Repository $repository repository instance
110
     * @param string|TreeishInterface $name       branch name
111
     * @param bool                    $create     like checkout -b, create a branch and check it out
112
     *
113
     * @throws \RuntimeException
114
     * @throws \Symfony\Component\Process\Exception\RuntimeException
115
     * @return Branch
116
     */
117 2
    public static function checkout(Repository $repository, $name, $create = false): \GitElephant\Objects\Branch
118
    {
119 2
        $branch = $create ? self::create($repository, $name) : new self($repository, $name);
0 ignored issues
show
Bug introduced by
It seems like $name defined by parameter $name on line 117 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Objects\Branch::create() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $name defined by parameter $name on line 117 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Objects\Branch::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
120
121 1
        $repository->checkout($branch);
122
123 1
        return $branch;
124
    }
125
126
    /**
127
     * Class constructor
128
     *
129
     * @param \GitElephant\Repository $repository repository instance
130
     * @param string                  $name       branch name
131
     *
132
     * @throws \RuntimeException
133
     * @throws \InvalidArgumentException
134
     * @throws \GitElephant\Exception\InvalidBranchNameException
135
     * @throws \Symfony\Component\Process\Exception\RuntimeException
136
     */
137 42
    public function __construct(Repository $repository, string $name)
138
    {
139 42
        $this->repository = $repository;
140 42
        $this->name = trim($name);
141 42
        $this->fullRef = 'refs/heads/' . $name;
142 42
        $this->createFromCommand();
143 42
    }
144
145
    /**
146
     * get the branch properties from command
147
     *
148
     * @throws \InvalidArgumentException
149
     */
150 42
    private function createFromCommand()
151
    {
152 42
        $command = BranchCommand::getInstance($this->getRepository())->listBranches();
153 42
        $outputLines = $this->repository->getCaller()->execute($command)->getOutputLines(true);
154 42
        foreach ($outputLines as $outputLine) {
155 42
            $matches = static::getMatches($outputLine);
156
157 42
            if ($this->name === $matches[1]) {
158 42
                $this->parseOutputLine($outputLine);
159
160 42
                return;
161
            }
162
        }
163
164 1
        throw new InvalidBranchNameException(sprintf('The %s branch doesn\'t exists', $this->name));
165
    }
166
167
    /**
168
     * parse an output line from the BranchCommand::singleInfo command
169
     *
170
     * @param string $branchString an output line for a branch
171
     *
172
     * @throws \InvalidArgumentException
173
     */
174 42
    public function parseOutputLine(string $branchString): void
175
    {
176 42
        if (preg_match('/^\* (.*)/', $branchString, $matches)) {
177 15
            $this->current = true;
178 15
            $branchString = substr($branchString, 2);
179
        } else {
180 33
            $branchString = trim($branchString);
181
        }
182
183 42
        $matches = static::getMatches($branchString);
184 42
        $this->name = $matches[1];
185 42
        $this->sha = $matches[2];
186 42
        $this->comment = $matches[3];
187 42
    }
188
189
    /**
190
     * get the matches from an output line
191
     *
192
     * @param string $branchString branch line output
193
     *
194
     * @throws \InvalidArgumentException
195
     * @return array
196
     */
197 45
    public static function getMatches(string $branchString): array
198
    {
199 45
        $branchString = trim($branchString);
200
201
        $regexList = [
202 45
            '/^\*?\ *?(\S+)\ +(\S{40})\ +(.+)$/',
203
            '/^\*?\ *?\(.*(detached).*\)\ +(\S{40})\ +(.+)$/',
204
        ];
205
206 45
        $matches = [];
207 45
        while (empty($matches) and $regex = array_pop($regexList)) {
208 45
            preg_match($regex, trim($branchString), $matches);
209
        }
210
211 45
        if (empty($matches)) {
212 2
            throw new \InvalidArgumentException(sprintf('the branch string is not valid: %s', $branchString));
213
        }
214
215 43
        return array_map('trim', $matches);
216
    }
217
218
    /**
219
     * toString magic method
220
     *
221
     * @return string the sha
222
     */
223 4
    public function __toString(): string
224
    {
225 4
        return $this->getSha();
226
    }
227
228
    /**
229
     * name setter
230
     *
231
     * @param string $name the branch name
232
     */
233
    public function setName(string $name): void
234
    {
235
        $this->name = $name;
236
    }
237
238
    /**
239
     * name setter
240
     *
241
     * @return string
242
     */
243 14
    public function getName(): string
244
    {
245 14
        return $this->name;
246
    }
247
248
    /**
249
     * sha setter
250
     *
251
     * @param string $sha the sha of the branch
252
     */
253
    public function setSha(string $sha): void
254
    {
255
        $this->sha = $sha;
256
    }
257
258
    /**
259
     * sha getter
260
     *
261
     * @return string
262
     */
263 9
    public function getSha(): string
264
    {
265 9
        return $this->sha;
266
    }
267
268
    /**
269
     * current setter
270
     *
271
     * @param bool $current whether if the branch is the current or not
272
     */
273
    public function setCurrent(bool $current): void
274
    {
275
        $this->current = $current;
276
    }
277
278
    /**
279
     * current getter
280
     *
281
     * @return bool
282
     */
283 5
    public function getCurrent(): bool
284
    {
285 5
        return $this->current;
286
    }
287
288
    /**
289
     * comment setter
290
     *
291
     * @param string $comment the branch comment
292
     */
293
    public function setComment(string $comment): void
294
    {
295
        $this->comment = $comment;
296
    }
297
298
    /**
299
     * comment getter
300
     *
301
     * @return string
302
     */
303 1
    public function getComment(): string
304
    {
305 1
        return $this->comment;
306
    }
307
308
    /**
309
     * fullref setter
310
     *
311
     * @param string $fullRef full git reference of the branch
312
     */
313
    public function setFullRef(string $fullRef): void
314
    {
315
        $this->fullRef = $fullRef;
316
    }
317
318
    /**
319
     * fullRef getter
320
     *
321
     * @return string
322
     */
323 2
    public function getFullRef(): string
324
    {
325 2
        return $this->fullRef;
326
    }
327
}
328