diff --git a/src/Symfony/Component/AssetMapper/CHANGELOG.md b/src/Symfony/Component/AssetMapper/CHANGELOG.md
index dce7c57aad41e..386abbbfdbd56 100644
--- a/src/Symfony/Component/AssetMapper/CHANGELOG.md
+++ b/src/Symfony/Component/AssetMapper/CHANGELOG.md
@@ -5,6 +5,8 @@ CHANGELOG
---
* Add support for pre-compressing assets with Brotli, Zstandard, Zopfli, and gzip
+ * Make `asset-map:compile` remove assets in debug mode
+ * Add `--force` to the `asset-map:compile` command to make it generate assets in debug mode
7.2
---
diff --git a/src/Symfony/Component/AssetMapper/Command/AssetMapperCompileCommand.php b/src/Symfony/Component/AssetMapper/Command/AssetMapperCompileCommand.php
index bb54194a03a22..c5cc4a57392fd 100644
--- a/src/Symfony/Component/AssetMapper/Command/AssetMapperCompileCommand.php
+++ b/src/Symfony/Component/AssetMapper/Command/AssetMapperCompileCommand.php
@@ -49,11 +49,12 @@ public function __construct(
protected function configure(): void
{
$this
+ ->addOption('force', 'f', null, 'Force compiling the assets even in debug mode')
->setHelp(<<<'EOT'
The %command.name% command compiles and dumps all the assets in
the asset mapper into the final public directory (usually public/assets).
-This command is meant to be run during deployment.
+When run in debug mode, this command actually removes those assets, unless --force is passed.
EOT
);
}
@@ -62,8 +63,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
- $this->eventDispatcher?->dispatch(new PreAssetsCompileEvent($io));
-
// remove existing config files
$this->compiledConfigReader->removeConfig(AssetMapper::MANIFEST_FILE_NAME);
$this->compiledConfigReader->removeConfig(ImportMapGenerator::IMPORT_MAP_CACHE_FILENAME);
@@ -74,6 +73,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$entrypointFiles[$entrypointName] = $path;
}
+ if ($this->isDebug && !$input->getOption('force')) {
+ $didUnlink = false;
+ $publicDir = $this->assetsFilesystem->getDestinationPath();
+
+ foreach ($this->assetMapper->allAssets() as $asset) {
+ if (is_file($publicDir.'/'.$asset->publicPath)) {
+ unlink($publicDir.'/'.$asset->publicPath);
+ $didUnlink = true;
+ }
+ }
+
+ if ($didUnlink) {
+ $io->warning('Running in debug mode: removed compiled assets to let them be served dynamically. Use --force to generate them instead.');
+ }
+
+ return 0;
+ }
+
+ $this->eventDispatcher?->dispatch(new PreAssetsCompileEvent($io));
+
$manifest = $this->createManifestAndWriteFiles($io);
$manifestPath = $this->compiledConfigReader->saveConfig(AssetMapper::MANIFEST_FILE_NAME, $manifest);
$io->comment(\sprintf('Manifest written to %s', $this->shortenPath($manifestPath)));
@@ -87,13 +106,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$styledEntrypointNames = array_map(fn (string $entrypointName) => \sprintf('%s>', $entrypointName), array_keys($entrypointFiles));
$io->comment(\sprintf('Entrypoint metadata written for %d> entrypoints (%s).', \count($entrypointFiles), implode(', ', $styledEntrypointNames)));
- if ($this->isDebug) {
- $io->warning(\sprintf(
- 'Debug mode is enabled in your project: Symfony will not serve any changed assets until you delete the files in the "%s" directory again.',
- $this->shortenPath(\dirname($manifestPath))
- ));
- }
-
return 0;
}
diff --git a/src/Symfony/Component/AssetMapper/Tests/Command/AssetMapperCompileCommandTest.php b/src/Symfony/Component/AssetMapper/Tests/Command/AssetMapperCompileCommandTest.php
index 36abbef953706..178a220fca1b0 100644
--- a/src/Symfony/Component/AssetMapper/Tests/Command/AssetMapperCompileCommandTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/Command/AssetMapperCompileCommandTest.php
@@ -54,7 +54,7 @@ public function testAssetsAreCompiled()
$command = $application->find('asset-map:compile');
$tester = new CommandTester($command);
- $exitCode = $tester->execute([]);
+ $exitCode = $tester->execute(['--force' => true]);
$this->assertSame(0, $exitCode);
// match Compiling \d+ assets
$this->assertMatchesRegularExpression('/Compiled \d+ assets/', $tester->getDisplay());
@@ -106,6 +106,12 @@ public function testAssetsAreCompiled()
'/assets/subdir/file5.js',
'/assets/file4.js',
], $entrypointData);
+
+ $tester = new CommandTester($command);
+ $exitCode = $tester->execute(['--force' => false]);
+ $this->assertSame(0, $exitCode);
+
+ $this->assertStringStartsWith('[WARNING] Running in debug mode: removed compiled assets', ltrim($tester->getDisplay()));
}
public function testEventIsDispatched()
@@ -124,7 +130,7 @@ public function testEventIsDispatched()
$command = $application->find('asset-map:compile');
$tester = new CommandTester($command);
- $tester->execute([]);
+ $tester->execute(['--force' => true]);
$this->assertTrue($listenerCalled);
}
}