AbstractTarAdapter::doTarExtractMembers()   B
last analyzed

Complexity

Conditions 9
Paths 49

Size

Total Lines 52
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 30
nc 49
nop 5
dl 0
loc 52
rs 8.0555
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of Compressy.
5
 *
6
 * (c) Alchemy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Gocobachi\Compressy\Adapter;
13
14
use Gocobachi\Compressy\Adapter\Resource\ResourceInterface;
15
use Gocobachi\Compressy\Archive\Archive;
16
use Gocobachi\Compressy\Archive\Member;
17
use Gocobachi\Compressy\Exception\RuntimeException;
18
use Gocobachi\Compressy\Exception\InvalidArgumentException;
19
use Gocobachi\Compressy\Resource\Resource as ZippyResource;
20
use Symfony\Component\Process\Exception\ExceptionInterface as ProcessException;
21
22
abstract class AbstractTarAdapter extends AbstractBinaryAdapter
23
{
24
    /**
25
     * @inheritdoc
26
     */
27
    protected function doCreate($path, $files, $recursive)
28
    {
29
        return $this->doTarCreate($this->getLocalOptions(), $path, $files, $recursive);
30
    }
31
32
    /**
33
     * @inheritdoc
34
     */
35
    protected function doListMembers(ResourceInterface $resource)
36
    {
37
        return $this->doTarListMembers($this->getLocalOptions(), $resource);
38
    }
39
40
    /**
41
     * @inheritdoc
42
     */
43
    protected function doAdd(ResourceInterface $resource, $files, $recursive)
44
    {
45
        return $this->doTarAdd($this->getLocalOptions(), $resource, $files, $recursive);
46
    }
47
48
    /**
49
     * @inheritdoc
50
     */
51
    protected function doRemove(ResourceInterface $resource, $files)
52
    {
53
        return $this->doTarRemove($this->getLocalOptions(), $resource, $files);
54
    }
55
56
    /**
57
     * @inheritdoc
58
     */
59
    protected function doExtractMembers(ResourceInterface $resource, $members, $to, $overwrite = false)
60
    {
61
        return $this->doTarExtractMembers($this->getLocalOptions(), $resource, $members, $to, $overwrite);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->doTarExtra...mbers, $to, $overwrite) returns the type array which is incompatible with the return type mandated by Gocobachi\Compressy\Adap...ter::doExtractMembers() of SplFileInfo.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
62
    }
63
64
    /**
65
     * @inheritdoc
66
     */
67
    protected function doExtract(ResourceInterface $resource, $to)
68
    {
69
        return $this->doTarExtract($this->getLocalOptions(), $resource, $to);
70
    }
71
72
    /**
73
     * @inheritdoc
74
     */
75
    protected function doGetInflatorVersion()
76
    {
77
        $process = $this
78
            ->inflator
79
            ->create()
80
            ->add('--version')
81
            ->getProcess();
82
83
        $process->run();
84
85
        if (!$process->isSuccessful()) {
86
            throw new RuntimeException(sprintf(
87
                'Unable to execute the following command %s {output: %s}',
88
                $process->getCommandLine(), $process->getErrorOutput()
89
            ));
90
        }
91
92
        return $this->parser->parseInflatorVersion($process->getOutput() ?: '');
93
    }
94
95
    /**
96
     * @inheritdoc
97
     */
98
    protected function doGetDeflatorVersion()
99
    {
100
        return $this->getInflatorVersion();
101
    }
102
103
    protected function doTarCreate($options, $path, $files = null, $recursive = true)
