Completed
Pull Request — develop (#140)
by
unknown
08:01 queued 02:05
created

NodeObject   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 345
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 83.52%

Importance

Changes 0
Metric Value
wmc 26
c 0
b 0
f 0
lcom 2
cbo 3
dl 0
loc 345
ccs 76
cts 91
cp 0.8352
rs 10

20 Methods

Rating   Name   Duplication   Size   Complexity  
B createFromOutputLine() 0 24 2
B getLineSlices() 0 28 4
A __construct() 0 18 1
A __toString() 0 4 1
A getMimeType() 0 4 1
A getExtension() 0 10 2
A isTree() 0 4 1
A isLink() 0 4 1
A isBlob() 0 4 1
A getFullPath() 0 7 2
A getPermissions() 0 4 1
A getSha() 0 4 1
A getType() 0 4 1
A getName() 0 4 1
A getPath() 0 4 1
A getSize() 0 4 1
A getLastCommit() 0 6 1
A revParse() 0 8 1
A setRepository() 0 4 1
A getRepository() 0 4 1
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\RevParseCommand;
23
use \GitElephant\Repository;
24
25
/**
26
 * A Object instance represents a node in the git tree repository
27
 * It could be a file or a folder, as well as a submodule (a "link" in the git language)
28
 *
29
 * @author Matteo Giachino <[email protected]>
30
 */
31
class NodeObject implements TreeishInterface
32
{
33
    const TYPE_BLOB = 'blob';
34
    const TYPE_TREE = 'tree';
35
    const TYPE_LINK = 'commit';
36
37
    /**
38
     * @var \GitElephant\Repository
39
     */
40
    protected $repository;
41
42
    /**
43
     * permissions
44
     *
45
     * @var string
46
     */
47
    private $permissions;
48
49
    /**
50
     * type
51
     *
52
     * @var string
53
     */
54
    private $type;
55
56
    /**
57
     * sha
58
     *
59
     * @var string
60
     */
61
    private $sha;
62
63
    /**
64
     * size
65
     *
66
     * @var string
67
     */
68
    private $size;
69
70
    /**
71
     * name
72
     *
73
     * @var string
74
     */
75
    private $name;
76
77
    /**
78
     * path
79
     *
80
     * @var string
81
     */
82
    private $path;
83
84
    /**
85
     * create a Object from a single outputLine of the git ls-tree command
86
     *
87
     * @param \GitElephant\Repository $repository repository instance
88
     * @param string                  $outputLine output from ls-tree command
89
     *
90
     * @see LsTreeCommand::tree
91
     * @return NodeObject
92
     */
93 8
    public static function createFromOutputLine(Repository $repository, string $outputLine)
94
    {
95 8
        $slices = static::getLineSlices($outputLine);
96 8
        $fullPath = $slices['fullPath'];
97 8
        if (false === $pos = mb_strrpos($fullPath, '/')) {
98
            // repository root
99 6
            $path = '';
100 6
            $name = $fullPath;
101
        }
102
        else {
103 4
            $path = substr($fullPath, 0, $pos);
104 4
            $name = substr($fullPath, $pos + 1);
105
        }
106
107 8
        return new static(
108 8
            $repository,
109 8
            $slices['permissions'],
110 8
            $slices['type'],
111 8
            $slices['sha'],
112 8
            $slices['size'],
113 8
            $name,
114 8
            $path
115
        );
116
    }
117
118
    /**
119
     * Take a line and turn it in slices
120
     *
121
     * @param string $line a single line output from the git binary
122
     *
123
     * @return array
124
     */
125 14
    public static function getLineSlices(string $line)
126
    {
127 14
        preg_match('/^(\d+) (\w+) ([a-z0-9]+) +(\d+|-)\t(.*)$/', $line, $matches);
128 14
        $permissions = $matches[1];
129 14
        $type = null;
130 14
        switch ($matches[2]) {
131 14
            case NodeObject::TYPE_TREE:
132 5
                $type = NodeObject::TYPE_TREE;
133 5
                break;
134 14
            case NodeObject::TYPE_BLOB:
135 14
                $type = NodeObject::TYPE_BLOB;
136 14
                break;
137 1
            case NodeObject::TYPE_LINK:
138 1
                $type = NodeObject::TYPE_LINK;
139 1
                break;
140
        }
141 14
        $sha = $matches[3];
142 14
        $size = $matches[4];
143 14
        $fullPath = $matches[5];
144
145
        return [
146 14
            'permissions' => $permissions,
147 14
            'type'        => $type,
148 14
            'sha'         => $sha,
149 14
            'size'        => $size,
150 14
            'fullPath'    => $fullPath,
151
        ];
152
    }
153
154
    /**
155
     * Class constructor
156
     *
157
     * @param \GitElephant\Repository $repository repository instance
158
     * @param string                  $permissions node permissions
159
     * @param string                  $type node type
160
     * @param string                  $sha node sha
161
     * @param string                  $size node size in bytes
162
     * @param string                  $name node name
163
     * @param string                  $path node path
164
     */
165 14
    public function __construct(
166
        Repository $repository,
167
        string $permissions,
168
        string $type,
169
        string $sha,
170
        string $size,
171
        string $name,
172
        string $path
173
    )
174
    {
0 ignored issues
show
Coding Style introduced by
The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Loading history...
175 14
        $this->repository = $repository;
176 14
        $this->permissions = $permissions;
177 14
        $this->type = $type;
178 14
        $this->sha = $sha;
179 14
        $this->size = $size;
180 14
        $this->name = $name;
181 14
        $this->path = $path;
182 14
    }
183
184
    /**
185
     * toString magic method
186
     *
187
     * @return string
188
     */
189 1
    public function __toString()
190
    {
191 1
        return (string)$this->name;
192
    }
193
194
    /**
195
     * Mime Type getter
196
     *
197
     * @param string $basePath the base path of the repository
198
     *
199
     * @return string
200
     */
201
    public function getMimeType(string $basePath)
202
    {
203
        return mime_content_type($basePath . DIRECTORY_SEPARATOR . $this->path);
204
    }
205
206
    /**
207
     * get extension if it's a blob
208
     *
209
     * @return string|null
210
     */
211
    public function getExtension()
212
    {
213
        $pos = strrpos($this->name, '.');
214
        if ($pos === false) {
215
            return null;
216
        }
217
        else {
218
            return substr($this->name, $pos + 1);
219
        }
220
    }
221
222
    /**
223
     * whether the node is a tree
224
     *
225
     * @return bool
226
     */
227 9
    public function isTree()
228
    {
229 9
        return self::TYPE_TREE == $this->getType();
230
    }
231
232
    /**
233
     * whether the node is a link
234
     *
235
     * @return bool
236
     */
237
    public function isLink()
238
    {
239
        return self::TYPE_LINK == $this->getType();
240
    }
241
242
    /**
243
     * whether the node is a blob
244
     *
245
     * @return bool
246
     */
247 1
    public function isBlob()
248
    {
249 1
        return self::TYPE_BLOB == $this->getType();
250
    }
251
252
    /**
253
     * Full path getter
254
     *
255
     * @return string
256
     */
257 12
    public function getFullPath()
258
    {
259 12
        return rtrim(
260 12
            '' == $this->path ? $this->name : $this->path . DIRECTORY_SEPARATOR . $this->name,
261 12
            DIRECTORY_SEPARATOR
262
        );
263
    }
264
265
    /**
266
     * permissions getter
267
     *
268
     * @return string
269
     */
270
    public function getPermissions()
271
    {
272
        return $this->permissions;
273
    }
274
275
    /**
276
     * sha getter
277
     *
278
     * @return string
279
     */
280 6
    public function getSha()
281
    {
282 6
        return $this->sha;
283
    }
284
285
    /**
286
     * type getter
287
     *
288
     * @return string
289
     */
290 13
    public function getType()
291
    {
292 13
        return $this->type;
293
    }
294
295
    /**
296
     * name getter
297
     *
298
     * @return string
299
     */
300 5
    public function getName()
301
    {
302 5
        return $this->name;
303
    }
304
305
    /**
306
     * path getter
307
     *
308
     * @return string
309
     */
310
    public function getPath()
311
    {
312
        return $this->path;
313
    }
314
315
    /**
316
     * size getter
317
     *
318
     * @return string
319
     */
320
    public function getSize()
321
    {
322
        return $this->size;
323
    }
324
325
    /**
326
     * gets the last commit in this object
327
     *
328
     * @return Commit
329
     */
330 3
    public function getLastCommit()
331
    {
332 3
        $log = $this->repository->getLog('HEAD', $this->getFullPath(), 1);
333
334 3
        return $log[0];
335
    }
336
337
    /**
338
     * rev-parse command - often used to return a commit tag.
339
     *
340
     * @param array $options the options to apply to rev-parse
341
     *
342
     * @throws \RuntimeException
343
     * @throws \InvalidArgumentException
344
     * @throws \Symfony\Component\Process\Exception\RuntimeException
345
     * @return array
346
     */
347 1
    public function revParse(array $options = [])
348
    {
349 1
        $c = RevParseCommand::getInstance()->revParse($this, $options);
350 1
        $caller = $this->repository->getCaller();
351 1
        $caller->execute($c);
352
353 1
        return array_map('trim', $caller->getOutputLines(true));
354
    }
355
356
    /*
357
     * Repository setter
358
     *
359
     * @param \GitElephant\Repository $repository the repository variable
360
     */
361 1
    public function setRepository(Repository $repository)
362
    {
363 1
        $this->repository = $repository;
364 1
    }
365
366
    /**
367
     * Repository getter
368
     *
369
     * @return \GitElephant\Repository
370
     */
371 59
    public function getRepository()
372
    {
373 59
        return $this->repository;
374
    }
375
}
376