Completed
Push — develop ( 61d4f1...4b8b90 )
by
unknown
9s
created

Status   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 82.61%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 5
dl 0
loc 169
ccs 38
cts 46
cp 0.8261
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A get() 0 4 1
A createFromCommand() 0 6 1
A all() 0 4 1
A untracked() 0 4 1
A modified() 0 4 1
A added() 0 4 1
A deleted() 0 4 1
A renamed() 0 4 1
A copied() 0 4 1
A parseOutputLines() 0 11 6
A splitStatusLine() 0 6 1
A filterByType() 0 15 3
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\Status;
21
22
use \GitElephant\Command\MainCommand;
23
use \GitElephant\Repository;
24
use \PhpCollection\Sequence;
25
26
/**
27
 * Class Status
28
 *
29
 * @package GitElephant\Status
30
 */
31
class Status
32
{
33
    /**
34
     * @var \GitElephant\Repository
35
     */
36
    private $repository;
37
38
    /**
39
     * @var array
40
     */
41
    protected $files;
42
43
    /**
44
     * @param Repository $repository
45
     *
46
     * @throws \RuntimeException
47
     * @throws \Symfony\Component\Process\Exception\RuntimeException
48
     */
49 9
    private function __construct(Repository $repository)
50
    {
51 9
        $this->files = [];
52 9
        $this->repository = $repository;
53 9
        $this->createFromCommand();
54 9
    }
55
56
    /**
57
     * @param Repository $repository
58
     *
59
     * @return \GitElephant\Status\Status
60
     */
61 9
    public static function get(Repository $repository)
62
    {
63 9
        return new static($repository);
64
    }
65
66
    /**
67
     * create from git command
68
     */
69 9
    private function createFromCommand()
70
    {
71 9
        $command = MainCommand::getInstance($this->repository)->status(true);
72 9
        $lines = $this->repository->getCaller()->execute($command)->getOutputLines(true);
73 9
        $this->parseOutputLines($lines);
74 9
    }
75
76
    /**
77
     * all files
78
     *
79
     * @return Sequence
80
     */
81
    public function all()
82
    {
83
        return new Sequence($this->files);
84
    }
85
86
    /**
87
     * untracked files
88
     *
89
     * @return Sequence
90
     */
91 2
    public function untracked()
92
    {
93 2
        return $this->filterByType(StatusFile::UNTRACKED);
94
    }
95
96
    /**
97
     * modified files
98
     *
99
     * @return Sequence
100
     */
101 2
    public function modified()
102
    {
103 2
        return $this->filterByType(StatusFile::MODIFIED);
104
    }
105
106
    /**
107
     * added files
108
     *
109
     * @return Sequence
110
     */
111 4
    public function added()
112
    {
113 4
        return $this->filterByType(StatusFile::ADDED);
114
    }
115
116
    /**
117
     * deleted files
118
     *
119
     * @return Sequence
120
     */
121 2
    public function deleted()
122
    {
123 2
        return $this->filterByType(StatusFile::DELETED);
124
    }
125
126
    /**
127
     * renamed files
128
     *
129
     * @return Sequence
130
     */
131 1
    public function renamed()
132
    {
133 1
        return $this->filterByType(StatusFile::RENAMED);
134
    }
135
136
    /**
137
     * copied files
138
     *
139
     * @return Sequence
140
     */
141
    public function copied()
142
    {
143
        return $this->filterByType(StatusFile::COPIED);
144
    }
145
146
    /**
147
     * create objects from command output
148
     * https://www.kernel.org/pub/software/scm/git/docs/git-status.html in the output section
149
     *
150
     *
151
     * @param array $lines
152
     */
153 9
    private function parseOutputLines(array $lines)
154
    {
155 9
        foreach ($lines as $line) {
156 8
            preg_match('/([MADRCU\? ])?([MADRCU\? ])?\ "?(\S+)"? ?( -> )?(\S+)?/', $line, $matches);
157 8
            $x = isset($matches[1]) ? $matches[1] : null;
158 8
            $y = isset($matches[2]) ? $matches[2] : null;
159 8
            $file = isset($matches[3]) ? $matches[3] : null;
160 8
            $renamedFile = isset($matches[4]) ? $matches[4] : null;
161 8
            $this->files[] = StatusFile::create($x, $y, $file, $renamedFile);
162
        }
163 9
    }
164
165
    /**
166
     * @param string $line
167
     *
168
     * @return mixed
169
     */
170
    protected function splitStatusLine(string $line)
171
    {
172
        preg_match('/([MADRCU\?])?([MADRCU\?])?\ "?(\S+)"? ?( -> )?(\S+)?/', $line, $matches);
173
174
        return $matches;
175
    }
176
177
    /**
178
     * filter files status in working tree and in index status
179
     *
180
     * @param string $type
181
     *
182
     * @return Sequence
183
     */
184 5
    protected function filterByType(string $type)
185
    {
186 5
        if (!$this->files) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->files of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
187
            return new Sequence();
188
        }
189
190 5
        return new Sequence(
191 5
            array_filter(
192 5
                $this->files,
193
                function (StatusFile $statusFile) use ($type) {
194 5
                    return $type === $statusFile->getWorkingTreeStatus() || $type === $statusFile->getIndexStatus();
195 5
                }
196
            )
197
        );
198
    }
199
}
200