Passed
Push — master ( 0d8a9b...48a836 )
by f
12:20
created

CreateCommand::execute()   F

Complexity

Conditions 25
Paths 148

Size

Total Lines 143
Code Lines 101

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 25
eloc 101
c 2
b 0
f 0
nc 148
nop 2
dl 0
loc 143
rs 3.0133

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\Basic\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('stdout', NULL, InputOption::VALUE_NONE, 'Print archive to stdout')
31
            ->addOption('format', NULL, InputOption::VALUE_REQUIRED, 'Format')
32
            ->addOption('dry-run', NULL, InputOption::VALUE_NONE, 'Do not perform real archiving. Just print prepared data')
33
        ;
34
    }
35
36
    protected static $compressionLevels = [
37
        'none' => BasicDriver::COMPRESSION_NONE,
38
        'weak' => BasicDriver::COMPRESSION_WEAK,
39
        'average' => BasicDriver::COMPRESSION_AVERAGE,
40
        'strong' => BasicDriver::COMPRESSION_STRONG,
41
        'maximum' => BasicDriver::COMPRESSION_MAXIMUM,
42
    ];
43
44
    /**
45
     * @throws \wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException
46
     * @throws \wapmorgan\UnifiedArchive\Exceptions\FileAlreadyExistsException
47
     */
48
    public function execute(InputInterface $input, OutputInterface $output)