104
    {
105
        $files = (array) $files;
106
107
        $builder = $this
108
            ->inflator
109
            ->create();
110
111
        if (!$recursive) {
112
            $builder->add('--no-recursion');
113
        }
114
115
        $builder->add('-c');
116
117
        foreach ((array) $options as $option) {
118
            $builder->add((string) $option);
119
        }
120
121
        if (0 === count($files)) {
122
            $nullFile = defined('PHP_WINDOWS_VERSION_BUILD') ? 'NUL' : '/dev/null';
123
124
            $builder->add('-f');
125
            $builder->add($path);
126
            $builder->add('-T');
127
            $builder->add($nullFile);
128
129
            $process = $builder->getProcess();
130
            $process->run();
131
132
        } else {
133
134
            $builder->add(sprintf('--file=%s', $path));
135
136
            if (!$recursive) {
137
                $builder->add('--no-recursion');
138
            }
139
140
            $collection = $this->manager->handle(getcwd(), $files);
141
142
            $builder->setWorkingDirectory($collection->getContext());
143
144
            $collection->forAll(function($i, ZippyResource $resource) use ($builder) {
145
                return $builder->add($resource->getTarget());
146
            });
147
148
            $process = $builder->getProcess();
149
150
            try {
151
                $process->run();
152
            } catch (ProcessException $e) {
153
                $this->manager->cleanup($collection);
154
                throw $e;
155
            }
156
157
            $this->manager->cleanup($collection);
158
        }
159
160
        if (!$process->isSuccessful()) {
161
            throw new RuntimeException(sprintf(
162
                'Unable to execute the following command %s {output: %s}',
163
                $process->getCommandLine(),
164
                $process->getErrorOutput()
165
            ));
166
        }
167
168
        return new Archive($this->createResource($path), $this, $this->manager);
169
    }
170
171
    protected function doTarListMembers($options, ResourceInterface $resource)
172
    {
173
        $builder = $this
174
            ->inflator
175
            ->create();
176
177
        foreach ($this->getListMembersOptions() as $option) {
178
            $builder->add($option);
179
        }
180
181
        $builder
182
            ->add('--list')
183
            ->add('-v')
184
            ->add(sprintf('--file=%s', $resource->getResource()));
185
186
        foreach ((array) $options as $option) {
187
            $builder->add((string) $option);
188
        }
189
190
        $process = $builder->getProcess();
191
        $process->run();
192
193
        if (!$process->isSuccessful()) {
194
            throw new RuntimeException(sprintf(
195
                'Unable to execute the following command %s {output: %s}',
196
                $process->getCommandLine(),
197
                $process->getErrorOutput()
198
            ));
199
        }
200
201
        $members = array();
202
203
        foreach ($this->parser->parseFileListing($process->getOutput() ?: '') as $member) {
204
            $members[] = new Member(
205
                    $resource,
206
                    $this,
207
                    $member['location'],
208
                    $member['size'],
209
                    $member['mtime'],
210
                    $member['is_dir']
211
            );
212
        }
213
214
        return $members;
215
    }
216
217
    protected function doTarAdd($options, ResourceInterface $resource, $files, $recursive = true)
218
    {
219
        $files = (array) $files;
220
221
        $builder = $this
222
            ->inflator
223
            ->create();
224
225
        if (!$recursive) {
226
            $builder->add('--no-recursion');
227
        }
228
229
        $builder
230
            ->add('--append')
231
            ->add(sprintf('--file=%s', $resource->getResource()));
232
233
        foreach ((array) $options as $option) {
234
            $builder->add((string) $option);
235
        }
236
237
        // there will be an issue if the file starts with a dash
238
        // see --add-file=FILE
239
        $collection = $this->manager->handle(getcwd(), $files);
240
241
        $builder->setWorkingDirectory($collection->getContext());
242
243
        $collection->forAll(function($i, ZippyResource $resource) use ($builder) {
244
            return $builder->add($resource->getTarget());
245
        });
246
247
        $process = $builder->getProcess();
248
249
        try {
250
            $process->run();
251
        } catch (ProcessException $e) {
252
            $this->manager->cleanup($collection);
253
            throw $e;
254
        }
255
256
        $this->manager->cleanup($collection);
257
258
        if (!$process->isSuccessful()) {
259
            throw new RuntimeException(sprintf(
260
                'Unable to execute the following command %s {output: %s}',
261
                $process->getCommandLine(),
262
                $process->getErrorOutput()
263
            ));
264
        }
265
266
        return $files;
267
    }
268
269
    protected function doTarRemove($options, ResourceInterface $resource, $files)
