Failed Conditions
Pull Request — master (#47)
by Mateusz
24:21
created

CacheManagerImpl::checkPackageFilesModified()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 15
ccs 0
cts 12
cp 0
rs 9.4285
cc 3
eloc 8
nc 3
nop 0
crap 12
1
<?php
2
3
/*
4
 * This file is part of the puli/manager package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Manager\Cache;
13
14
use Puli\Manager\Api\Cache\CacheFile;
15
use Puli\Manager\Api\Cache\CacheManager;
16
use Puli\Manager\Api\Config\Config;
17
use Puli\Manager\Api\Context\ProjectContext;
18
use Puli\Manager\Api\Package\Package;
19
use Puli\Manager\Api\Package\PackageCollection;
20
use Puli\Manager\Api\Package\PackageFile;
21
use Puli\Manager\Api\Package\PackageManager;
22
use Puli\Manager\Api\Package\RootPackage;
23
use Puli\Manager\Assert\Assert;
24
use Webmozart\Expression\Expr;
25
use Webmozart\Expression\Expression;
26
use Webmozart\PathUtil\Path;
27
28
/**
29
 * Manages cached packages information.
30
 *
31
 * @since  1.0
32
 *
33
 * @author Mateusz Sojda <[email protected]>
34
 */
35
class CacheManagerImpl implements CacheManager
36
{
37
    /**
38
     * @var PackageManager
39
     */
40
    private $packageManager;
41
42
    /**
43
     * @var CacheFileStorage
44
     */
45
    private $storage;
46
47
    /**
48
     * @var ProjectContext
49
     */
50
    private $context;
51
52
    /**
53
     * @var string
54
     */
55
    private $rootDir;
56
57
    /**
58
     * Creates new cache manager.
59
     *
60
     * @param PackageManager    $packageManager  The package manager.
61
     * @param CacheFileStorage  $storage         The file storage.
62
     * @param ProjectContext    $context         Project context.
63
     */
64
    public function __construct(PackageManager $packageManager, CacheFileStorage $storage, ProjectContext $context)
65
    {
66
        $this->packageManager = $packageManager;
67
        $this->storage = $storage;
68
        $this->context = $context;
69
        $this->rootDir = $context->getRootDirectory();
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function getContext()
76
    {
77
        return $this->context;
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function getCacheFile()
84
    {
85
        $path = $this->getContext()->getConfig()->get(Config::CACHE_FILE);
86
        $path = Path::makeAbsolute($path, $this->rootDir);
87
88
        if (false === $this->storage->cacheFileExists($path)) {
89
            $this->refreshCacheFile();
90
        }
91
92
        $cacheFile = $this->storage->loadCacheFile($path);
93
94
        return $cacheFile;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function refreshCacheFile()
101
    {
102
        $path = $this->getContext()->getConfig()->get(Config::CACHE_FILE);
103
104
        if ($this->storage->cacheFileExists($path) || false === $this->checkPackageFilesModified()) {
105
            return;
106
        }
107
108
        $cacheFile = new CacheFile(Path::makeAbsolute($path, $this->rootDir));
109
110
        foreach ($this->getInstalledPackages() as $package) {
111
            $packageFile = $package->getPackageFile();
112
            if (false === $packageFile instanceof PackageFile) {
113
                continue;
114
            }
115
116
            $cacheFile->addPackageFile($packageFile);
117
118
            $installInfo = $package->getInstallInfo();
119
            $cacheFile->addInstallInfo($installInfo);
120
        }
121
122
        $this->storage->saveCacheFile($cacheFile);
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function getPackage($name)
129
    {
130
        Assert::string($name, 'The package name must be a string. Got: %s');
131
132
        $cacheFile = $this->getCacheFile();
133
        $packageFile = $cacheFile->getPackageFile($name);
134
135
        return $this->buildPackage($packageFile, $cacheFile);
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function getRootPackage()
142
    {
143
        return new RootPackage(
144
            $this->getContext()->getRootPackageFile(),
145
            $this->rootDir
146
        );
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function getPackages()
153
    {
154
        $cacheFile = $this->getCacheFile();
155
        $packages = new PackageCollection();
156
157
        foreach ($cacheFile->getPackageFiles() as $packageFile) {
158
            $package = $this->buildPackage($packageFile, $cacheFile);
159
            $packages->add($package);
160
        }
161
162
        return $packages;
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168
    public function findPackages(Expression $expr)
169
    {
170
        $cacheFile = $this->getCacheFile();
171
        $packages = new PackageCollection();
172
173
        foreach ($cacheFile->getPackageFiles() as $packageFile) {
174
            $package = $this->buildPackage($packageFile, $cacheFile);
175
176
            if ($expr->evaluate($package)) {
177
                $packages->add($package);
178
            }
179
        }
180
181
        return $packages;
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187
    public function hasPackage($name)
188
    {
189
        Assert::string($name, 'The package name must be a string. Got: %s');
190
191
        $cacheFile = $this->getCacheFile();
192
193
        return $cacheFile->hasPackageFile($name);
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function hasPackages(Expression $expr = null)
200
    {
201
        $cacheFile = $this->getCacheFile();
202
203
        if (!$expr) {
204
            return $cacheFile->hasPackageFiles();
205
        }
206
207
        foreach ($this->getPackages() as $package) {
208
            if ($expr->evaluate($package)) {
209
                return true;
210
            }
211
        }
212
213
        return false;
214
    }
215
216
    private function getInstalledPackages()
217
    {
218
        $packages = $this->packageManager->findPackages(Expr::true());
219
220
        return $packages->getInstalledPackages();
221
    }
222
223
    private function buildPackage(PackageFile $packageFile, CacheFile $cacheFile)
224
    {
225
        $installInfo = $cacheFile->getInstallInfo($packageFile->getPackageName());
226
        $installPath = Path::makeAbsolute($installInfo->getInstallPath(), $this->rootDir);
227
228
        return new Package($packageFile, $installPath, $installInfo);
229
    }
230
231
    private function checkPackageFilesModified()
232
    {
233
        $cacheFile = $this->getCacheFile();
234
        $cacheFileMtime = filemtime($cacheFile->getPath());
235
236
        foreach ($cacheFile->getInstallInfos() as $installInfo) {
237
            $packageFilePath = Path::makeAbsolute("{$installInfo->getInstallPath()}/puli.json", $this->rootDir);
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $installInfo instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
238
239
            if (filemtime($packageFilePath) > $cacheFileMtime) {
240
                return true;
241
            }
242
        }
243
244
        return false;
245
    }
246
}