49
    {
50
        $archive_file = $input->getArgument('archive');
51
        $files_to_pack = $input->getArgument('file');
52
53
        $password = $input->getOption('password');
54
        $compression = $input->getOption('compression');
55
        if (!isset(static::$compressionLevels[$compression])) {
56
            throw new \InvalidArgumentException('Compression "' . $compression . '" is not valid');
57
        }
58
        $compression = static::$compressionLevels[$compression];
59
        $path = $input->getOption('path');
60
        if (!in_array($path, ['full', 'root', 'relative', 'basename'], true)) {
61
            throw new \InvalidArgumentException('Path can not have this value');
62
        }
63
        $dry_run = $input->getOption('dry-run');
64
        $comment = $input->getOption('comment');
65
        $stdout = $input->getOption('stdout');
66
67
        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

67
        if (file_exists(/** @scrutinizer ignore-type */ $archive_file)) {
Loading history...
68
            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

68
            if (is_dir(/** @scrutinizer ignore-type */ $archive_file))
Loading history...
69
                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

69
                throw new \InvalidArgumentException(/** @scrutinizer ignore-type */ $archive_file . ' is a directory!');
Loading history...
70
            else {
71
                throw new \InvalidArgumentException('File "' . $archive_file . '" already exists!');
72
            }
73
        }
74
75
        $files_list = [];
76
77
        foreach ($files_to_pack as $i => $file_to_pack) {
78
            $file_to_pack = realpath($file_to_pack);
79
            switch ($path) {
80
                case 'full':
81
                    $destination = ltrim($file_to_pack, '/');
82
                    $files_list[$destination] = $file_to_pack;
83
                    if (!$stdout) {
84
                        $output->writeln(
85
                            '<comment>' . $file_to_pack . ' => ' . $destination . '</comment>',
86
                            OutputInterface::VERBOSITY_VERBOSE
87
                        );
88
                    }
89
                    break;
90
                case 'root':
91
                    if (is_dir($file_to_pack)) {
92
                        if (!$stdout) {
93
                            $output->writeln(
94
                                '<comment>' . $file_to_pack . ' => root</comment>',
95
                                OutputInterface::VERBOSITY_VERBOSE
96
                            );
97
                        }
98
                        if (!isset($files_list[''])) {
99
                            $files_list[''] = $file_to_pack;
100
                        } elseif (is_string($files_list[''])) {
101
                            $files_list[''] = [$files_list[''], $file_to_pack];
102
                        } else {
103
                            $files_list[''][] = $file_to_pack;
104
                        }
105
                    } else {
106
                        if (!$stdout) {
107
                            $output->writeln(
108
                                '<comment>' . $file_to_pack . ' => ' . basename($file_to_pack) . '</comment>',
109
                                OutputInterface::VERBOSITY_VERBOSE
110
                            );
111
                        }
112
                        $files_list[basename($file_to_pack)] = $file_to_pack;
113
                    }
114
                    break;
115
                case 'relative':
116
                    $destination = ltrim($file_to_pack, '/.');
117
                    $files_list[$destination] = $file_to_pack;
118
                    if (!$stdout) {
119
                        $output->writeln(
120
                            '<comment>' . $file_to_pack . ' => ' . $destination . '</comment>',
121
                            OutputInterface::VERBOSITY_VERBOSE
122
                        );
123
                    }
124
                    break;
125
                case 'basename':
126
                    $destination = basename($file_to_pack);
127
                    $files_list[$destination] = $file_to_pack;
128
                    if (!$stdout) {
129
                        $output->writeln(
130
                            '<comment>' . $file_to_pack . ' => ' . $destination . '</comment>',
131
                            OutputInterface::VERBOSITY_VERBOSE
132
                        );
133
                    }
134
                    break;
135
            }
136
        }
137
138
        $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 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

138
        $information = UnifiedArchive::prepareForArchiving($files_list, /** @scrutinizer ignore-type */ $archive_file);
Loading history...
139
        if ($dry_run) {
140
            $output->writeln('Format: <info>' . $information['type'] . '</info>');
141
            $output->writeln('Original size: <info>' . implode($this->formatSize($information['totalSize'])) . '</info>');
142
            $output->writeln('Files: <info>' . $information['numberOfFiles'] . '</info>');
143
            foreach ($information['files'] as $destination => $source) {
144
                // is folder
145
                if ($source === null) {
146
                    continue;
147
                }
148
149
                $output->writeln($source . ' => <comment>' . $destination . '</comment>');
150
            }
151
            return 0;
152
        }
153
154
        ProgressBar::setFormatDefinition('archiving', '  %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%: %message%');
155
156
        if ($stdout) {
157
            $archived_files = UnifiedArchive::createInString($files_list, $archive_file, $compression, $password);
0 ignored issues
show
Unused Code introduced by
The assignment to $archived_files is dead and can be removed.
Loading history...
Bug introduced by
It seems like $password can also be of type string[]; however, parameter $password of wapmorgan\UnifiedArchive...chive::createInString() 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

157
            $archived_files = UnifiedArchive::createInString($files_list, $archive_file, $compression, /** @scrutinizer ignore-type */ $password);
Loading history...
158
        }
159
        $progressBar = new ProgressBar($output, $information['numberOfFiles']);
160
        $progressBar->setFormat('archiving');
161
        $progressBar->start();
162
        $archived_files = UnifiedArchive::create($files_list, $archive_file, $compression, $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
163
        use ($progressBar) {
164
            if ($fsFilename === null) {
165
                $progressBar->setMessage('Creating ' . $archiveFilename);
166
            } else {
167
                $progressBar->setMessage($fsFilename);
168
            }
169
            $progressBar->advance();
170
        });
171
        $progressBar->finish();
172
        $progressBar->clear();
173
        $output->writeln('');
174
175
        if (!$archived_files) {
176
            throw new \RuntimeException('archiveFiles result is false');
177
        }
178
179
        $archive = $this->open($archive_file);
180
        if (!empty($comment)) {
181
            $archive->setComment($comment);
182
        }
183
184
        $output->writeln(
185
            'Created <info>' . $archive_file . '</info> with <comment>' . $archived_files . '</comment> file(s) ('
186
            . implode($this->formatSize($archive->getOriginalSize())) . ') of total size '
187
            . implode($this->formatSize(filesize($archive_file)))
188
        );
189
190
        return 0;
191
    }
192
}
193