Completed
Push — master ( c1a738...2c88a4 )
by
unknown
02:35 queued 01:13
created

Status::all()   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
/**
4
 * GitElephant - An abstraction layer for git written in PHP
5
 * Copyright (C) 2013  Matteo Giachino
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see [http://www.gnu.org/licenses/].
19
 */
20
21
namespace GitElephant\Status;
22
23
use GitElephant\Command\MainCommand;
24
use GitElephant\Repository;
25
use PhpCollection\Sequence;
26
27
/**
28
 * Class Status
29
 *
30
 * @package GitElephant\Status
31
 */
32
class Status
33
{
34
    /**
35
     * @var \GitElephant\Repository
36
     */
37
    private $repository;
38
39
    /**
40
     * @var array<StatusFile>
41
     */
42
    protected $files;
43
44
    /**
45
     * Private constructor in order to follow the singleton pattern
46
     *
47
     * @param Repository $repository
48
     *
49
     * @throws \RuntimeException
50
     * @throws \Symfony\Component\Process\Exception\RuntimeException
51
     */
52 10
    private function __construct(Repository $repository)
53
    {
54 10
        $this->files = [];
55 10
        $this->repository = $repository;
56 10
        $this->createFromCommand();
57 10
    }
58
59
    /**
60
     * @param Repository $repository
61
     *
62
     * @return \GitElephant\Status\Status
63
     */
64 10
    public static function get(Repository $repository)
65
    {
66 10
        return new static($repository);
67
    }
68
69
    /**
70
     * create from git command
71
     */
72 10
    private function createFromCommand(): void
73
    {
74 10
        $command = MainCommand::getInstance($this->repository)->status(true);
75 10
        $lines = $this->repository->getCaller()->execute($command)->getOutputLines(true);
76 10
        $this->parseOutputLines($lines);
77 10
    }
78
79
    /**
80
     * all files
81
     *
82
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
83
     */
84 1
    public function all(): \PhpCollection\Sequence
85
    {
86 1
        return new Sequence($this->files);
87
    }
88
89
    /**
90
     * untracked files
91
     *
92
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
93
     */
94 2
    public function untracked(): \PhpCollection\Sequence
95
    {
96 2
        return $this->filterByType(StatusFile::UNTRACKED);
97
    }
98
99
    /**
100
     * modified files
101
     *
102
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
103
     */
104 2
    public function modified(): \PhpCollection\Sequence
105
    {
106 2
        return $this->filterByType(StatusFile::MODIFIED);
107
    }
108
109
    /**
110
     * added files
111
     *
112
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
113
     */
114 4
    public function added(): \PhpCollection\Sequence
115
    {
116 4
        return $this->filterByType(StatusFile::ADDED);
117
    }
118
119
    /**
120
     * deleted files
121
     *
122
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
123
     */
124 2
    public function deleted(): \PhpCollection\Sequence
125
    {
126 2
        return $this->filterByType(StatusFile::DELETED);
127
    }
128
129
    /**
130
     * renamed files
131
     *
132
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
133
     */
134 1
    public function renamed(): \PhpCollection\Sequence
135
    {
136 1
        return $this->filterByType(StatusFile::RENAMED);
137
    }
138
139
    /**
140
     * copied files
141
     *
142
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
143
     */
144
    public function copied(): \PhpCollection\Sequence
145
    {
146
        return $this->filterByType(StatusFile::COPIED);
147
    }
148
149
    /**
150
     * create objects from command output
151
     * https://www.kernel.org/pub/software/scm/git/docs/git-status.html in the output section
152
     *
153
     *
154
     * @param array $lines
155
     */
156 10
    private function parseOutputLines(array $lines): void
157
    {
158 10
        foreach ($lines as $line) {
159 9
            preg_match('/([MADRCU\? ])?([MADRCU\? ])?\ "?(\S+)"? ?( -> )?(\S+)?/', $line, $matches);
160 9
            $x = isset($matches[1]) ? $matches[1] : null;
161 9
            $y = isset($matches[2]) ? $matches[2] : null;
162 9
            $file = isset($matches[3]) ? $matches[3] : null;
163 9
            $renamedFile = isset($matches[4]) ? $matches[4] : null;
164 9
            $this->files[] = StatusFile::create($x, $y, $file, $renamedFile);
165
        }
166 10
    }
167
168
    /**
169
     * @param string $line
170
     *
171
     * @return array<string>|null
172
     */
173
    protected function splitStatusLine(string $line)
174
    {
175
        preg_match('/([MADRCU\?])?([MADRCU\?])?\ "?(\S+)"? ?( -> )?(\S+)?/', $line, $matches);
176
177
        return $matches;
178
    }
179
180
    /**
181
     * filter files status in working tree and in index status
182
     *
183
     * @param string $type
184
     *
185
     * @return Sequence<StatusFile>
0 ignored issues
show
Documentation introduced by
The doc-type Sequence<StatusFile> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
186
     */
187 5
    protected function filterByType(string $type): \PhpCollection\Sequence
188
    {
189 5
        if (!$this->files) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->files of type GitElephant\Status\StatusFile[] 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...
190
            return new Sequence();
191
        }
192
193 5
        return new Sequence(
194 5
            array_filter(
195 5
                $this->files,
196
                function (StatusFile $statusFile) use ($type) {
197 5
                    return $type === $statusFile->getWorkingTreeStatus() || $type === $statusFile->getIndexStatus();
198 5
                }
199
            )
200
        );
201
    }
202
}
203