Completed
Push — 3.0 ( 46e3af...f23b72 )
by Daniel
03:20
created

ModuleManager::createVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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