Completed
Pull Request — develop (#165)
by
unknown
01:48
created

NodeObject::getType()   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
 * 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
        } else {
102 4
            $path = substr($fullPath, 0, $pos);
103 4
            $name = substr($fullPath, $pos + 1);
104
        }
105 8
        return new static(
106 8
            $repository,
107 8
            $slices['permissions'],
108 8
            $slices['type'],
109 8
            $slices['sha'],
110 8
            $slices['size'],
111 8
            $name,
112 8
            $path
113
        );
114
    }
115
116
    /**
117
     * Take a line and turn it in slices
118
     *
119
     * @param string $line a single line output from the git binary
120
     *
121
     * @return array
122
     */
123 14
    public static function getLineSlices(string $line): array
124
    {
125 14
        preg_match('/^(\d+) (\w+) ([a-z0-9]+) +(\d+|-)\t(.*)$/', $line, $matches);
126 14
        $permissions = $matches[1];
127 14
        $type = null;
128 14
        switch ($matches[2]) {
129
            case NodeObject::TYPE_TREE:
130 5
                $type = NodeObject::TYPE_TREE;
131 5
                break;
132
            case NodeObject::TYPE_BLOB:
133 14
                $type = NodeObject::TYPE_BLOB;
134 14
                break;
135
            case NodeObject::TYPE_LINK:
136 1
                $type = NodeObject::TYPE_LINK;
137 1
                break;
138
        }
139 14
        $sha = $matches[3];
140 14
        $size = $matches[4];
141 14
        $fullPath = $matches[5];
142
        return [
143 14
            'permissions' => $permissions,
144 14
            'type'        => $type,
145 14
            'sha'         => $sha,
146 14
            'size'        => $size,
147 14
            'fullPath'    => $fullPath,
148
        ];
149
    }
150
151
    /**
152
     * Class constructor
153
     *
154
     * @param \GitElephant\Repository $repository  repository instance
155
     * @param string                  $permissions node permissions
156
     * @param string                  $type        node type
157
     * @param string                  $sha         node sha
158
     * @param string                  $size        node size in bytes
159
     * @param string                  $name        node name
160
     * @param string                  $path        node path
161
     */
162 14
    public function __construct(Repository $repository, string $permissions, string $type, string $sha, string $size, string $name, string $path)
163
    {
164 14
        $this->repository = $repository;
165 14
        $this->permissions = $permissions;
166 14
        $this->type = $type;
167 14
        $this->sha = $sha;
168 14
        $this->size = $size;
169 14
        $this->name = $name;
170 14
        $this->path = $path;
171 14
    }
172
173
    /**
174
     * toString magic method
175
     *
176
     * @return string
177
     */
178 1
    public function __toString(): string
179
    {
180 1
        return (string)$this->name;
181
    }
182
183
    /**
184
     * Mime Type getter
185
     *
186
     * @param string $basePath the base path of the repository
187
     *
188
     * @return string
189
     */
190
    public function getMimeType(string $basePath)
191
    {
192
        return mime_content_type($basePath . DIRECTORY_SEPARATOR . $this->path);
193
    }
194
195
    /**
196
     * get extension if it's a blob
197
     *
198
     * @return string|null
199
     */
200
    public function getExtension(): ?string
201
    {
202
        $pos = strrpos($this->name, '.');
203
        if ($pos === false) {
204
            return null;
205
        } else {
206
            return substr($this->name, $pos + 1);
207
        }
208
    }
209
210
    /**
211
     * whether the node is a tree
212
     *
213
     * @return bool
214
     */
215 9
    public function isTree(): bool
216
    {
217 9
        return self::TYPE_TREE == $this->getType();
218
    }
219
220
    /**
221
     * whether the node is a link
222
     *
223
     * @return bool
224
     */
225
    public function isLink(): bool
226
    {
227
        return self::TYPE_LINK == $this->getType();
228
    }
229
230
    /**
231
     * whether the node is a blob
232
     *
233
     * @return bool
234
     */
235 1
    public function isBlob(): bool
236
    {
237 1
        return self::TYPE_BLOB == $this->getType();
238
    }
239
240
    /**
241
     * Full path getter
242
     *
243
     * @return string
244
     */
245 12
    public function getFullPath(): string
246
    {
247 12
        return rtrim(
248 12
            '' == $this->path ? $this->name : $this->path . DIRECTORY_SEPARATOR . $this->name,
249 12
            DIRECTORY_SEPARATOR
250
        );
251
    }
252
253
    /**
254
     * permissions getter
255
     *
256
     * @return string
257
     */
258
    public function getPermissions(): string
259
    {
260
        return $this->permissions;
261
    }
262
263
    /**
264
     * sha getter
265
     *
266
     * @return string
267
     */
268 6
    public function getSha(): string
269
    {
270 6
        return $this->sha;
271
    }
272
273
    /**
274
     * type getter
275
     *
276
     * @return string
277
     */
278 13
    public function getType(): string
279
    {
280 13
        return $this->type;
281
    }
282
283
    /**
284
     * name getter
285
     *
286
     * @return string
287
     */
288 5
    public function getName(): string
289
    {
290 5
        return $this->name;
291
    }
292
293
    /**
294
     * path getter
295
     *
296
     * @return string
297
     */
298
    public function getPath(): string
299
    {
300
        return $this->path;
301
    }
302
303
    /**
304
     * size getter
305
     *
306
     * @return string
307
     */
308
    public function getSize(): string
309
    {
310
        return $this->size;
311
    }
312
313
    /**
314
     * gets the last commit in this object
315
     *
316
     * @return Commit
317
     */
318 3
    public function getLastCommit(): ?\GitElephant\Objects\Commit
319
    {
320 3
        $log = $this->repository->getLog('HEAD', $this->getFullPath(), 1);
321
322 3
        return $log[0];
323
    }
324
325
    /**
326
     * rev-parse command - often used to return a commit tag.
327
     *
328
     * @param array $options the options to apply to rev-parse
329
     *
330
     * @throws \RuntimeException
331
     * @throws \InvalidArgumentException
332
     * @throws \Symfony\Component\Process\Exception\RuntimeException
333
     * @return array
334
     */
335 1
    public function revParse(array $options = []): array
336
    {
337 1
        $c = RevParseCommand::getInstance()->revParse($this, $options);
338 1
        $caller = $this->repository->getCaller();
339 1
        $caller->execute($c);
340 1
        return array_map('trim', $caller->getOutputLines(true));
341
    }
342
343
    /*
344
     * Repository setter
345
     *
346
     * @param \GitElephant\Repository $repository the repository variable
347
     */
348 1
    public function setRepository(Repository $repository): void
349
    {
350 1
        $this->repository = $repository;
351 1
    }
352
353
    /**
354
     * Repository getter
355
     *
356
     * @return \GitElephant\Repository
357
     */
358 59
    public function getRepository(): \GitElephant\Repository
359
    {
360 59
        return $this->repository;
361
    }
362
}
363