1313
1414use Symfony \Component \AssetMapper \AssetMapper ;
1515use Symfony \Component \AssetMapper \AssetMapperInterface ;
16+ use Symfony \Component \AssetMapper \CompiledAssetMapperConfigReader ;
1617use Symfony \Component \AssetMapper \Event \PreAssetsCompileEvent ;
1718use Symfony \Component \AssetMapper \ImportMap \ImportMapGenerator ;
1819use Symfony \Component \AssetMapper \Path \PublicAssetsPathResolverInterface ;
20+ use Symfony \Component \AssetMapper \ImportMap \ImportMapManager ;
21+ use Symfony \Component \AssetMapper \Path \PublicAssetsFilesystemInterface ;
1922use Symfony \Component \Console \Attribute \AsCommand ;
2023use Symfony \Component \Console \Command \Command ;
21- use Symfony \Component \Console \Exception \InvalidArgumentException ;
2224use Symfony \Component \Console \Input \InputInterface ;
2325use Symfony \Component \Console \Output \OutputInterface ;
2426use Symfony \Component \Console \Style \SymfonyStyle ;
25- use Symfony \Component \Filesystem \Filesystem ;
2627use Symfony \Contracts \EventDispatcher \EventDispatcherInterface ;
2728
2829/**
3637final class AssetMapperCompileCommand extends Command
3738{
3839 public function __construct (
39- private readonly PublicAssetsPathResolverInterface $ publicAssetsPathResolver ,
40+ private readonly CompiledAssetMapperConfigReader $ compiledConfigReader ,
4041 private readonly AssetMapperInterface $ assetMapper ,
4142 private readonly ImportMapGenerator $ importMapGenerator ,
42- private readonly Filesystem $ filesystem ,
43+ private readonly PublicAssetsFilesystemInterface $ assetsFilesystem ,
4344 private readonly string $ projectDir ,
44- private readonly string $ publicDirName ,
4545 private readonly bool $ isDebug ,
4646 private readonly ?EventDispatcherInterface $ eventDispatcher = null ,
4747 ) {
@@ -51,7 +51,6 @@ public function __construct(
5151 protected function configure (): void
5252 {
5353 $ this
54- ->addOption ('clean ' , null , null , 'Whether to clean the public directory before compiling assets ' )
5554 ->setHelp (<<<'EOT'
5655The <info>%command.name%</info> command compiles and dumps all the assets in
5756the asset mapper into the final public directory (usually <comment>public/assets</comment>).
@@ -64,61 +63,36 @@ protected function configure(): void
6463 protected function execute (InputInterface $ input , OutputInterface $ output ): int
6564 {
6665 $ io = new SymfonyStyle ($ input , $ output );
67- $ publicDir = $ this ->projectDir .'/ ' .$ this ->publicDirName ;
68- if (!is_dir ($ publicDir )) {
69- throw new InvalidArgumentException (sprintf ('The public directory "%s" does not exist. ' , $ publicDir ));
70- }
71-
72- $ outputDir = $ this ->publicAssetsPathResolver ->getPublicFilesystemPath ();
73- if ($ input ->getOption ('clean ' )) {
74- $ io ->comment (sprintf ('Cleaning <info>%s</info> ' , $ outputDir ));
75- $ this ->filesystem ->remove ($ outputDir );
76- $ this ->filesystem ->mkdir ($ outputDir );
77- }
78-
79- // set up the file paths
80- $ files = [];
81- $ manifestPath = $ outputDir .'/ ' .AssetMapper::MANIFEST_FILE_NAME ;
82- $ files [] = $ manifestPath ;
8366
84- $ importMapPath = $ outputDir .'/ ' .ImportMapGenerator::IMPORT_MAP_CACHE_FILENAME ;
85- $ files [] = $ importMapPath ;
67+ $ this ->eventDispatcher ?->dispatch(new PreAssetsCompileEvent ($ output ));
8668
87- $ entrypointFilePaths = [];
69+ // remove existing config files
70+ $ this ->compiledConfigReader ->removeConfig (AssetMapper::MANIFEST_FILE_NAME );
71+ $ this ->compiledConfigReader ->removeConfig (ImportMapGenerator::IMPORT_MAP_CACHE_FILENAME );
72+ $ entrypointFiles = [];
8873 foreach ($ this ->importMapGenerator ->getEntrypointNames () as $ entrypointName ) {
89- $ dumpedEntrypointPath = $ outputDir . ' / ' . sprintf (ImportMapGenerator::ENTRYPOINT_CACHE_FILENAME_PATTERN , $ entrypointName );
90- $ files [] = $ dumpedEntrypointPath ;
91- $ entrypointFilePaths [$ entrypointName ] = $ dumpedEntrypointPath ;
74+ $ path = sprintf (ImportMapGenerator::ENTRYPOINT_CACHE_FILENAME_PATTERN , $ entrypointName );
75+ $ this -> compiledConfigReader -> removeConfig ( $ path ) ;
76+ $ entrypointFiles [$ entrypointName ] = $ path ;
9277 }
9378
94- // remove existing files
95- foreach ($ files as $ file ) {
96- if (is_file ($ file )) {
97- $ this ->filesystem ->remove ($ file );
98- }
99- }
100-
101- $ this ->eventDispatcher ?->dispatch(new PreAssetsCompileEvent ($ outputDir , $ output ));
102-
103- // dump new files
104- $ manifest = $ this ->createManifestAndWriteFiles ($ io , $ publicDir );
105- $ this ->filesystem ->dumpFile ($ manifestPath , json_encode ($ manifest , \JSON_PRETTY_PRINT ));
79+ $ manifest = $ this ->createManifestAndWriteFiles ($ io );
80+ $ manifestPath = $ this ->compiledConfigReader ->saveConfig (AssetMapper::MANIFEST_FILE_NAME , $ manifest );
10681 $ io ->comment (sprintf ('Manifest written to <info>%s</info> ' , $ this ->shortenPath ($ manifestPath )));
10782
108- $ this ->filesystem -> dumpFile ( $ importMapPath , json_encode ( $ this ->importMapGenerator ->getRawImportMapData (), \ JSON_THROW_ON_ERROR | \ JSON_PRETTY_PRINT | \ JSON_UNESCAPED_SLASHES | \ JSON_HEX_TAG ));
83+ $ importMapPath = $ this ->compiledConfigReader -> saveConfig (ImportMapGenerator:: IMPORT_MAP_CACHE_FILENAME , $ this ->importMapGenerator ->getRawImportMapData ());
10984 $ io ->comment (sprintf ('Import map data written to <info>%s</info>. ' , $ this ->shortenPath ($ importMapPath )));
11085
111- $ entrypointNames = $ this ->importMapGenerator ->getEntrypointNames ();
112- foreach ($ entrypointFilePaths as $ entrypointName => $ path ) {
113- $ this ->filesystem ->dumpFile ($ path , json_encode ($ this ->importMapGenerator ->findEagerEntrypointImports ($ entrypointName ), \JSON_THROW_ON_ERROR | \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_HEX_TAG ));
86+ foreach ($ entrypointFiles as $ entrypointName => $ path ) {
87+ $ this ->compiledConfigReader ->saveConfig ($ path , $ this ->importMapGenerator ->findEagerEntrypointImports ($ entrypointName ));
11488 }
115- $ styledEntrypointNames = array_map (fn (string $ entrypointName ) => sprintf ('<info>%s</> ' , $ entrypointName ), $ entrypointNames );
116- $ io ->comment (sprintf ('Entrypoint metadata written for <comment>%d</> entrypoints (%s). ' , \count ($ entrypointNames ), implode (', ' , $ styledEntrypointNames )));
89+ $ styledEntrypointNames = array_map (fn (string $ entrypointName ) => sprintf ('<info>%s</> ' , $ entrypointName ), array_keys ( $ entrypointFiles ) );
90+ $ io ->comment (sprintf ('Entrypoint metadata written for <comment>%d</> entrypoints (%s). ' , \count ($ entrypointFiles ), implode (', ' , $ styledEntrypointNames )));
11791
11892 if ($ this ->isDebug ) {
11993 $ io ->warning (sprintf (
120- 'You are compiling assets in development. Symfony will not serve any changed assets until you delete the "%s" directory. ' ,
121- $ this ->shortenPath ($ outputDir )
94+ 'You are compiling assets in development. Symfony will not serve any changed assets until you delete the files in the "%s" directory. ' ,
95+ $ this ->shortenPath (\dirname ( $ manifestPath ) )
12296 ));
12397 }
12498
@@ -130,20 +104,18 @@ private function shortenPath(string $path): string
130104 return str_replace ($ this ->projectDir .'/ ' , '' , $ path );
131105 }
132106
133- private function createManifestAndWriteFiles (SymfonyStyle $ io, string $ publicDir ): array
107+ private function createManifestAndWriteFiles (SymfonyStyle $ io ): array
134108 {
135109 $ allAssets = $ this ->assetMapper ->allAssets ();
136110
137- $ io ->comment (sprintf ('Compiling assets to <info>%s%s </info> ' , $ publicDir , $ this ->publicAssetsPathResolver -> resolvePublicPath ( '' )));
111+ $ io ->comment (sprintf ('Compiling and writing asset files to <info>%s</info> ' , $ this -> shortenPath ( $ this ->assetsFilesystem -> getDestinationPath () )));
138112 $ manifest = [];
139113 foreach ($ allAssets as $ asset ) {
140- // $asset->getPublicPath() will start with a "/"
141- $ targetPath = $ publicDir .$ asset ->publicPath ;
142114 if (null !== $ asset ->content ) {
143115 // The original content has been modified by the AssetMapperCompiler
144- $ this ->filesystem -> dumpFile ( $ targetPath , $ asset ->content );
116+ $ this ->assetsFilesystem -> write ( $ asset -> publicPath , $ asset ->content );
145117 } else {
146- $ this ->filesystem ->copy ($ asset ->sourcePath , $ targetPath , true );
118+ $ this ->assetsFilesystem ->copy ($ asset ->sourcePath , $ asset -> publicPath );
147119 }
148120
149121 $ manifest [$ asset ->logicalPath ] = $ asset ->publicPath ;
0 commit comments