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

Diff::rewind()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 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\Diff;
21
22
use \GitElephant\Utilities;
23
use \GitElephant\Repository;
24
use \GitElephant\Command\DiffTreeCommand;
25
use \GitElephant\Command\DiffCommand;
26
27
/**
28
 * Represent a collection of diffs between two trees
29
 *
30
 * @author Matteo Giachino <[email protected]>
31
 */
32
class Diff implements \ArrayAccess, \Countable, \Iterator
33
{
34
    /**
35
     * @var \GitElephant\Repository
36
     */
37
    private $repository;
38
39
    /**
40
     * the cursor position
41
     *
42
     * @var int
43
     */
44
    private $position;
45
46
    /**
47
     * DiffObject instances
48
     *
49
     * @var array
50
     */
51
    private $diffObjects;
52
53
    /**
54
     * static generator to generate a Diff object
55
     *
56
     * @param \GitElephant\Repository                 $repository repository
57
     * @param null|string|\GitElephant\Objects\Commit $commit1    first commit
58
     * @param null|string|\GitElephant\Objects\Commit $commit2    second commit
59
     * @param null|string                             $path       path to consider
60
     *
61
     * @throws \RuntimeException
62
     * @throws \InvalidArgumentException
63
     * @throws \Symfony\Component\Process\Exception\RuntimeException
64
     * @return Diff
65
     */
66 2
    public static function create(Repository $repository, $commit1 = null, $commit2 = null, $path = null)
67
    {
68 2
        $commit = new self($repository);
69 2
        $commit->createFromCommand($commit1, $commit2, $path);
0 ignored issues
show
Bug introduced by
It seems like $commit1 defined by parameter $commit1 on line 66 can also be of type object<GitElephant\Objects\Commit> or string; however, GitElephant\Objects\Diff\Diff::createFromCommand() does only seem to accept null, 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...
Bug introduced by
It seems like $commit2 defined by parameter $commit2 on line 66 can also be of type object<GitElephant\Objects\Commit> or string; however, GitElephant\Objects\Diff\Diff::createFromCommand() does only seem to accept null, 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...
Bug introduced by
It seems like $path defined by parameter $path on line 66 can also be of type string; however, GitElephant\Objects\Diff\Diff::createFromCommand() does only seem to accept null, 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...
70
71 2
        return $commit;
72
    }
73
74
    /**
75
     * Class constructor
76
     * bare Diff object
77
     *
78
     * @param \GitElephant\Repository $repository  repository instance
79
     * @param null                    $diffObjects diff objects
80
     */
81 2
    public function __construct(Repository $repository, $diffObjects = null)
82
    {
83 2
        $this->position = 0;
84 2
        $this->repository = $repository;
85 2
        $this->diffObjects = $diffObjects;
0 ignored issues
show
Documentation Bug introduced by
It seems like $diffObjects of type null is incompatible with the declared type array of property $diffObjects.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86 2
    }
87
88
    /**
89
     * get the commit properties from command
90
     *
91
     * @param null $commit1 commit 1
92
     * @param null $commit2 commit 2
93
     * @param null $path    path
94
     *
95
     * @throws \RuntimeException
96
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
97
     * @throws \Symfony\Component\Process\Exception\LogicException
98
     * @throws \InvalidArgumentException
99
     * @throws \Symfony\Component\Process\Exception\RuntimeException
100
     * @see ShowCommand::commitInfo
101
     */
102 2
    public function createFromCommand($commit1 = null, $commit2 = null, $path = null)
103
    {
104 2
        if (null === $commit1) {
105
            $commit1 = $this->getRepository()->getCommit();
106
        }
107 2
        if (is_string($commit1)) {
108
            $commit1 = $this->getRepository()->getCommit($commit1);
109
        }
110 2
        if ($commit2 === null) {
111 2
            if ($commit1->isRoot()) {
0 ignored issues
show
Bug introduced by
It seems like $commit1 is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
112
                $command = DiffTreeCommand::getInstance($this->repository)->rootDiff($commit1);
0 ignored issues
show
Bug introduced by
It seems like $commit1 defined by parameter $commit1 on line 102 can be null; however, GitElephant\Command\DiffTreeCommand::rootDiff() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
113
            } else {
114 2
                $command = DiffCommand::getInstance($this->repository)->diff($commit1);
0 ignored issues
show
Bug introduced by
It seems like $commit1 defined by parameter $commit1 on line 102 can be null; however, GitElephant\Command\DiffCommand::diff() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
115
            }
116 2
        } else {
117
            if (is_string($commit2)) {
118
                $commit2 = $this->getRepository()->getCommit($commit2);
119
            }
120
            $command = DiffCommand::getInstance($this->repository)->diff($commit1, $commit2, $path);
0 ignored issues
show
Bug introduced by
It seems like $commit1 defined by parameter $commit1 on line 102 can be null; however, GitElephant\Command\DiffCommand::diff() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
121
        }
122 2
        $outputLines = $this->getCaller()->execute($command)->getOutputLines();
123 2
        $this->parseOutputLines($outputLines);
124 2
    }
125
126
    /**
127
     * parse the output of a git command showing a commit
128
     *
129
     * @param array $outputLines output lines
130
     *
131
     * @throws \InvalidArgumentException
132
     */
133 2
    private function parseOutputLines($outputLines)
134
    {
135 2
        $this->diffObjects = array();
136 2
        $splitArray = Utilities::pregSplitArray($outputLines, '/^diff --git SRC\/(.*) DST\/(.*)$/');
137 2
        foreach ($splitArray as $diffObjectLines) {
138 2
            $this->diffObjects[] = new DiffObject($diffObjectLines);
139 2
        }
140 2
    }
141
142
    /**
143
     * @return \GitElephant\Command\Caller\Caller
144
     */
145 2
    private function getCaller()
146
    {
147 2
        return $this->getRepository()->getCaller();
148
    }
149
150
    /**
151
     * Repository setter
152
     *
153
     * @param \GitElephant\Repository $repository the repository variable
154
     */
155
    public function setRepository($repository)
156
    {
157
        $this->repository = $repository;
158
    }
159
160
    /**
161
     * Repository getter
162
     *
163
     * @return \GitElephant\Repository
164
     */
165 2
    public function getRepository()
166
    {
167 2
        return $this->repository;
168
    }
169
170
    /**
171
     * ArrayAccess interface
172
     *
173
     * @param int $offset offset
174
     *
175
     * @return bool
176
     */
177
    public function offsetExists($offset)
178
    {
179
        return isset($this->diffObjects[$offset]);
180
    }
181
182
    /**
183
     * ArrayAccess interface
184
     *
185
     * @param int $offset offset
186
     *
187
     * @return null|mixed
188
     */
189 1
    public function offsetGet($offset)
190
    {
191 1
        return isset($this->diffObjects[$offset]) ? $this->diffObjects[$offset] : null;
192
    }
193
194
    /**
195
     * ArrayAccess interface
196
     *
197
     * @param int   $offset offset
198
     * @param mixed $value  value
199
     */
200
    public function offsetSet($offset, $value)
201
    {
202
        if (is_null($offset)) {
203
            $this->diffObjects[] = $value;
204
        } else {
205
            $this->diffObjects[$offset] = $value;
206
        }
207
    }
208
209
    /**
210
     * ArrayAccess interface
211
     *
212
     * @param int $offset offset
213
     */
214
    public function offsetUnset($offset)
215
    {
216
        unset($this->diffObjects[$offset]);
217
    }
218
219
    /**
220
     * Countable interface
221
     *
222
     * @return int|void
223
     */
224 2
    public function count()
225
    {
226 2
        return count($this->diffObjects);
227
    }
228
229
    /**
230
     * Iterator interface
231
     *
232
     * @return mixed
233
     */
234
    public function current()
235
    {
236
        return $this->diffObjects[$this->position];
237
    }
238
239
    /**
240
     * Iterator interface
241
     */
242
    public function next()
243
    {
244
        ++$this->position;
245
    }
246
247
    /**
248
     * Iterator interface
249
     *
250
     * @return int
251
     */
252
    public function key()
253
    {
254
        return $this->position;
255
    }
256
257
    /**
258
     * Iterator interface
259
     *
260
     * @return bool
261
     */
262
    public function valid()
263
    {
264
        return isset($this->diffObjects[$this->position]);
265
    }
266
267
    /**
268
     * Iterator interface
269
     */
270
    public function rewind()
271
    {
272
        $this->position = 0;
273
    }
274
}
275