Completed
Pull Request — master (#5)
by David
02:09
created

AssetsBuilder   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 9
dl 0
loc 103
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A findAssetTypes() 0 16 1
B buildAssetTypes() 0 24 5
A getDiscoveryJson() 0 14 1
1
<?php
2
3
4
namespace TheCodingMachine\Discovery;
5
6
use Composer\Installer\InstallationManager;
7
use Composer\IO\IOInterface;
8
use Composer\Package\PackageInterface;
9
use Composer\Repository\RepositoryInterface;
10
use Symfony\Component\Filesystem\Filesystem;
11
use TheCodingMachine\Discovery\Utils\JsonException;
12
13
/**
14
 * Transforms discovery.json files into arrays of assets.
15
 */
16
class AssetsBuilder
17
{
18
19
20
    /**
21
     * @var InstallationManager
22
     */
23
    private $installationManager;
24
    /**
25
     * @var IOInterface
26
     */
27
    private $io;
28
    /**
29
     * @var string
30
     */
31
    private $rootDir;
32
33
    public function __construct(InstallationManager $installationManager, IOInterface $io, string $rootDir)
34
    {
35
        $this->installationManager = $installationManager;
36
        $this->io = $io;
37
        $this->rootDir = $rootDir;
38
    }
39
40
    /**
41
     * Find discovery.json files in the passed repository and builds an asset type.
42
     *
43
     * @param RepositoryInterface $repository
44
     * @return AssetType[]
45
     */
46
    public function findAssetTypes(RepositoryInterface $repository) : array
47
    {
48
        $unorderedPackagesList = $repository->getPackages();
49
50
        $orderedPackageList = PackagesOrderer::reorderPackages($unorderedPackagesList);
51
52
        $packages = array_filter($orderedPackageList, function (PackageInterface $package) {
53
            $installationManager = $this->installationManager;
54
55
            $packageInstallPath = $installationManager->getInstallPath($package);
56
57
            return file_exists($packageInstallPath.'/discovery.json');
58
        });
59
60
        return $this->buildAssetTypes($packages);
61
    }
62
63
    /**
64
     * Builds the AssetTypes that will be exported in the generated TheCodingMachine\Discovery class.
65
     *
66
     * @param PackageInterface[] $discoveryPackages
67
     *
68
     * @return AssetType[] An array of AssetType, indexed by asset type name.
69
     */
70
    public function buildAssetTypes(array $discoveryPackages) : array
71
    {
72
        /* @var $assetTypes AssetType[] */
73
        $assetTypes = [];
74
75
        foreach ($discoveryPackages as $package) {
76
            try {
77
                $assetOperationsByType = $this->getDiscoveryJson($package);
78
                // TODO display warnings if problem with discovery.json without crashing!
79
80
                foreach ($assetOperationsByType as $type => $assetOperations) {
81
                    $assetTypes[$type] = $assetTypes[$type] ?? new AssetType($type);
82
83
                    foreach ($assetOperations as $assetOperation) {
84
                        $assetTypes[$type]->addAssetOperation($assetOperation);
85
                    }
86
                }
87
            } catch (JsonException $exception) {
88
                $this->io->writeError($exception->getMessage());
89
            }
90
        }
91
92
        return $assetTypes;
93
    }
94
95
    /**
96
     * Returns the parsed JSON of the discovery.json file of a package.
97
     *
98
     * @param PackageInterface $package
99
     *
100
     * @return AssetOperation[][]
101
     *
102
     * @throws \TheCodingMachine\Discovery\Utils\JsonException
103
     */
104
    private function getDiscoveryJson(PackageInterface $package) : array
105
    {
106
        $packageInstallPath = $this->installationManager->getInstallPath($package);
107
108
        $fileSystem = new Filesystem();
109
110
        $packageDir = $fileSystem->makePathRelative($packageInstallPath, realpath($this->rootDir));
111
112
        $path = $packageInstallPath.'/discovery.json';
113
114
        $discoveryFileLoader = new DiscoveryFileLoader();
115
116
        return $discoveryFileLoader->loadDiscoveryFile(new \SplFileInfo($path), $package->getName(), $packageDir);
117
    }
118
}
119