270
    {
271
        $files = (array) $files;
272
273
        $builder = $this
274
            ->inflator
275
            ->create();
276
277
        $builder
278
            ->add('--delete')
279
            ->add(sprintf('--file=%s', $resource->getResource()));
280
281
        foreach ((array) $options as $option) {
282
            $builder->add((string) $option);
283
        }
284
285
        if (!$this->addBuilderFileArgument($files, $builder)) {
286
            throw new InvalidArgumentException('Invalid files');
287
        }
288
289
        $process = $builder->getProcess();
290
291
        $process->run();
292
293
        if (!$process->isSuccessful()) {
294
            throw new RuntimeException(sprintf(
295
                'Unable to execute the following command %s {output: %s}',
296
                $process->getCommandLine(),
297
                $process->getErrorOutput()
298
            ));
299
        }
300
301
        return $files;
302
    }
303
304
    protected function doTarExtract($options, ResourceInterface $resource, $to = null)
305
    {
306
        if (null !== $to && !is_dir($to)) {
307
            throw new InvalidArgumentException(sprintf("%s is not a directory", $to));
308
        }
309
310
        $builder = $this
311
            ->inflator
312
            ->create();
313
314
        $builder
315
            ->add('--extract')
316
            ->add(sprintf('--file=%s', $resource->getResource()));
317
318
        foreach ($this->getExtractOptions() as $option) {
319
            $builder
320
                ->add($option);
321
        }
322
323
        foreach ((array) $options as $option) {
324
            $builder->add((string) $option);
325
        }
326
327
        if (null !== $to) {
328
            $builder
329
                ->add('--directory')
330
                ->add($to);
331
        }
332
333
        $process = $builder->getProcess();
334
335
        $process->run();
336
337
        if (!$process->isSuccessful()) {
338
            throw new RuntimeException(sprintf(
339
                'Unable to execute the following command %s {output: %s}',
340
                $process->getCommandLine(),
341
                $process->getErrorOutput()
342
            ));
343
        }
344
345
        return new \SplFileInfo($to ?: $resource->getResource());
346
    }
347
348
    /**
349
     * @param array             $options
350
     * @param ResourceInterface $resource
351
     * @param array             $members
352
     * @param string            $to
353
     * @param bool              $overwrite
354
     *
355
     * @return array
356
     */
357
    protected function doTarExtractMembers($options, ResourceInterface $resource, $members, $to = null, $overwrite = false)
358
    {
359
        if (null !== $to && !is_dir($to)) {
360
            throw new InvalidArgumentException(sprintf("%s is not a directory", $to));
361
        }
362
363
        $members = (array) $members;
364
365
        $builder = $this
366
            ->inflator
367
            ->create();
368
369
        if ($overwrite == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
370
            $builder->add('-k');
371
        }
372
373
        $builder
374
            ->add('--extract')
375
            ->add(sprintf('--file=%s', $resource->getResource()));
376
377
        foreach ($this->getExtractMembersOptions() as $option) {
378
            $builder
379
                ->add($option);
380
        }
381
382
        foreach ((array) $options as $option) {
383
            $builder->add((string) $option);
384
        }
385
386
        if (null !== $to) {
387
            $builder
388
                ->add('--directory')
389
                ->add($to);
390
        }
391
392
        if (!$this->addBuilderFileArgument($members, $builder)) {
393
            throw new InvalidArgumentException('Invalid files');
394
        }
395
396
        $process = $builder->getProcess();
397
398
        $process->run();
399
400
        if (!$process->isSuccessful()) {
401
            throw new RuntimeException(sprintf(
402
                'Unable to execute the following command %s {output: %s}',
403
                $process->getCommandLine(),
404
                $process->getErrorOutput()
405
            ));
406
        }
407
408
        return $members;
409
    }
410
411
    /**
412
     * Returns an array of option for the listMembers command
413
     *
414
     * @return array
415
     */
416
    abstract protected function getListMembersOptions();
417
418
    /**
419
     * Returns an array of option for the extract command
420
     *
421
     * @return array
422
     */
423
    abstract protected function getExtractOptions();
424
425
    /**
426
     * Returns an array of option for the extractMembers command
427
     *
428
     * @return array
429
     */
430
    abstract protected function getExtractMembersOptions();
431
432
    /**
433
     * Gets adapter specific additional options
434
     *
435
     * @return array
436
     */
437
    abstract protected function getLocalOptions();
438
}
439