Completed
Pull Request — master (#120)
by Marco
04:14
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 chdir;
16
use function getcwd;
17
18
final class LocateDependenciesViaComposer implements LocateDependencies
19
{
20
    /** @var Locator */
21
    private $astLocator;
22
23
    /** @var callable */
24
    private $makeComposerInstaller;
25
26
    /**
27
     * @psalm-param callable () : Installer $makeComposerInstaller
28
     */
29
    public function __construct(
30
        callable $makeComposerInstaller,
31
        Locator $astLocator
32
    ) {
33
        // This is needed because the CWD of composer cannot be changed at runtime, but only at startup
34
        $this->makeComposerInstaller = $makeComposerInstaller;
35
        $this->astLocator            = $astLocator;
36
    }
37
38
    public function __invoke(string $installationPath) : SourceLocator
39
    {
40
        Assert::that($installationPath)->directory();
41
        Assert::that($installationPath . '/composer.json')->file();
42
43
        $this->runInDirectory(function () use ($installationPath) : void {
44
            $installer = ($this->makeComposerInstaller)($installationPath);
45
46
            Assert::that($installer)->isInstanceOf(Installer::class);
47
            assert($installer instanceof Installer);
48
49
            // Some defaults needed for this specific implementation:
50
            $installer->setDevMode(false);
51
            $installer->setDumpAutoloader(false);
52
            $installer->setRunScripts(false);
53
            $installer->setIgnorePlatformRequirements(true);
54
55
            $installer->run();
56
        }, $installationPath);
57
58
        return new AggregateSourceLocator([
59
            (new MakeLocatorForInstalledJson())->__invoke($installationPath, $this->astLocator),
60
            new PhpInternalSourceLocator($this->astLocator),
61
        ]);
62
    }
63
64
    private function runInDirectory(callable $callable, string $directoryOfExecution) : void
65
    {
66
        $originalDirectory = getcwd();
67
68
        Assert::that($originalDirectory)->string();
69
70
        try {
71
            chdir($directoryOfExecution);
72
            $callable();
73
        } finally {
74
            chdir($originalDirectory);
75
        }
76
    }
77
}
78