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

Log   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 268
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 60.66%

Importance

Changes 0
Metric Value
wmc 24
lcom 1
cbo 5
dl 0
loc 268
ccs 37
cts 61
cp 0.6066
rs 10
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A createFromCommand() 0 12 1
A createFromOutputLines() 0 7 1
A __construct() 0 11 1
A parseOutputLines() 0 13 4
A toArray() 0 4 1
A first() 0 4 1
A last() 0 4 1
A index() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 4 2
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
A count() 0 4 1
A current() 0 4 1
A next() 0 4 1
A key() 0 4 1
A valid() 0 4 1
A rewind() 0 4 1
A setRepository() 0 4 1
A getRepository() 0 4 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\Objects;
22
23
use \GitElephant\Repository;
24
use \GitElephant\Command\LogCommand;
25
use \GitElephant\Utilities;
26
27
/**
28
 * Git log abstraction object
29
 *
30
 * @author Matteo Giachino <[email protected]>
31
 * @author Dhaval Patel <[email protected]>
32
 */
33
class Log implements \ArrayAccess, \Countable, \Iterator
34
{
35
    /**
36
     * @var \GitElephant\Repository
37
     */
38
    private $repository;
39
40
    /**
41
     * the commits related to this log
42
     *
43
     * @var array
44
     */
45
    private $commits = [];
46
47
    /**
48
     * the cursor position
49
     *
50
     * @var int
51
     */
52
    private $position = 0;
53
54
    /**
55
     * static method to generate standalone log
56
     *
57
     * @param \GitElephant\Repository $repository  repo
58
     * @param array                   $outputLines output lines from command.log
59
     *
60
     * @return \GitElephant\Objects\Log
61
     */
62 1
    public static function createFromOutputLines(Repository $repository, array $outputLines): \GitElephant\Objects\Log
63
    {
64 1
        $log = new self($repository);
65 1
        $log->parseOutputLines($outputLines);
66
67 1
        return $log;
68
    }
69
70
    /**
71
     * Class constructor
72
     *
73
     * @param Repository  $repository
74
     * @param string      $ref
75
     * @param string|null $path
76
     * @param int         $limit
77
     * @param int|null    $offset
78
     * @param bool        $firstParent
79
     */
80 19
    public function __construct(
81
        Repository $repository,
82
        $ref = 'HEAD',
83
        $path = null,
84
        int $limit = 15,
85
        int $offset = null,
86
        bool $firstParent = false
87
    ) {
88 19
        $this->repository = $repository;
89 19
        $this->createFromCommand($ref, $path, $limit, $offset, $firstParent);
90 19
    }
91
92
    /**
93
     * get the commit properties from command
94
     *
95
     * @param string  $ref         treeish reference
96
     * @param string  $path        path
97
     * @param int     $limit       limit
98
     * @param string  $offset      offset
99
     * @param boolean $firstParent first parent
100
     *
101
     * @throws \RuntimeException
102
     * @throws \Symfony\Component\Process\Exception\LogicException
103
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
104
     * @throws \Symfony\Component\Process\Exception\RuntimeException
105
     * @see ShowCommand::commitInfo
106
     */
107 19
    private function createFromCommand($ref, $path = null, int $limit = null, int $offset = null, bool $firstParent = false): void
108
    {
109 19
        $command = LogCommand::getInstance($this->getRepository())
110 19
            ->showLog($ref, $path, $limit, $offset, $firstParent);
111
112 19
        $outputLines = $this->getRepository()
113 19
            ->getCaller()
114 19
            ->execute($command)
115 19
            ->getOutputLines(true);
116
117 19
        $this->parseOutputLines($outputLines);
118 19
    }
119
120 19
    private function parseOutputLines(array $outputLines): void
121
    {
122 19
        $this->commits = [];
123 19
        $commits = Utilities::pregSplitFlatArray($outputLines, '/^commit (\w+)$/');
124
125 19
        foreach ($commits as $commitOutputLines) {
126 19
            if (is_string($commitOutputLines)) {
127
                $this->commits[] = Commit::createFromOutputLines($this->getRepository(), [$commitOutputLines]);
128 19
            } elseif (is_iterable($commitOutputLines)) {
129 19
                $this->commits[] = Commit::createFromOutputLines($this->getRepository(), $commitOutputLines);
130
            }
131
        }
132 19
    }
133
134
    /**
135
     * Get array representation
136
     *
137
     * @return array
138
     */
139 1
    public function toArray(): array
140
    {
141 1
        return $this->commits;
142
    }
143
144
    /**
145
     * Get the first commit
146
     *
147
     * @return Commit|null
148
     */
149
    public function first(): ?\GitElephant\Objects\Commit
150
    {
151
        return $this->offsetGet(0);
152
    }
153
154
    /**
155
     * Get the last commit
156
     *
157
     * @return Commit|null
158
     */
159 3
    public function last(): ?\GitElephant\Objects\Commit
160
    {
161 3
        return $this->offsetGet($this->count() - 1);
162
    }
163
164
    /**
165
     * Get commit at index
166
     *
167
     * @param int $index the commit index
168
     *
169
     * @return Commit|null
170
     */
171 1
    public function index(int $index): ?\GitElephant\Objects\Commit
172
    {
173 1
        return $this->offsetGet($index);
174
    }
175
176
    /**
177
     * ArrayAccess interface
178
     *
179
     * @param int $offset offset
180
     *
181
     * @return bool
182
     */
183
    public function offsetExists($offset): bool
184
    {
185
        return isset($this->commits[$offset]);
186
    }
187
188
    /**
189
     * ArrayAccess interface
190
     *
191
     * @param int $offset offset
192
     *
193
     * @return Commit|null
194
     */
195 14
    public function offsetGet($offset): ?\GitElephant\Objects\Commit
196
    {
197 14
        return isset($this->commits[$offset]) ? $this->commits[$offset] : null;
198
    }
199
200
    /**
201
     * ArrayAccess interface
202
     *
203
     * @param int   $offset offset
204
     * @param mixed $value  value
205
     *
206
     * @throws \RuntimeException
207
     */
208
    public function offsetSet($offset, $value)
209
    {
210
        throw new \RuntimeException('Can\'t set elements on logs');
211
    }
212
213
    /**
214
     * ArrayAccess interface
215
     *
216
     * @param int $offset offset
217
     *
218
     * @throws \RuntimeException
219
     */
220
    public function offsetUnset($offset)
221
    {
222
        throw new \RuntimeException('Can\'t unset elements on logs');
223
    }
224
225
    /**
226
     * Countable interface
227
     *
228
     * @return int
229
     */
230 8
    public function count(): int
231
    {
232 8
        return count($this->commits);
233
    }
234
235
    /**
236
     * Iterator interface
237
     *
238
     * @return Commit|null
239
     */
240
    public function current(): ?\GitElephant\Objects\Commit
241
    {
242
        return $this->offsetGet($this->position);
243
    }
244
245
    /**
246
     * Iterator interface
247
     */
248
    public function next(): void
249
    {
250
        ++$this->position;
251
    }
252
253
    /**
254
     * Iterator interface
255
     *
256
     * @return int
257
     */
258
    public function key(): int
259
    {
260
        return $this->position;
261
    }
262
263
    /**
264
     * Iterator interface
265
     *
266
     * @return bool
267
     */
268
    public function valid(): bool
269
    {
270
        return $this->offsetExists($this->position);
271
    }
272
273
    /**
274
     * Iterator interface
275
     */
276
    public function rewind(): void
277
    {
278
        $this->position = 0;
279
    }
280
281
    /**
282
     * Repository setter
283
     *
284
     * @param \GitElephant\Repository $repository the repository variable
285
     */
286
    public function setRepository(Repository $repository): void
287
    {
288
        $this->repository = $repository;
289
    }
290
291
    /**
292
     * Repository getter
293
     *
294
     * @return \GitElephant\Repository
295
     */
296 19
    public function getRepository(): \GitElephant\Repository
297
    {
298 19
        return $this->repository;
299
    }
300
}
301