Skip to content

Commit ea68966

Browse files
committed
Fix cache:clear with buildDir
1 parent b81a03d commit ea68966

File tree

13 files changed

+108
-63
lines changed

13 files changed

+108
-63
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php

+39-27
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9191
}
9292

9393
$useBuildDir = $realBuildDir !== $realCacheDir;
94+
$oldBuildDir = substr($realBuildDir, 0, -1).('~' === substr($realBuildDir, -1) ? '+' : '~');
9495
if ($useBuildDir) {
95-
$oldBuildDir = substr($realBuildDir, 0, -1).('~' === substr($realBuildDir, -1) ? '+' : '~');
9696
$fs->remove($oldBuildDir);
9797

9898
if (!is_writable($realBuildDir)) {
9999
throw new RuntimeException(sprintf('Unable to write in the "%s" directory.', $realBuildDir));
100100
}
101+
102+
if ($this->isNfs($realCacheDir)) {
103+
$fs->remove($realCacheDir);
104+
} else {
105+
$fs->rename($realCacheDir, $oldCacheDir);
106+
}
107+
$fs->mkdir($realCacheDir);
101108
}
102109

103110
$io->comment(sprintf('Clearing the cache for the <info>%s</info> environment with debug <info>%s</info>', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));
@@ -114,7 +121,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
114121

115122
// the warmup cache dir name must have the same length as the real one
116123
// to avoid the many problems in serialized resources files
117-
$warmupDir = substr($realCacheDir, 0, -1).('_' === substr($realCacheDir, -1) ? '-' : '_');
124+
$warmupDir = substr($realBuildDir, 0, -1).('_' === substr($realBuildDir, -1) ? '-' : '_');
118125

119126
if ($output->isVerbose() && $fs->exists($warmupDir)) {
120127
$io->comment('Clearing outdated warmup directory...');
@@ -153,35 +160,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
153160
touch($warmupDir.'/'.$containerDir.'.legacy');
154161
}
155162

156-
if ('/' === \DIRECTORY_SEPARATOR && $mounts = @file('/proc/mounts')) {
157-
foreach ($mounts as $mount) {
158-
$mount = \array_slice(explode(' ', $mount), 1, -3);
159-
if (!\in_array(array_pop($mount), ['vboxsf', 'nfs'])) {
160-
continue;
161-
}
162-
$mount = implode(' ', $mount).'/';
163-
164-
if (0 === strpos($realCacheDir, $mount)) {
165-
$io->note('For better performances, you should move the cache and log directories to a non-shared folder of the VM.');
166-
$oldCacheDir = false;
167-
break;
168-
}
169-
}
170-
}
171-
172-
if ($oldCacheDir) {
173-
$fs->rename($realCacheDir, $oldCacheDir);
163+
if ($this->isNfs($realBuildDir)) {
164+
$io->note('For better performances, you should move the cache and log directories to a non-shared folder of the VM.');
165+
$fs->remove($realBuildDir);
174166
} else {
175-
$fs->remove($realCacheDir);
176-
}
177-
$fs->rename($warmupDir, $realCacheDir);
178-
179-
if ($useBuildDir) {
180167
$fs->rename($realBuildDir, $oldBuildDir);
181-
// Copy the content of the warmed cache in the build dir
182-
$fs->mirror($realCacheDir, $realBuildDir);
183168
}
184169

170+
$fs->rename($warmupDir, $realBuildDir);
171+
185172
if ($output->isVerbose()) {
186173
$io->comment('Removing old build and cache directory...');
187174
}
@@ -214,6 +201,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
214201
return 0;
215202
}
216203

