Passed
Pull Request — master (#120)
by Marco
06:44
created

LocateDependenciesViaComposer::sourceLocatorFromAutoloadStatic()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 1
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Roave\BackwardCompatibility\LocateDependencies;
6
7
use Assert\Assert;
8
use Composer\Installer;
9
use Roave\BetterReflection\SourceLocator\Ast\Locator;
10
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
11
use Roave\BetterReflection\SourceLocator\Type\Composer\Factory\MakeLocatorForInstalledJson;
12
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
13
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;
14
use function assert;
15
use function Safe\chdir;
16
use function Safe\getcwd;
17
18
final class LocateDependenciesViaComposer implements LocateDependencies
19
{
20
    /** @var Locator */
21
    private $astLocator;
22
23
    /** @var callable */
24
    private $makeComposerInstaller;
25
26
    public function __construct(
27
        callable $makeComposerInstaller,
28
        Locator $astLocator
29
    ) {
30
        // This is needed because the CWD of composer cannot be changed at runtime, but only at startup
31
        $this->makeComposerInstaller = $makeComposerInstaller;
32
        $this->astLocator            = $astLocator;
33
    }
34
35
    public function __invoke(string $installationPath) : SourceLocator
36
    {
37
        Assert::that($installationPath)->directory();
38
        Assert::that($installationPath . '/composer.json')->file();
39
40
        $this->runInDirectory(function () use ($installationPath) : void {
41
            $installer = ($this->makeComposerInstaller)($installationPath);
42
43
            Assert::that($installer)->isInstanceOf(Installer::class);
44
            assert($installer instanceof Installer);
45
46
            // Some defaults needed for this specific implementation:
47
            $installer->setDevMode(false);
48
            $installer->setDumpAutoloader(false);
49
            $installer->setRunScripts(false);
50
            $installer->setIgnorePlatformRequirements(true);
51
52
            $installer->run();
53
        }, $installationPath);
54
55
        return new AggregateSourceLocator([
56
            (new MakeLocatorForInstalledJson())->__invoke($installationPath, $this->astLocator),
57
            new PhpInternalSourceLocator($this->astLocator),
58
        ]);
59
    }
60
61
    private function runInDirectory(callable $callable, string $directoryOfExecution) : void
62
    {
63
        $originalDirectory = getcwd();
64
65
        Assert::that($originalDirectory)->string();
66
67
        try {
68
            chdir($directoryOfExecution);
69
            $callable();
70
        } finally {
71
            chdir($originalDirectory);
72
        }
73
    }
74
}
75