Passed
Push — 1.1.x ( bc52f7...e8e75c )
by f
12:04
created

CreateCommand::execute()   D

Complexity

Conditions 19
Paths 58

Size

Total Lines 112
Code Lines 82

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 19
eloc 82
c 2
b 0
f 0
nc 58
nop 2
dl 0
loc 112
rs 4.5166

How to fix   Long Method    Complexity   

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
namespace wapmorgan\UnifiedArchive\Commands;
4
5
use http\Exception\InvalidArgumentException;
6
use Symfony\Component\Console\Helper\ProgressBar;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use wapmorgan\UnifiedArchive\Drivers\BasicDriver;
12
use wapmorgan\UnifiedArchive\UnifiedArchive;
13
14
class CreateCommand extends BaseCommand
15
{
16
    protected static $defaultName = 'archive:create';
17
18
    protected function configure()
19
    {
20
        parent::configure();
21
        $this
22
            ->setDescription('Creates new archive')
23
            ->setHelp('Creates new archive.')
24
            ->addArgument('archive', InputArgument::REQUIRED, 'New archive filename. Type of archive will be recognized from extension')
25
            ->addArgument('file', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Files to pack')
26
            ->addOption('password', NULL, InputOption::VALUE_REQUIRED, 'Password for new archive')
27
            ->addOption('compression', NULL, InputOption::VALUE_OPTIONAL, 'Compression level for new archive. Variants: none, weak, average, strong, maximum.', 'average')
28
            ->addOption('comment', NULL, InputOption::VALUE_OPTIONAL, 'Comment for new archive')
29
            ->addOption('path', NULL, InputOption::VALUE_OPTIONAL, 'Path resolving if destination is not passed. Variants: full, root, relative, basename', 'root')
30
            ->addOption('dry-run', NULL, InputOption::VALUE_NONE, 'Do not perform real archiving. Just print prepared data')
31
        ;
32
    }
33
34
    protected static $compressionLevels = [
35
        'none' => BasicDriver::COMPRESSION_NONE,
36
        'weak' => BasicDriver::COMPRESSION_WEAK,
37
        'average' => BasicDriver::COMPRESSION_AVERAGE,
38
        'strong' => BasicDriver::COMPRESSION_STRONG,
39
        'maximum' => BasicDriver::COMPRESSION_MAXIMUM,
40
    ];
41
42
    public function execute(InputInterface $input, OutputInterface $output)
43
    {
44
        $archive_file = $input->getArgument('archive');
45
        $files_to_pack = $input->getArgument('file');
46
47
        $password = $input->getOption('password');
48
        $compression = $input->getOption('compression');
49
        if (!isset(static::$compressionLevels[$compression])) {
50
            throw new \InvalidArgumentException('Compression "' . $compression . '" is not valid');
51
        }
52
        $compression = static::$compressionLevels[$compression];
53
        $path = $input->getOption('path');
54
        if (!in_array($path, ['full', 'root', 'relative', 'basename'], true)) {
55
            throw new \InvalidArgumentException('Path can not have this value');
56
        }
57
        $dry_run = $input->getOption('dry-run');
58
        $comment = $input->getOption('comment');
59
60
        if (file_exists($archive_file)) {
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type null and string[]; however, parameter $filename of file_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

60
        if (file_exists(/** @scrutinizer ignore-type */ $archive_file)) {
Loading history...
61
            if (is_dir($archive_file))
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type null and string[]; however, parameter $filename of is_dir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
            if (is_dir(/** @scrutinizer ignore-type */ $archive_file))
Loading history...
62
                throw new \InvalidArgumentException($archive_file . ' is a directory!');
0 ignored issues
show
Bug introduced by
Are you sure $archive_file of type null|string|string[] can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

62
                throw new \InvalidArgumentException(/** @scrutinizer ignore-type */ $archive_file . ' is a directory!');
Loading history...
63
            else {
64
                throw new \InvalidArgumentException('File "' . $archive_file . '" already exists!');
65
            }
66
        }
67
68
        $files_list = [];
69
70
        foreach ($files_to_pack as $i => $file_to_pack) {
71
            $file_to_pack = realpath($file_to_pack);
72
            switch ($path) {
73
                case 'full':
74
                    $destination = ltrim($file_to_pack, '/');
75
                    $files_list[$destination] = $file_to_pack;
76
                    $output->writeln('<comment>' . $file_to_pack . ' => ' . $destination . '</comment>', OutputInterface::VERBOSITY_VERBOSE);
77
                    break;
78
                case 'root':
79
                    if (is_dir($file_to_pack)) {
80
                        $output->writeln('<comment>' . $file_to_pack . ' => root</comment>', OutputInterface::VERBOSITY_VERBOSE);
81
                        if (!isset($files_list[''])) {
82
                            $files_list[''] = $file_to_pack;
83
                        } elseif (is_string($files_list[''])) {
84
                            $files_list[''] = [$files_list[''], $file_to_pack];
85
                        } else {
86
                            $files_list[''][] = $file_to_pack;
87
                        }
88
                    } else {
89
                        $output->writeln('<comment>' . $file_to_pack . ' => ' . basename($file_to_pack) . '</comment>', OutputInterface::VERBOSITY_VERBOSE);
90
                        $files_list[basename($file_to_pack)] = $file_to_pack;
91
                    }
92
                    break;
93
                case 'relative':
94
                    $destination = ltrim($file_to_pack, '/.');
95
                    $files_list[$destination] = $file_to_pack;
96
                    $output->writeln('<comment>' . $file_to_pack . ' => ' . $destination . '</comment>', OutputInterface::VERBOSITY_VERBOSE);
97
                    break;
98
                case 'basename':
99
                    $destination = basename($file_to_pack);
100
                    $files_list[$destination] = $file_to_pack;
101
                    $output->writeln('<comment>' . $file_to_pack . ' => ' . $destination . '</comment>', OutputInterface::VERBOSITY_VERBOSE);
102
                    break;
103
            }
104
        }
105
106
        $information = UnifiedArchive::prepareForArchiving($files_list, $archive_file);
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type string[]; however, parameter $archiveName of wapmorgan\UnifiedArchive...::prepareForArchiving() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
        $information = UnifiedArchive::prepareForArchiving($files_list, /** @scrutinizer ignore-type */ $archive_file);
Loading history...
107
        if ($dry_run) {
108
            $output->writeln('Format: <info>' . $information['type'] . '</info>');
109
            $output->writeln('Original size: <info>' . implode($this->formatSize($information['totalSize'])) . '</info>');
110
            $output->writeln('Files: <info>' . $information['numberOfFiles'] . '</info>');
111
            foreach ($information['files'] as $destination => $source) {
112
                // is folder
113
                if ($source === null) {
114
                    continue;
115
                }
116
117
                $output->writeln($source . ' => <comment>' . $destination . '</comment>');
118
            }
119
            return 0;
120
        }
121
122
        ProgressBar::setFormatDefinition('archiving', '  %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%: %message%');
123
124
        $progressBar = new ProgressBar($output, $information['numberOfFiles']);
125
        $progressBar->setFormat('archiving');
126
        $progressBar->start();
127
        $archived_files = UnifiedArchive::archiveFiles($files_list, $archive_file, $compression, $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type string[]; however, parameter $archiveName of wapmorgan\UnifiedArchive...Archive::archiveFiles() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

127
        $archived_files = UnifiedArchive::archiveFiles($files_list, /** @scrutinizer ignore-type */ $archive_file, $compression, $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
Loading history...
Bug introduced by
It seems like $password can also be of type string[]; however, parameter $password of wapmorgan\UnifiedArchive...Archive::archiveFiles() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

127
        $archived_files = UnifiedArchive::archiveFiles($files_list, $archive_file, $compression, /** @scrutinizer ignore-type */ $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
Loading history...
128
            use ($progressBar) {
129
            if ($fsFilename === null) {
130
                $progressBar->setMessage('Creating ' . $archiveFilename);
131
            } else {
132
                $progressBar->setMessage($fsFilename);
133
            }
134
            $progressBar->advance();
135
        });
136
        $progressBar->finish();
137
        $progressBar->clear();
138
        $output->writeln('');
139
140
        if (!$archived_files) {
141
            throw new \RuntimeException('archiveFiles result is false');
142
        }
143
144
        $archive = $this->open($archive_file);
145
        if (!empty($comment)) {
146
            $archive->setComment($comment);
0 ignored issues
show
Bug introduced by
It seems like $comment can also be of type string[]; however, parameter $comment of wapmorgan\UnifiedArchive...edArchive::setComment() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
            $archive->setComment(/** @scrutinizer ignore-type */ $comment);
Loading history...
147
        }
148
149
        $output->writeln('Created <info>' . $archive_file . '</info> with <comment>' . $archived_files . '</comment> file(s) ('
150
                         . implode($this->formatSize($archive->getOriginalSize())) . ') of total size '
151
                         . implode($this->formatSize(filesize($archive_file))));
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type null and string[]; however, parameter $filename of filesize() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

151
                         . implode($this->formatSize(filesize(/** @scrutinizer ignore-type */ $archive_file))));
Loading history...
152
153
        return 0;
154
    }
155
}
156