Completed
Push — 3.0 ( 46111f...d5ff83 )
by Daniel
02:06
created

ModuleManager::getInstalls()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.004

Importance

Changes 5
Bugs 2 Features 2
Metric Value
c 5
b 2
f 2
dl 0
loc 24
ccs 12
cts 13
cp 0.9231
rs 8.9713
cc 3
eloc 12
nc 1
nop 1
crap 3.004
1
<?php
2
3
namespace MagentoHackathon\Composer\Magento;
4
5
use Composer\Package\PackageInterface;
6
use MagentoHackathon\Composer\Magento\Deploy\Manager\Entry;
7
use MagentoHackathon\Composer\Magento\Event\EventManager;
8
use MagentoHackathon\Composer\Magento\Event\PackageDeployEvent;
9
use MagentoHackathon\Composer\Magento\Event\PackageUnInstallEvent;
10
use MagentoHackathon\Composer\Magento\Factory\InstallStrategyFactory;
11
use MagentoHackathon\Composer\Magento\Repository\InstalledPackageRepositoryInterface;
12
use MagentoHackathon\Composer\Magento\UnInstallStrategy\UnInstallStrategyInterface;
13
14
/**
15
 * Class ModuleManager
16
 * @package MagentoHackathon\Composer\Magento
17
 * @author  Aydin Hassan <[email protected]>
18
 */
