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

ConfigLoader::loadConfig()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 50
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 27
c 1
b 0
f 0
nc 4
nop 8
dl 0
loc 50
rs 9.1768

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
namespace Humbug\PhpScoper\Console;
6
7
use Fidry\Console\Command\CommandRegistry;
8
use Fidry\Console\IO;
9
use Humbug\PhpScoper\Configuration;
10
use Symfony\Component\Console\Exception\RuntimeException;
11
use Symfony\Component\Console\Input\StringInput;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Filesystem\Filesystem;
14
use function bin2hex;
15
use function count;
16
use function file_exists;
17
use function random_bytes;
18
use function Safe\sprintf;
19
use function trim;
20
use const DIRECTORY_SEPARATOR;
21
22
/**
23
 * @private
24
 */
25
final class ConfigLoader
26
{
27
    private CommandRegistry $commandRegistry;
28
    private Filesystem $fileSystem;
29
30
    public function __construct(
31
        CommandRegistry $commandRegistry,
32
        Filesystem $fileSystem
33
    ) {
34
        $this->commandRegistry = $commandRegistry;
35
        $this->fileSystem = $fileSystem;
36
    }
37
38
    /**
39
     * @param string[] $paths
40
     */
41
    public function loadConfig(
42
        IO $io,
43
        string $prefix,
44
        bool $noConfig,
45
        ?string $configFilePath,
46
        string $defaultConfigFilePath,
47
        bool $isInitCommandExecuted,
48
        array $paths,
49
        string $cwd
50
    ): Configuration
51
    {
52
        $prefix = trim($prefix);
53
54
        if ($noConfig) {
55
            return self::loadConfigWithoutConfigFile(
56
                $io,
57
                $prefix,
58
                $paths,
59
                $cwd,
60
            );
61
        }
62
63
        if (null === $configFilePath && !$isInitCommandExecuted) {
64
            $configFilePath = $this->loadDefaultConfig(
65
                $io,
66
                $this->makeAbsolutePath($defaultConfigFilePath, $cwd),
67
            );
68
69
            if (null === $configFilePath) {
70
                return $this->loadConfig(
71
                    $io,
72
                    $prefix,
73
                    $noConfig,
74
                    $configFilePath,
75
                    $defaultConfigFilePath,
76
                    true,
77
                    $paths,
78
                    $cwd,
79
                );
80
            }
81
        } else {
82
            $configFilePath = $this->makeAbsolutePath(
83
                $configFilePath,
0 ignored issues
show
Bug introduced by
It seems like $configFilePath can also be of type null; however, parameter $path of Humbug\PhpScoper\Console...der::makeAbsolutePath() 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

83
                /** @scrutinizer ignore-type */ $configFilePath,
Loading history...
84
                $cwd,
85
            );
86
        }
87
88
        self::logConfigFilePathFound($io, $configFilePath);
89
90
        return self::loadConfiguration($configFilePath, $prefix, $paths, $cwd);
91
    }
92
93
    /**
94
     * @param string[] $paths
95
     */
96
    private static function loadConfigWithoutConfigFile(
97
        IO $io,
98
        ?string $prefix,
99
        array $paths,
100
        string $cwd
101
    ): Configuration
102
    {
103
        $io->writeln(
104
            'Loading without configuration file.',
105
            OutputInterface::VERBOSITY_DEBUG
106
        );
107
108
        return self::loadConfiguration(null, $prefix, $paths, $cwd);
0 ignored issues
show
Bug introduced by
It seems like $prefix can also be of type null; however, parameter $prefix of Humbug\PhpScoper\Console...er::loadConfiguration() 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

108
        return self::loadConfiguration(null, /** @scrutinizer ignore-type */ $prefix, $paths, $cwd);
Loading history...
109
    }
110
111
    /**
112
     * @return string|null Config file path when found otherwise executes the init command
113
     */
114
    private function loadDefaultConfig(IO $io, string $defaultConfigFilePath): ?string
115
    {
116
        $configFilePath = $defaultConfigFilePath;
117
118
        if (file_exists($configFilePath)) {
119
            return $configFilePath;
120
        }
121
122
        $initInput = new StringInput('');
123
        $initInput->setInteractive($io->isInteractive());
124
125
        $this->commandRegistry
126
            ->getCommand('init')
127
            ->execute(
128
                new IO(
129
                    $initInput,
130
                    $io->getOutput(),
131
                ),
132
            );
133
134
        $io->writeln(
135
            sprintf(
136
                'Config file "<comment>%s</comment>" not found. Skipping.',
137
                $configFilePath,
138
            ),
139
            OutputInterface::VERBOSITY_DEBUG,
140
        );
141
142
        return null;
143
    }
144
145
    private static function logConfigFilePathFound(IO $io, ?string $configFilePath): void
146
    {
147
        if (null === $configFilePath) {
148
            $io->writeln(
149
                'Loading without configuration file.',
150
                OutputInterface::VERBOSITY_DEBUG,
151
            );
152
153
            return;
154
        }
155
156
        if (false === file_exists($configFilePath)) {
157
            throw new RuntimeException(
158
                sprintf(
159
                    'Could not find the configuration file "%s".',
160
                    $configFilePath,
161
                ),
162
            );
163
        }
164
165
        $io->writeln(
166
            sprintf(
167
                'Using the configuration file "%s".',
168
                $configFilePath,
169
            ),
170
            OutputInterface::VERBOSITY_DEBUG,
171
        );
172
    }
173
174
    /**
175
     * @param string[] $paths
176
     */
177
    private static function loadConfiguration(
178
        ?string $configFilePath,
179
        string $prefix,
180
        array $paths,
181
        string $cwd
182
    ): Configuration
183
    {
184
        return self::configurePaths(
185
            self::configurePrefix(
186
                Configuration::load($configFilePath, $paths),
187
                $prefix,
188
            ),
189
            $cwd,
190
        );
191
    }
192
193
    private static function configurePrefix(Configuration $config, string $prefix): Configuration
194
    {
195
        if ('' !== $prefix) {
196
            return $config->withPrefix($prefix);
197
        }
198
199
        if (null === $config->getPrefix()) {
200
            return $config->withPrefix(self::generateRandomPrefix());
201
        }
202
203
        return $config;
204
    }
205
206
    /**
207
     * @param string[] $paths
208
     */
209
    private static function configurePaths(
210
        Configuration $config,
211
        string $cwd
212
    ): Configuration
213
    {
214
        // Use the current working directory as the path if no file has been
215
        // found
216
        if (0 === count($config->getFilesWithContents())) {
217
            return $config->withPaths([$cwd]);
218
        }
219
220
        return $config;
221
    }
222
223
    private static function generateRandomPrefix(): string
224
    {
225
        return '_PhpScoper'.bin2hex(random_bytes(6));
226
    }
227
228
    private function makeAbsolutePath(
229
        string $path,
230
        string $cwd
231
    ): string
232
    {
233
        if (false === $this->fileSystem->isAbsolutePath($path)) {
234
            $path = $cwd.DIRECTORY_SEPARATOR.$path;
235
        }
236
237
        return $path;
238
    }
239
}
240