Passed
Push — master ( 165520...cfabca )
by Théo
12:07 queued 10:05
created

ConfigLoader::loadConfig()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 50
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

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

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
        } elseif (null !== $configFilePath) {
82
            $configFilePath = $this->makeAbsolutePath(
83
                $configFilePath,
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);
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
    private static function configurePaths(
207
        Configuration $config,
208
        string $cwd
209
    ): Configuration
210
    {
211
        // Use the current working directory as the path if no file has been
212
        // found
213
        if (0 === count($config->getFilesWithContents())) {
214
            return $config->withPaths([$cwd]);
215
        }
216
217
        return $config;
218
    }
219
220
    private static function generateRandomPrefix(): string
221
    {
222
        return '_PhpScoper'.bin2hex(random_bytes(6));
223
    }
224
225
    private function makeAbsolutePath(
226
        string $path,
227
        string $cwd
228
    ): string
229
    {
230
        if (false === $this->fileSystem->isAbsolutePath($path)) {
231
            $path = $cwd.DIRECTORY_SEPARATOR.$path;
232
        }
233
234
        return $path;
235
    }
236
}
237