19
class ModuleManager
20
{
21
    /**
22
     * @var InstalledPackageRepositoryInterface
23
     */
24
    protected $installedPackageRepository;
25
26
    /**
27
     * @var EventManager
28
     */
29
    protected $eventManager;
30
31
    /**
32
     * @var ProjectConfig
33
     */
34
    protected $config;
35
36
    /**
37
     * @var UnInstallStrategyInterface
38
     */
39
    protected $unInstallStrategy;
40
41
    /**
42
     * @var InstallStrategyFactory
43
     */
44
    protected $installStrategyFactory;
45
46
    /**
47
     * @param InstalledPackageRepositoryInterface $installedRepository
48
     * @param EventManager $eventManager
49
     * @param ProjectConfig $config
50
     * @param UnInstallStrategyInterface $unInstallStrategy
51
     * @param InstallStrategyFactory $installStrategyFactory
52
     */
53 7
    public function __construct(
54
        InstalledPackageRepositoryInterface $installedRepository,
55
        EventManager $eventManager,
56
        ProjectConfig $config,
57
        UnInstallStrategyInterface $unInstallStrategy,
58
        InstallStrategyFactory $installStrategyFactory
59
    ) {
60 7
        $this->installedPackageRepository = $installedRepository;
61 7
        $this->eventManager = $eventManager;
62 7
        $this->config = $config;
63 7
        $this->unInstallStrategy = $unInstallStrategy;
64 7
        $this->installStrategyFactory = $installStrategyFactory;
65 7
    }
66
67
    /**
68
     * @param array $currentComposerInstalledPackages
69
     * @return array
70
     */
71 7
    public function updateInstalledPackages(array $currentComposerInstalledPackages)
72
    {
73 7
        $packagesToRemove = $this->getRemoves(
74 7
            $currentComposerInstalledPackages,
75 7
            $this->installedPackageRepository->findAll()
76 7
        );
77
78 7
        $packagesToInstall  = $this->getInstalls($currentComposerInstalledPackages);
79
80 7
        $this->doRemoves($packagesToRemove);
81 7
        $this->doInstalls($packagesToInstall);
82
83
        return array(
84 7
            $packagesToRemove,
85
            $packagesToInstall
86 7
        );
87
    }
88
89
    /**
90
     * @param PackageInterface[] $packagesToInstall
91
     */
92 7
    public function doInstalls(array $packagesToInstall)
93
    {
94 7
        foreach ($packagesToInstall as $install) {
95 5
            $installStrategy = $this->installStrategyFactory->make(
96 5
                $install,
97 5
                $this->getPackageSourceDirectory($install)
98 5
            );
99
100 5
            $deployEntry = new Entry();
101 5
            $deployEntry->setPackageName($install->getPrettyName());
102 5
            $deployEntry->setDeployStrategy($installStrategy);
103 5
            $this->eventManager->dispatch(
104 5
                new PackageDeployEvent('pre-package-deploy', $deployEntry)
105 5
            );
106 5
            $files = $installStrategy->deploy()->getDeployedFiles();
107 5
            $this->eventManager->dispatch(
108 5
                new PackageDeployEvent('post-package-deploy', $deployEntry)
109 5
            );
110 5
            $this->installedPackageRepository->add(new InstalledPackage(
111 5
                $install->getName(),
112 5
                $this->createVersion($install),
113
                $files
114 5
            ));
115 7
        }
116 7
    }
117
118
    /**
119
     * @param InstalledPackage[] $packagesToRemove
120
     */
121 7
    public function doRemoves(array $packagesToRemove)
122
    {
123 7
        foreach ($packagesToRemove as $remove) {
124 5
            $this->eventManager->dispatch(new PackageUnInstallEvent('pre-package-uninstall', $remove));
125 5
            $this->unInstallStrategy->unInstall($remove->getInstalledFiles());
126 5
            $this->eventManager->dispatch(new PackageUnInstallEvent('post-package-uninstall', $remove));
127 5
            $this->installedPackageRepository->remove($remove);
128 7
        }
129 7
    }
130
131
    /**
132
     * @param PackageInterface[] $currentComposerInstalledPackages
133
     * @param InstalledPackage[] $magentoInstalledPackages
134
     * @return InstalledPackage[]
135
     */
136 7
    public function getRemoves(array $currentComposerInstalledPackages, array $magentoInstalledPackages)
137
    {
138
        //make the package names as the array keys
139 7
        if (count($currentComposerInstalledPackages)) {
140 6
            $currentComposerInstalledPackages = array_combine(
141 6
                array_map(
142
                    function (PackageInterface $package) {
143 6
                        return $package->getName();
144 6
                    },
145
                    $currentComposerInstalledPackages
146 6
                ),
147
                $currentComposerInstalledPackages
148 6
            );
149 6
        }
150 7
        return array_filter(
151 7
            $magentoInstalledPackages,
152
            function (InstalledPackage $package) use ($currentComposerInstalledPackages) {
153 6
                if (!isset($currentComposerInstalledPackages[$package->getName()])) {
154 2
                    return true;
155
                }
156
157 5
                $composerPackage = $currentComposerInstalledPackages[$package->getName()];
158 5
                return $package->getVersion() !== $this->createVersion($composerPackage);
159
            }
160 7
        );
161
    }
162
163
    /**
164
     * @param PackageInterface[] $currentComposerInstalledPackages
165
     * @return PackageInterface[]
166
     */
167 7
    public function getInstalls(array $currentComposerInstalledPackages)
168
    {
169 7
        $repo = $this->installedPackageRepository;
170
        $packages = array_filter($currentComposerInstalledPackages, function (PackageInterface $package) use ($repo) {
171 6
            return !$repo->has($package->getName(), $this->createVersion($package));
172 7
        });
173
174 7
        $config = $this->config;
175 7
        usort($packages, function (PackageInterface $aObject, PackageInterface $bObject) use ($config) {
176 1
            $a = $config->getModuleSpecificSortValue($aObject->getName());
177 1
            $b = $config->getModuleSpecificSortValue($bObject->getName());
178 1
            if ($a == $b) {
179 1
                return strcmp($aObject->getName(), $bObject->getName());
180
                /**
181
                 * still changes sort order and breaks a test, so for now strcmp as workaround
182
                 * to keep the test working.
183
                 */
184
                // return 0;
185
            }
186
            return ($a < $b) ? -1 : 1;
187 7
        });
188
189 7
        return $packages;
190
    }
191
192
    /**
193
     * @param PackageInterface $package
194
     * @return string
195
     */
196 5
    private function getPackageSourceDirectory(PackageInterface $package)
197
    {
198 5
        $path = sprintf("%s/%s", $this->config->getVendorDir(), $package->getPrettyName());
199 5
        $targetDir = $package->getTargetDir();
200
201 5
        if ($targetDir) {
202
            $path = sprintf("%s/%s", $path, $targetDir);
203
        }
204
205 5
        $path = realpath($path);
206 5
        return $path;
207
    }
208
209
    /**
210
     * Create a version string which is unique. dev-master
211
     * packages report a version of 9999999-dev. We need a unique version
212
     * so we can detect changes. here we use the source reference which
213
     * in the case of git is the commit hash
214
     *
215
     * @param PackageInterface $package
216
     *
217
     * @return string
218
     */
219 6
    private function createVersion(PackageInterface $package)
220
    {
221 6
        $version = $package->getVersion();
222
223 6
        if (null !== $package->getSourceReference()) {
224 1
            $version = sprintf('%s-%s', $version, $package->getSourceReference());
225 1
        }
226
227 6
        return $version;
228
    }
229
}
230