Completed
Push — develop ( 5247fd...3c6b2e )
by
unknown
9s
created

Branch::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

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