Passed
Push — master ( a14eec...8c9177 )
by Théo
02:07
created

ConfigLoader::canonicalizePath()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 11
rs 10
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\Configuration;
10
use Humbug\PhpScoper\Configuration\ConfigurationFactory;
11
use Symfony\Component\Console\Exception\RuntimeException;
12
use Symfony\Component\Console\Input\StringInput;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Filesystem\Filesystem;
15
use Symfony\Component\Filesystem\Path;
16
use function assert;
17
use function count;
18
use function file_exists;
19
use function Safe\sprintf;
20
use function trim;
21
use const DIRECTORY_SEPARATOR;
22
23
/**
24
 * @private
25
 */
26
final class ConfigLoader
27
{
28
    private CommandRegistry $commandRegistry;
29
    private Filesystem $fileSystem;
30
    private ConfigurationFactory $configFactory;
31
32
    public function __construct(
33
        CommandRegistry $commandRegistry,
34
        Filesystem $fileSystem,
35
        ConfigurationFactory $configFactory
36
    ) {
37
        $this->commandRegistry = $commandRegistry;
38
        $this->fileSystem = $fileSystem;
39
        $this->configFactory = $configFactory;
40
    }
41
42
    /**
43
     * @param non-empty-string|null $configFilePath Canonical absolute path
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string|null at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string|null.
Loading history...
44
     * @param non-empty-string $defaultConfigFilePath
45
     * @param list<non-empty-string> $paths List of canonical absolute paths
46
     */
47
    public function loadConfig(
48
        IO $io,
49
        string $prefix,
50
        bool $noConfig,
51
        ?string $configFilePath,
52
        string $defaultConfigFilePath,
53
        bool $isInitCommandExecuted,
54
        array $paths,
55
        string $cwd
56
    ): Configuration
57
    {
58
        $prefix = trim($prefix);
59
        $defaultConfigFilePath = $this->canonicalizePath($defaultConfigFilePath, $cwd);
60
61
        if ($noConfig) {
62
            return $this->loadConfigWithoutConfigFile(
63
                $io,
64
                $prefix,
65
                $paths,
66
                $cwd,
67
            );
68
        }
69
70
        if (null === $configFilePath && !$isInitCommandExecuted) {
71
            $configFilePath = $this->loadDefaultConfig(
72
                $io,
73
                $defaultConfigFilePath,
74
            );
75
76
            if (null === $configFilePath) {
77
                return $this->loadConfig(
78
                    $io,
79
                    $prefix,
80
                    $noConfig,
81
                    $configFilePath,
82
                    $defaultConfigFilePath,
83
                    true,
84
                    $paths,
85
                    $cwd,
86
                );
87
            }
88
        }
89
90
        self::logConfigFilePathFound($io, $configFilePath);
91
92
        return $this->loadConfiguration($configFilePath, $prefix, $paths, $cwd);
93
    }
94
95
    /**
96
     * @param list<non-empty-string> $paths
0 ignored issues
show
Bug introduced by
The type Humbug\PhpScoper\Console\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...
97
     */
98
    private function loadConfigWithoutConfigFile(
99
        IO $io,
100
        string $prefix,
101
        array $paths,
102
        string $cwd
103
    ): Configuration
104
    {
105
        $io->writeln(
106
            'Loading without configuration file.',
107
            OutputInterface::VERBOSITY_DEBUG
108
        );
109
110
        return $this->loadConfiguration(null, $prefix, $paths, $cwd);
111
    }
112
113
    /**
114
     * @param non-empty-string $defaultConfigFilePath
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
115
     *
116
     * @return non-empty-string|null Config file path when found otherwise executes the init command
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string|null at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string|null.
Loading history...
117
     */
118
    private function loadDefaultConfig(IO $io, string $defaultConfigFilePath): ?string
119
    {
120
        $configFilePath = $defaultConfigFilePath;
121
122
        if (file_exists($configFilePath)) {
123
            return $configFilePath;
124
        }
125
126
        $initInput = new StringInput('');
127
        $initInput->setInteractive($io->isInteractive());
128
129
        $this->commandRegistry
130
            ->getCommand('init')
131
            ->execute(
132
                new IO(
133
                    $initInput,
134
                    $io->getOutput(),
135
                ),
136
            );
137
138
        $io->writeln(
139
            sprintf(
140
                'Config file "<comment>%s</comment>" not found. Skipping.',
141
                $configFilePath,
142
            ),
143
            OutputInterface::VERBOSITY_DEBUG,
144
        );
145
146
        return null;
147
    }
148
149
    private static function logConfigFilePathFound(IO $io, ?string $configFilePath): void
150
    {
151
        if (null === $configFilePath) {
152
            $io->writeln(
153
                'Loading without configuration file.',
154
                OutputInterface::VERBOSITY_DEBUG,
155
            );
156
157
            return;
158
        }
159
160
        if (!file_exists($configFilePath)) {
161
            throw new RuntimeException(
162
                sprintf(
163
                    'Could not find the configuration file "%s".',
164
                    $configFilePath,
165
                ),
166
            );
167
        }
168
169
        $io->writeln(
170
            sprintf(
171
                'Using the configuration file "%s".',
172
                $configFilePath,
173
            ),
174
            OutputInterface::VERBOSITY_DEBUG,
175
        );
176
    }
177
178
    /**
179
     * @param non-empty-string|null $configFilePath
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string|null at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string|null.
Loading history...
180
     * @param list<non-empty-string> $paths
181
     */
182
    private function loadConfiguration(
183
        ?string $configFilePath,
184
        string $prefix,
185
        array $paths,
186
        string $cwd
187
    ): Configuration
188
    {
189
        return $this->configurePaths(
190
            $this->configurePrefix(
191
                $this->configFactory->create($configFilePath, $paths),
192
                $prefix,
193
            ),
194
            $cwd,
195
        );
196
    }
197
198
    private function configurePrefix(Configuration $config, string $prefix): Configuration
199
    {
200
        if ('' !== $prefix) {
201
            return $this->configFactory->createWithPrefix(
202
                $config,
203
                $prefix,
204
            );
205
        }
206
207
        return $config;
208
    }
209
210
    private function configurePaths(
211
        Configuration $config,
212
        string $cwd
213
    ): Configuration
214
    {
215
        // Use the current working directory as the path if no file has been
216
        // found
217
        if (0 === count($config->getFilesWithContents())) {
218
            return $this->configFactory->createWithPaths(
219
                $config,
220
                [$cwd],
221
            );
222
        }
223
224
        return $config;
225
    }
226
227
    /**
228
     * @param non-empty-string $path
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
229
     *
230
     * @return non-empty-string Absolute canonical path
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
231
     */
232
    private function canonicalizePath(string $path, string $cwd): string
233
    {
234
        $canonicalPath = Path::canonicalize(
235
            $this->fileSystem->isAbsolutePath($path)
236
                ? $path
237
                : $cwd.DIRECTORY_SEPARATOR.$path,
238
        );
239
240
        assert('' !== $canonicalPath);
241
242
        return $canonicalPath;
243
    }
244
}
245