Passed
Pull Request — master (#483)
by Théo
110:16
created

AddPrefixCommand::scopeFile()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 35
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4.0039

Importance

Changes 0
Metric Value
cc 4
eloc 15
nc 5
nop 8
dl 0
loc 35
ccs 15
cts 16
cp 0.9375
crap 4.0039
rs 9.7666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the humbug/php-scoper package.
7
 *
8
 * Copyright (c) 2017 Théo FIDRY <[email protected]>,
9
 *                    Pádraic Brady <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Humbug\PhpScoper\Console\Command;
16
17
use Fidry\Console\Application\Application;
18
use Fidry\Console\Command\Command;
19
use Fidry\Console\Command\CommandAware;
20
use Fidry\Console\Command\CommandAwareness;
21
use Fidry\Console\Command\Configuration as CommandConfiguration;
22
use Fidry\Console\ExitCode;
23
use Fidry\Console\IO;
24
use Humbug\PhpScoper\Configuration;
25
use Humbug\PhpScoper\Console\ConfigLoader;
26
use Humbug\PhpScoper\Console\ConsoleScoper;
27
use Humbug\PhpScoper\Scoper;
28
use Humbug\PhpScoper\Scoper\ConfigurableScoper;
29
use Symfony\Component\Console\Exception\RuntimeException;
30
use Symfony\Component\Console\Input\InputArgument;
31
use Symfony\Component\Console\Input\InputOption;
32
use Symfony\Component\Filesystem\Filesystem;
33
use function array_map;
34
use function count;
35
use function is_dir;
36
use function is_writable;
37
use function Safe\getcwd;
38
use function Safe\sprintf;
39
use const DIRECTORY_SEPARATOR;
40
41
final class AddPrefixCommand implements Command, CommandAware
42
{
43
    use CommandAwareness;
44
45
    private const PATH_ARG = 'paths';
46
    private const PREFIX_OPT = 'prefix';
47
    private const OUTPUT_DIR_OPT = 'output-dir';
48
    private const FORCE_OPT = 'force';
49
    private const STOP_ON_FAILURE_OPT = 'stop-on-failure';
50
    private const CONFIG_FILE_OPT = 'config';
51
    private const DEFAULT_CONFIG_FILE_PATH = 'scoper.inc.php';
52
    private const NO_CONFIG_OPT = 'no-config';
53
54
    private Filesystem $fileSystem;
55 16
    private ConfigurableScoper $scoper;
56
    private bool $init = false;
57 16
    private Application $application;
58
59 16
    public function __construct(
60 16
        Filesystem $fileSystem,
61
        Scoper $scoper,
62
        Application $application
63
    ) {
64
        $this->fileSystem = $fileSystem;
65
        $this->scoper = new ConfigurableScoper($scoper);
66 16
        $this->application = $application;
67
    }
68 16
69
    public function getConfiguration(): CommandConfiguration
70
    {
71 16
        return new CommandConfiguration(
72 16
            'add-prefix',
73 16
            'Goes through all the PHP files found in the given paths to apply the given prefix to namespaces & FQNs.',
74 16
            '',
75 16
            [
76 16
                new InputArgument(
77
                    self::PATH_ARG,
78 16
                    InputArgument::IS_ARRAY,
79 16
                    'The path(s) to process.'
80 16
                ),
81 16
            ],
82 16
            [
83
                ChangeableDirectory::createOption(),
84 16
                new InputOption(
85 16
                    self::PREFIX_OPT,
86 16
                    'p',
87 16
                    InputOption::VALUE_REQUIRED,
88 16
                    'The namespace prefix to add.',
89 16
                ),
90
                new InputOption(
91 16
                    self::OUTPUT_DIR_OPT,
92 16
                    'o',
93 16
                    InputOption::VALUE_REQUIRED,
94 16
                    'The output directory in which the prefixed code will be dumped.',
95 16
                    'build',
96
                ),
97 16
                new InputOption(
98 16
                    self::FORCE_OPT,
99 16
                    'f',
100 16
                    InputOption::VALUE_NONE,
101 16
                    'Deletes any existing content in the output directory without any warning.'
102
                ),
103 16
                new InputOption(
104 16
                    self::STOP_ON_FAILURE_OPT,
105 16
                    's',
106 16
                    InputOption::VALUE_NONE,
107 16
                    'Stops on failure.'
108 16
                ),
109 16
                new InputOption(
110
                    self::CONFIG_FILE_OPT,
111
                    'c',
112 16
                    InputOption::VALUE_REQUIRED,
113 16
                    sprintf(
114 16
                        'Conf,iguration file. Will use "%s" if found by default.',
115 16
                        self::DEFAULT_CONFIG_FILE_PATH
116 16
                    )
117
                ),
118
                new InputOption(
119
                    self::NO_CONFIG_OPT,
120
                    null,
121
                    InputOption::VALUE_NONE,
122
                    'Do not look for a configuration file.'
123
                ),
124 14
            ],
125
        );
126 14
    }
127 14
128
    public function execute(IO $io): int
129 14
    {
130
        $io->writeln('');
131 14
132 14
        ChangeableDirectory::changeWorkingDirectory($io);
133 14
134
        $paths = $this->getPathArguments($io);
135 14
        $outputDir = $this->getOutputDir($io);
136 12
137
        $config = $this->retrieveConfig($io, $paths);
138 12
139
        $this->getScoper($config)->scope(
140
            $io,
141
            $config,
142 12
            $paths,
143 12
            $outputDir,
144 12
            $io->getBooleanOption(self::STOP_ON_FAILURE_OPT),
145
        );
146
147 12
        return ExitCode::SUCCESS;
148 12
    }
149 12
150
    private function getOutputDir(IO $io): string
151
    {
152
        $outputDir = $io->getStringOption(self::OUTPUT_DIR_OPT);
153 12
154 12
        if (false === $this->fileSystem->isAbsolutePath($outputDir)) {
155 12
            $outputDir = getcwd().DIRECTORY_SEPARATOR.$outputDir;
156 12
        }
157 12
158 12
        if (false === $this->fileSystem->exists($outputDir)) {
159 12
            return $outputDir;
160 12
        }
161
162
        if (false === is_writable($outputDir)) {
163
            throw new RuntimeException(
164
                sprintf(
165
                    'Expected "<comment>%s</comment>" to be writeable.',
166
                    $outputDir
167
                )
168
            );
169
        }
170 12
171
        if ($io->getBooleanOption(self::FORCE_OPT)) {
172 12
            $this->fileSystem->remove($outputDir);
173
174
            return $outputDir;
175
        }
176
177
        $question = sprintf(
178 12
            is_dir($outputDir)
179
                ? 'The output directory "<comment>%s</comment>" already exists. Continuing will erase its content, do you wish to proceed?'
180
                : 'Expected "<comment>%s</comment>" to be a directory but found a file instead. It will be  removed, do you wish to proceed?',
181
            $outputDir,
182
        );
183
184
        $canDeleteFile = $io->confirm($question, false);
185
186
        if ($canDeleteFile) {
187
            $this->fileSystem->remove($outputDir);
188 12
        }
189
190 12
        return $outputDir;
191
    }
192 12
193 12
    /**
194
     * @param string[] $paths
195 12
     */
196 12
    private function retrieveConfig(IO $io, array $paths): Configuration
197
    {
198 12
        $configLoader = new ConfigLoader(
199 12
            $this->getCommandRegistry(),
200
            $this->fileSystem,
201
        );
202
203 12
        return $configLoader->loadConfig(
204 12
            $io,
205 12
            $io->getStringOption(self::PREFIX_OPT),
206 12
            $io->getBooleanOption(self::NO_CONFIG_OPT),
207 12
            $io->getNullableStringOption(self::CONFIG_FILE_OPT),
208 12
            self::DEFAULT_CONFIG_FILE_PATH,
209 12
            $this->init,
210 12
            $paths,
211 12
            getcwd(),
212
        );
213
    }
214
215 12
    /**
216
     * @return list<string> List of absolute paths
1 ignored issue
show
Bug introduced by
The type Humbug\PhpScoper\Console\Command\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
217 12
     */
218 12
    private function getPathArguments(IO $io): array
219
    {
220
        $cwd = getcwd();
221 12
        $fileSystem = $this->fileSystem;
222
223
        return array_map(
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_map(functio...gument(self::PATH_ARG)) returns the type array which is incompatible with the documented return type Humbug\PhpScoper\Console\Command\list.
Loading history...
224 12
            static fn (string $path) => $fileSystem->isAbsolutePath($path)
225
                ? $path
226 12
                : $cwd.DIRECTORY_SEPARATOR.$path,
227
            $io->getStringArrayArgument(self::PATH_ARG),
228
        );
229
    }
230
231
    private function getScoper(Configuration $config): ConsoleScoper
232
    {
233
        return new ConsoleScoper(
234
            $this->fileSystem,
235
            $this->application,
236 12
            $this->getInnerScoper($config),
237
        );
238
    }
239
240
    private function getInnerScoper(Configuration $config): Scoper
241
    {
242
        if (count($config->getWhitelistedFiles()) === 0) {
243
            return $this->scoper;
244
        }
245
246
        return $this->scoper->withWhitelistedFiles(
247 12
            ...$config->getWhitelistedFiles(),
248 2
        );
249 2
    }
250
}
251