204+
private function isNfs(string $dir): bool
205+
{
206+
static $mounts = null;
207+
208+
if (null === $mounts) {
209+
$mounts = [];
210+
if ('/' === \DIRECTORY_SEPARATOR && $mounts = @file('/proc/mounts')) {
211+
foreach ($mounts as $mount) {
212+
$mount = \array_slice(explode(' ', $mount), 1, -3);
213+
if (!\in_array(array_pop($mount), ['vboxsf', 'nfs'])) {
214+
continue;
215+
}
216+
$mounts[] = implode(' ', $mount).'/';
217+
}
218+
}
219+
}
220+
foreach ($mounts as $mount) {
221+
if (0 === strpos($dir, $mount)) {
222+
return true;
223+
}
224+
}
225+
226+
return false;
227+
}
228+
217229
private function warmup(string $warmupDir, string $realBuildDir, bool $enableOptionalWarmers = true)
218230
{
219231
// create a temporary kernel

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ protected function describeContainerEnvVars(array $envs, array $options = [])
157157

158158
protected function describeContainerDeprecations(ContainerBuilder $builder, array $options = []): void
159159
{
160-
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.cache_dir'), $builder->getParameter('kernel.container_class'));
160+
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.build_dir'), $builder->getParameter('kernel.container_class'));
161161
if (!file_exists($containerDeprecationFilePath)) {
162162
throw new RuntimeException('The deprecation file does not exist, please try warming the cache first.');
163163
}

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ protected function describeContainerService($service, array $options = [], Conta
107107

108108
protected function describeContainerDeprecations(ContainerBuilder $builder, array $options = []): void
109109
{
110-
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.cache_dir'), $builder->getParameter('kernel.container_class'));
110+
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.build_dir'), $builder->getParameter('kernel.container_class'));
111111
if (!file_exists($containerDeprecationFilePath)) {
112112
throw new RuntimeException('The deprecation file does not exist, please try warming the cache first.');
113113
}

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ protected function describeContainerDefinition(Definition $definition, array $op
360360

361361
protected function describeContainerDeprecations(ContainerBuilder $builder, array $options = []): void
362362
{
363-
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.cache_dir'), $builder->getParameter('kernel.container_class'));
363+
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.build_dir'), $builder->getParameter('kernel.container_class'));
364364
if (!file_exists($containerDeprecationFilePath)) {
365365
$options['output']->warning('The deprecation file does not exist, please try warming the cache first.');
366366

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ protected function describeContainerEnvVars(array $envs, array $options = [])
109109

110110
protected function describeContainerDeprecations(ContainerBuilder $builder, array $options = []): void
111111
{
112-
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.cache_dir'), $builder->getParameter('kernel.container_class'));
112+
$containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $builder->getParameter('kernel.build_dir'), $builder->getParameter('kernel.container_class'));
113113
if (!file_exists($containerDeprecationFilePath)) {
114114
throw new RuntimeException('The deprecation file does not exist, please try warming the cache first.');
115115
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ private function registerDebugConfiguration(array $config, ContainerBuilder $con
899899
$debug = $container->getParameter('kernel.debug');
900900

901901
if ($debug) {
902-
$container->setParameter('debug.container.dump', '%kernel.cache_dir%/%kernel.container_class%.xml');
902+
$container->setParameter('debug.container.dump', '%kernel.build_dir%/%kernel.container_class%.xml');
903903
}
904904

905905
if ($debug && class_exists(Stopwatch::class)) {

src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
->set('data_collector.logger', LoggerDataCollector::class)
5656
->args([
5757
service('logger')->ignoreOnInvalid(),
58-
sprintf('%s/%s', param('kernel.cache_dir'), param('kernel.container_class')),
58+
sprintf('%s/%s', param('kernel.build_dir'), param('kernel.container_class')),
5959
service('request_stack')->ignoreOnInvalid(),
6060
])
6161
->tag('monolog.logger', ['channel' => 'profiler'])

src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : []
109109
->args([
110110
tagged_iterator('kernel.cache_warmer'),
111111
param('kernel.debug'),
112-
sprintf('%s/%sDeprecations.log', param('kernel.cache_dir'), param('kernel.container_class')),
112+
sprintf('%s/%sDeprecations.log', param('kernel.build_dir'), param('kernel.container_class')),
113113
])
114114
->tag('container.no_preload')
115115

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php

+55-24
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
use Symfony\Component\Config\Resource\ResourceInterface;
1919
use Symfony\Component\Console\Input\ArrayInput;
2020
use Symfony\Component\Console\Output\NullOutput;
21+
use Symfony\Component\DependencyInjection\Container;
2122
use Symfony\Component\Filesystem\Filesystem;
2223
use Symfony\Component\Finder\Finder;
23-
use Symfony\Component\HttpKernel\KernelInterface;
2424

2525
class CacheClearCommandTest extends TestCase
2626
{
@@ -41,65 +41,96 @@ protected function tearDown(): void
4141
$this->fs->remove($this->kernel->getProjectDir());
4242
}
4343

44-
/** @dataProvider getKernel */
45-
public function testCacheIsFreshAfterCacheClearedWithWarmup(KernelInterface $kernel)
44+
public function testCacheIsFreshAfterCacheClearedWithWarmup()
4645
{
46+
$this->fs->mkdir($this->kernel->getProjectDir());
47+
4748
$input = new ArrayInput(['cache:clear']);
48-
$application = new Application($kernel);
49+
$application = new Application($this->kernel);
4950
$application->setCatchExceptions(false);
5051

5152
$application->doRun($input, new NullOutput());
5253

5354
// Ensure that all *.meta files are fresh
5455
$finder = new Finder();
55-
$metaFiles = $finder->files()->in($kernel->getCacheDir())->name('*.php.meta');
56+
$metaFiles = $finder->files()->in($this->kernel->getCacheDir())->name('*.php.meta');
5657
// check that cache is warmed up
5758
$this->assertNotEmpty($metaFiles);
5859
$configCacheFactory = new ConfigCacheFactory(true);
5960

6061
foreach ($metaFiles as $file) {
61-
$configCacheFactory->cache(substr($file, 0, -5), function () use ($file) {
62-
$this->fail(sprintf('Meta file "%s" is not fresh', (string) $file));
63-
});
62+
$configCacheFactory->cache(
63+
substr($file, 0, -5),
64+
function () use ($file) {
65+
$this->fail(sprintf('Meta file "%s" is not fresh', (string) $file));
66+
}
67+
);
6468
}
6569

6670
// check that app kernel file present in meta file of container's cache
67-
$containerClass = $kernel->getContainer()->getParameter('kernel.container_class');
71+
$containerClass = $this->kernel->getContainer()->getParameter('kernel.container_class');
6872
$containerRef = new \ReflectionClass($containerClass);
6973
$containerFile = \dirname($containerRef->getFileName(), 2).'/'.$containerClass.'.php';
7074
$containerMetaFile = $containerFile.'.meta';
71-
$kernelRef = new \ReflectionObject($kernel);
72-
$kernelFile = $kernelRef->getFileName();
75+
$this->kernelRef = new \ReflectionObject($this->kernel);
76+
$this->kernelFile = $this->kernelRef->getFileName();
7377
/** @var ResourceInterface[] $meta */
7478
$meta = unserialize(file_get_contents($containerMetaFile));
7579
$found = false;
7680
foreach ($meta as $resource) {
77-
if ((string) $resource === $kernelFile) {
81+
if ((string) $resource === $this->kernelFile) {
7882
$found = true;
7983
break;
8084
}
8185
}
8286
$this->assertTrue($found, 'Kernel file should present as resource');
8387

8488
$containerRef = new \ReflectionClass(require $containerFile);
85-
$containerFile = str_replace('tes_'.\DIRECTORY_SEPARATOR, 'test'.\DIRECTORY_SEPARATOR, $containerRef->getFileName());
86-
$this->assertMatchesRegularExpression(sprintf('/\'kernel.container_class\'\s*=>\s*\'%s\'/', $containerClass), file_get_contents($containerFile), 'kernel.container_class is properly set on the dumped container');
89+
$containerFile = str_replace(
90+
'tes_'.\DIRECTORY_SEPARATOR,
91+
'test'.\DIRECTORY_SEPARATOR,
92+
$containerRef->getFileName()
93+
);
94+
$this->assertMatchesRegularExpression(
95+
sprintf('/\'kernel.container_class\'\s*=>\s*\'%s\'/', $containerClass),
96+
file_get_contents($containerFile),
97+
'kernel.container_class is properly set on the dumped container'
98+
);
8799
}
88100

89-
public function getKernel()
101+
public function testCacheIsWarmedWhenCalledTwice()
90102
{
91-
yield [new TestAppKernel('test', true)];
92-
yield [new NoBuildDirKernel('test', true)];
103+
$input = new ArrayInput(['cache:clear']);
104+
$application = new Application(clone $this->kernel);
105+
$application->setCatchExceptions(false);
106+
$application->doRun($input, new NullOutput());
107+
108+
$_SERVER['REQUEST_TIME'] = time() + 1;
109+
$application = new Application(clone $this->kernel);
110+
$application->setCatchExceptions(false);
111+
$application->doRun($input, new NullOutput());
112+
113+
$this->assertTrue(is_file($this->kernel->getCacheDir().'/annotations.php'));
93114
}
94-
}
95115

96-
class NoBuildDirKernel extends TestAppKernel
97-
{
98-
protected function getKernelParameters()
116+
public function testCacheIsWarmedWithOldContainer()
99117
{
100-
$parameters = parent::getKernelParameters();
101-
unset($parameters['kernel.build_dir']);
118+
$kernel = clone $this->kernel;
119+
120+
// Hack to get a dumped working container,
121+
// BUT without "kernel.build_dir" parameter (like an old dumped container)
122+
$kernel->boot();
123+
$container = $kernel->getContainer();
124+
\Closure::bind(function (Container $class) {
125+
unset($class->loadedDynamicParameters['kernel.build_dir']);
126+
unset($class->parameters['kernel.build_dir']);
127+
}, null, \get_class($container))($container);
128+
129+
$input = new ArrayInput(['cache:clear']);
130+
$application = new Application($kernel);
131+
$application->setCatchExceptions(false);
132+
$application->doRun($input, new NullOutput());
102133

103-
return $parameters;
134+
$this->expectNotToPerformAssertions();
104135
}
105136
}

src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php

+2
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ public static function getContainerDeprecations()
9292
{
9393
$builderWithDeprecations = new ContainerBuilder();
9494
$builderWithDeprecations->setParameter('kernel.cache_dir', __DIR__.'/../../Fixtures/Descriptor/cache');
95+
$builderWithDeprecations->setParameter('kernel.build_dir', __DIR__.'/../../Fixtures/Descriptor/cache');
9596
$builderWithDeprecations->setParameter('kernel.container_class', 'KernelContainerWith');
9697

9798
$builderWithoutDeprecations = new ContainerBuilder();
9899
$builderWithoutDeprecations->setParameter('kernel.cache_dir', __DIR__.'/../../Fixtures/Descriptor/cache');
100+
$builderWithoutDeprecations->setParameter('kernel.build_dir', __DIR__.'/../../Fixtures/Descriptor/cache');
99101
$builderWithoutDeprecations->setParameter('kernel.container_class', 'KernelContainerWithout');
100102

101103
return [

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public function testDescribeEnvVar()
139139
public function testGetDeprecation()
140140
{
141141
static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml', 'debug' => true]);
142-
$path = sprintf('%s/%sDeprecations.log', static::$kernel->getContainer()->getParameter('kernel.cache_dir'), static::$kernel->getContainer()->getParameter('kernel.container_class'));
142+
$path = sprintf('%s/%sDeprecations.log', static::$kernel->getContainer()->getParameter('kernel.build_dir'), static::$kernel->getContainer()->getParameter('kernel.container_class'));
143143
touch($path);
144144
file_put_contents($path, serialize([[
145145
'type' => 16384,
@@ -169,7 +169,7 @@ public function testGetDeprecation()
169169
public function testGetDeprecationNone()
170170
{
171171
static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml', 'debug' => true]);
172-
$path = sprintf('%s/%sDeprecations.log', static::$kernel->getContainer()->getParameter('kernel.cache_dir'), static::$kernel->getContainer()->getParameter('kernel.container_class'));
172+
$path = sprintf('%s/%sDeprecations.log', static::$kernel->getContainer()->getParameter('kernel.build_dir'), static::$kernel->getContainer()->getParameter('kernel.container_class'));
173173
touch($path);
174174
file_put_contents($path, serialize([]));
175175

@@ -188,7 +188,7 @@ public function testGetDeprecationNone()
188188
public function testGetDeprecationNoFile()
189189
{
190190
static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml', 'debug' => true]);
191-
$path = sprintf('%s/%sDeprecations.log', static::$kernel->getContainer()->getParameter('kernel.cache_dir'), static::$kernel->getContainer()->getParameter('kernel.container_class'));
191+
$path = sprintf('%s/%sDeprecations.log', static::$kernel->getContainer()->getParameter('kernel.build_dir'), static::$kernel->getContainer()->getParameter('kernel.container_class'));
192192
@unlink($path);
193193

194194
$application = new Application(static::$kernel);

src/Symfony/Bundle/FrameworkBundle/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"symfony/event-dispatcher": "^5.1",
2525
"symfony/error-handler": "^4.4.1|^5.0.1",
2626
"symfony/http-foundation": "^5.2.1",
27-
"symfony/http-kernel": "^5.2",
27+
"symfony/http-kernel": "^5.2.1",
2828
"symfony/polyfill-mbstring": "~1.0",
2929
"symfony/polyfill-php80": "^1.15",
3030
"symfony/filesystem": "^4.4|^5.0",

src/Symfony/Component/HttpKernel/Kernel.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ protected function getKernelParameters()
609609
'kernel.runtime_environment' => '%env(default:kernel.environment:APP_RUNTIME_ENV)%',
610610
'kernel.debug' => $this->debug,
611611
'kernel.build_dir' => realpath($buildDir = $this->warmupDir ?: $this->getBuildDir()) ?: $buildDir,
612-
'kernel.cache_dir' => realpath($this->getCacheDir()) ?: $this->getCacheDir(),
612+
'kernel.cache_dir' => realpath($cacheDir = ($this->getCacheDir() === $this->getBuildDir() ? ($this->warmupDir ?: $this->getCacheDir()) : $this->getCacheDir())) ?: $cacheDir,
613613
'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(),
614614
'kernel.bundles' => $bundles,
615615
'kernel.bundles_metadata' => $bundlesMetadata,

0 commit comments

Comments
 (0)