Issues (224)

src/Composer/ComposerOrchestrator.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14
15
namespace KevinGH\Box\Composer;
16
17
use Composer\Semver\Semver;
18
use Fidry\Console\IO;
0 ignored issues
show
The type Fidry\Console\IO 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...
19
use Fidry\FileSystem\FileSystem;
20
use Humbug\PhpScoper\Symbol\SymbolsRegistry;
21
use KevinGH\Box\Composer\Throwable\IncompatibleComposerVersion;
22
use KevinGH\Box\Composer\Throwable\UndetectableComposerVersion;
23
use KevinGH\Box\NotInstantiable;
24
use Psr\Log\LoggerInterface;
25
use Psr\Log\NullLogger;
26
use RuntimeException;
27
use Symfony\Component\Process\Exception\ProcessFailedException;
28
use function sprintf;
29
use function trim;
30
use const PHP_EOL;
31
32
/**
33
 * @private
34
 */
35
final class ComposerOrchestrator
36
{
37
    use NotInstantiable;
38
39
    public const SUPPORTED_VERSION_CONSTRAINTS = '^2.2.0';
40
41
    private string $detectedVersion;
42
43
    public static function create(): self
44
    {
45
        return new self(
46
            ComposerProcessFactory::create(io: IO::createNull()),
47
            new NullLogger(),
48
            new FileSystem(),
49
        );
50
    }
51
52
    public function __construct(
53
        private readonly ComposerProcessFactory $processFactory,
54
        private readonly LoggerInterface $logger,
55
        private readonly FileSystem $fileSystem,
56
    ) {
57
    }
58
59
    /**
60
     * @throws UndetectableComposerVersion
61
     */
62
    public function getVersion(): string
63
    {
64
        if (isset($this->detectedVersion)) {
65
            return $this->detectedVersion;
66
        }
67
68
        $getVersionProcess = $this->processFactory->getVersionProcess();
69
70
        $this->logger->info($getVersionProcess->getCommandLine());
71
72
        $getVersionProcess->run();
73
74
        if (false === $getVersionProcess->isSuccessful()) {
75
            throw UndetectableComposerVersion::forFailedProcess($getVersionProcess);
76
        }
77
78
        $output = $getVersionProcess->getOutput();
79
80
        if (1 !== preg_match('/Composer version (\S+?) /', $output, $match)) {
81
            throw UndetectableComposerVersion::forOutput(
82
                $getVersionProcess,
83
                $output,
84
            );
85
        }
86
87
        $this->detectedVersion = $match[1];
88
89
        return $this->detectedVersion;
90
    }
91
92
    /**
93
     * @throws UndetectableComposerVersion
94
     * @throws IncompatibleComposerVersion
95
     */
96
    public function checkVersion(): void
97
    {
98
        $version = $this->getVersion();
99
100
        $this->logger->info(
101
            sprintf(
102
                'Version detected: %s (Box requires %s)',
103
                $version,
104
                self::SUPPORTED_VERSION_CONSTRAINTS,
105
            ),
106
        );
107
108
        if (!Semver::satisfies($version, self::SUPPORTED_VERSION_CONSTRAINTS)) {
109
            throw IncompatibleComposerVersion::create($version, self::SUPPORTED_VERSION_CONSTRAINTS);
110
        }
111
    }
112
113
    public function dumpAutoload(
114
        SymbolsRegistry $symbolsRegistry,
115
        string $prefix,
116
        bool $excludeDevFiles,
117
        array $excludedComposerAutoloadFileHashes,
118
    ): void {
119
        $this->dumpAutoloader(true === $excludeDevFiles);
120
121
        if ('' === $prefix) {
122
            return;
123
        }
124
125
        $autoloadFile = $this->getVendorDir().'/autoload.php';
126
127
        $autoloadContents = AutoloadDumper::generateAutoloadStatements(
128
            $symbolsRegistry,
129
            $excludedComposerAutoloadFileHashes,
130
            $this->fileSystem->getFileContents($autoloadFile),
131
        );
132
133
        $this->fileSystem->dumpFile($autoloadFile, $autoloadContents);
134
    }
135
136
    public function getVendorDir(): string
137
    {
138
        $vendorDirProcess = $this->processFactory->getVendorDirProcess();
139
140
        $this->logger->info($vendorDirProcess->getCommandLine());
141
142
        $vendorDirProcess->run();
143
144
        if (false === $vendorDirProcess->isSuccessful()) {
145
            throw new RuntimeException(
146
                'Could not retrieve the vendor dir.',
147
                0,
148
                new ProcessFailedException($vendorDirProcess),
149
            );
150
        }
151
152
        return trim($vendorDirProcess->getOutput());
153
    }
154
155
    private function dumpAutoloader(bool $noDev): void
156
    {
157
        $dumpAutoloadProcess = $this->processFactory->getDumpAutoloaderProcess($noDev);
158
159
        $this->logger->info($dumpAutoloadProcess->getCommandLine());
160
161
        $dumpAutoloadProcess->run();
162
163
        if (false === $dumpAutoloadProcess->isSuccessful()) {
164
            throw new RuntimeException(
165
                'Could not dump the autoloader.',
166
                0,
167
                new ProcessFailedException($dumpAutoloadProcess),
168
            );
169
        }
170
171
        $output = $dumpAutoloadProcess->getOutput();
172
        $errorOutput = $dumpAutoloadProcess->getErrorOutput();
173
174
        if ('' !== $output) {
175
            $this->logger->info(
176
                'STDOUT output:'.PHP_EOL.$output,
177
                ['stdout' => $output],
178
            );
179
        }
180
181
        if ('' !== $errorOutput) {
182
            $this->logger->info(
183
                'STDERR output:'.PHP_EOL.$errorOutput,
184
                ['stderr' => $errorOutput],
185
            );
186
        }
187
    }
188
}
189