Completed
Push — develop ( 5f7df1...9cb564 )
by Matteo
10s
created

Branch   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 77.33%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 23
c 4
b 0
f 0
lcom 1
cbo 5
dl 0
loc 284
ccs 58
cts 75
cp 0.7733
rs 10

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __toString() 0 4 1
A setName() 0 4 1
A getName() 0 4 1
A setSha() 0 4 1
A getSha() 0 4 1
A setCurrent() 0 4 1
A getCurrent() 0 4 1
A setComment() 0 4 1
A getComment() 0 4 1
A setFullRef() 0 4 1
A getFullRef() 0 4 1
A create() 0 6 1
A createFromOutputLine() 0 8 1
A checkout() 0 11 2
A __construct() 0 7 1
A createFromCommand() 0 14 3
A parseOutputLine() 0 13 2
A getMatches() 0 10 2
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 Object 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, $name, $startPoint = null)
82
    {
83 33
        $repository->getCaller()->execute(BranchCommand::getInstance($repository)->create($name, $startPoint));
84
85 33
        return new self($repository, $name);
86
    }
87
88
    /**
89
     * static generator to generate a single commit from output of command.show service
90
     *
91
     * @param \GitElephant\Repository $repository repository
92
     * @param string                  $outputLine output line
93
     *
94
     * @throws \InvalidArgumentException
95
     * @return Branch
96
     */
97 13
    public static function createFromOutputLine(Repository $repository, $outputLine)
98
    {
99 13
        $matches = static::getMatches($outputLine);
100 13
        $branch = new self($repository, $matches[1]);
101 13
        $branch->parseOutputLine($outputLine);
102
103 13
        return $branch;
104
    }
105
106
    /**
107
     * @param \GitElephant\Repository $repository repository instance
108
     * @param string|TreeishInterface $name       branch name
109
     * @param bool                    $create     like checkout -b, create a branch and check it out
110
     *
111
     * @throws \RuntimeException
112
     * @throws \Symfony\Component\Process\Exception\RuntimeException
113
     * @return Branch
114
     */
115 2
    public static function checkout(Repository $repository, $name, $create = false)
116
    {
117 2
        if ($create) {
118
            $branch = self::create($repository, $name);
0 ignored issues
show
Bug introduced by
It seems like $name defined by parameter $name on line 115 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...
119
        } else {
120 2
            $branch = new self($repository, $name);
0 ignored issues
show
Bug introduced by
It seems like $name defined by parameter $name on line 115 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...
121
        }
122 1
        $repository->checkout($branch);
123
124 1
        return $branch;
125
    }
126
127
    /**
128
     * Class constructor
129
     *
130
     * @param \GitElephant\Repository $repository repository instance
131
     * @param string                  $name       branch name
132
     *
133
     * @throws \RuntimeException
134
     * @throws \InvalidArgumentException
135
     * @throws \GitElephant\Exception\InvalidBranchNameException
136
     * @throws \Symfony\Component\Process\Exception\RuntimeException
137
     */
138 42
    public function __construct(Repository $repository, $name)
139
    {
140 42
        $this->repository = $repository;
141 42
        $this->name = trim($name);
142 42
        $this->fullRef = 'refs/heads/'.$name;
143 42
        $this->createFromCommand();
144 42
    }
145
146
    /**
147
     * get the branch properties from command
148
     *
149
     * @throws \InvalidArgumentException
150
     */
151 42
    private function createFromCommand()
152
    {
153 42
        $command = BranchCommand::getInstance($this->getRepository())->listBranches();
154 42
        $outputLines = $this->repository->getCaller()->execute($command)->getOutputLines(true);
155 42
        foreach ($outputLines as $outputLine) {
156 42
            $matches = static::getMatches($outputLine);
157 42
            if ($this->name === $matches[1]) {
158 42
                $this->parseOutputLine($outputLine);
159
160 42
                return;
161
            }
162 32
        }
163 1
        throw new InvalidBranchNameException(sprintf('The %s branch doesn\'t exists', $this->name));
164
    }
165
166
    /**
167
     * parse an output line from the BranchCommand::singleInfo command
168
     *
169
     * @param string $branchString an output line for a branch
170
     * @throws \InvalidArgumentException
171
     */
172 42
    public function parseOutputLine($branchString)
173
    {
174 42
        if (preg_match('/^\* (.*)/', $branchString, $matches)) {
175 15
            $this->current = true;
176 15
            $branchString = substr($branchString, 2);
177 15
        } else {
178 33
            $branchString = trim($branchString);
179
        }
180 42
        $matches = static::getMatches($branchString);
181 42
        $this->name = $matches[1];
182 42
        $this->sha = $matches[2];
183 42
        $this->comment = $matches[3];
184 42
    }
185
186
    /**
187
     * get the matches from an output line
188
     *
189
     * @param string $branchString branch line output
190
     *
191
     * @throws \InvalidArgumentException
192
     * @return array
193
     */
194 45
    public static function getMatches($branchString)
195
    {
196 45
        $matches = array();
197 45
        preg_match('/^\*?\ *?(\S+)\ +(\S{40})\ +(.+)$/', trim($branchString), $matches);
198 45
        if (!count($matches)) {
199 2
            throw new \InvalidArgumentException(sprintf('the branch string is not valid: %s', $branchString));
200
        }
201
202 43
        return array_map('trim', $matches);
203
    }
204
205
    /**
206
     * toString magic method
207
     *
208
     * @return string the sha
209
     */
210 4
    public function __toString()
211
    {
212 4
        return $this->getSha();
213
    }
214
215
    /**
216
     * name setter
217
     *
218
     * @param string $name the branch name
219
     */
220
    public function setName($name)
221
    {
222
        $this->name = $name;
223
    }
224
225
    /**
226
     * name setter
227
     *
228
     * @return string
229
     */
230 14
    public function getName()
231
    {
232 14
        return $this->name;
233
    }
234
235
    /**
236
     * sha setter
237
     *
238
     * @param string $sha the sha of the branch
239
     */
240
    public function setSha($sha)
241
    {
242
        $this->sha = $sha;
243
    }
244
245
    /**
246
     * sha getter
247
     *
248
     * @return string
249
     */
250 9
    public function getSha()
251
    {
252 9
        return $this->sha;
253
    }
254
255
    /**
256
     * current setter
257
     *
258
     * @param bool $current whether if the branch is the current or not
259
     */
260
    public function setCurrent($current)
261
    {
262
        $this->current = $current;
263
    }
264
265
    /**
266
     * current getter
267
     *
268
     * @return bool
269
     */
270 5
    public function getCurrent()
271
    {
272 5
        return $this->current;
273
    }
274
275
    /**
276
     * comment setter
277
     *
278
     * @param string $comment the branch comment
279
     */
280
    public function setComment($comment)
281
    {
282
        $this->comment = $comment;
283
    }
284
285
    /**
286
     * comment getter
287
     *
288
     * @return string
289
     */
290 1
    public function getComment()
291
    {
292 1
        return $this->comment;
293
    }
294
295
    /**
296
     * fullref setter
297
     *
298
     * @param string $fullRef full git reference of the branch
299
     */
300
    public function setFullRef($fullRef)
301
    {
302
        $this->fullRef = $fullRef;
303
    }
304
305
    /**
306
     * fullRef getter
307
     *
308
     * @return string
309
     */
310 2
    public function getFullRef()
311
    {
312 2
        return $this->fullRef;
313
    }
314
}
315