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 ;
18- use Symfony \Component \AssetMapper \Path \PublicAssetsPathResolverInterface ;
19+ use Symfony \Component \AssetMapper \Path \PublicAssetsFilesystemInterface ;
1920use Symfony \Component \Console \Attribute \AsCommand ;
2021use Symfony \Component \Console \Command \Command ;
21- use Symfony \Component \Console \Exception \InvalidArgumentException ;
2222use Symfony \Component \Console \Input \InputInterface ;
2323use Symfony \Component \Console \Output \OutputInterface ;
2424use Symfony \Component \Console \Style \SymfonyStyle ;
25- use Symfony \Component \Filesystem \Filesystem ;
2625use Symfony \Contracts \EventDispatcher \EventDispatcherInterface ;
2726
2827/**
3635final class AssetMapperCompileCommand extends Command
3736{
3837 public function __construct (
39- private readonly PublicAssetsPathResolverInterface $ publicAssetsPathResolver ,
38+ private readonly CompiledAssetMapperConfigReader $ compiledConfigReader ,
4039 private readonly AssetMapperInterface $ assetMapper ,
4140 private readonly ImportMapGenerator $ importMapGenerator ,
42- private readonly Filesystem $ filesystem ,
41+ private readonly PublicAssetsFilesystemInterface $ assetsFilesystem ,
4342 private readonly string $ projectDir ,
44- private readonly string $ publicDirName ,
4543 private readonly bool $ isDebug ,
4644 private readonly ?EventDispatcherInterface $ eventDispatcher = null ,
4745 ) {
@@ -51,7 +49,6 @@ public function __construct(
5149 protected function configure (): void
5250 {
5351 $ this
54- ->addOption ('clean ' , null , null , 'Whether to clean the public directory before compiling assets ' )
5552 ->setHelp (<<<'EOT'
5653The <info>%command.name%</info> command compiles and dumps all the assets in
5754the asset mapper into the final public directory (usually <comment>public/assets</comment>).
@@ -64,61 +61,36 @@ protected function configure(): void
6461 protected function execute (InputInterface $ input , OutputInterface $ output ): int
6562 {
6663 $ 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 ;
8364
84- $ importMapPath = $ outputDir .'/ ' .ImportMapGenerator::IMPORT_MAP_CACHE_FILENAME ;
85- $ files [] = $ importMapPath ;
65+ $ this ->eventDispatcher ?->dispatch(new PreAssetsCompileEvent ($ output ));
8666
87- $ entrypointFilePaths = [];
67+ // remove existing config files
68+ $ this ->compiledConfigReader ->removeConfig (AssetMapper::MANIFEST_FILE_NAME );
69+ $ this ->compiledConfigReader ->removeConfig (ImportMapGenerator::IMPORT_MAP_CACHE_FILENAME );
70+ $ entrypointFiles = [];
8871 foreach ($ this ->importMapGenerator ->getEntrypointNames () as $ entrypointName ) {
89- $ dumpedEntrypointPath = $ outputDir . ' / ' . sprintf (ImportMapGenerator::ENTRYPOINT_CACHE_FILENAME_PATTERN , $ entrypointName );
90- $ files [] = $ dumpedEntrypointPath ;
91- $ entrypointFilePaths [$ entrypointName ] = $ dumpedEntrypointPath ;
72+ $ path = sprintf (ImportMapGenerator::ENTRYPOINT_CACHE_FILENAME_PATTERN , $ entrypointName );
73+ $ this -> compiledConfigReader -> removeConfig ( $ path ) ;
74+ $ entrypointFiles [$ entrypointName ] = $ path ;
9275 }
9376
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 ));
77+ $ manifest = $ this ->createManifestAndWriteFiles ($ io );
78+ $ manifestPath = $ this ->compiledConfigReader ->saveConfig (AssetMapper::MANIFEST_FILE_NAME , $ manifest );
10679 $ io ->comment (sprintf ('Manifest written to <info>%s</info> ' , $ this ->shortenPath ($ manifestPath )));
10780
108- $ this ->filesystem -> dumpFile ( $ importMapPath , json_encode ( $ this ->importMapGenerator ->getRawImportMapData (), \ JSON_THROW_ON_ERROR | \ JSON_PRETTY_PRINT | \ JSON_UNESCAPED_SLASHES | \ JSON_HEX_TAG ));
81+ $ importMapPath = $ this ->compiledConfigReader -> saveConfig (ImportMapGenerator:: IMPORT_MAP_CACHE_FILENAME , $ this ->importMapGenerator ->getRawImportMapData ());
10982 $ io ->comment (sprintf ('Import map data written to <info>%s</info>. ' , $ this ->shortenPath ($ importMapPath )));
11083
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 ));
84+ foreach ($ entrypointFiles as $ entrypointName => $ path ) {
85+ $ this ->compiledConfigReader ->saveConfig ($ path , $ this ->importMapGenerator ->findEagerEntrypointImports ($ entrypointName ));
11486 }
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 )));
87+ $ styledEntrypointNames = array_map (fn (string $ entrypointName ) => sprintf ('<info>%s</> ' , $ entrypointName ), array_keys ( $ entrypointFiles ) );
88+ $ io ->comment (sprintf ('Entrypoint metadata written for <comment>%d</> entrypoints (%s). ' , \count ($ entrypointFiles ), implode (', ' , $ styledEntrypointNames )));
11789
11890 if ($ this ->isDebug ) {
11991 $ 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 )
92+ 'You are compiling assets in development. Symfony will not serve any changed assets until you delete the files in the "%s" directory. ' ,
93+ $ this ->shortenPath (\dirname ( $ manifestPath ) )
12294 ));
12395 }
12496
@@ -130,20 +102,18 @@ private function shortenPath(string $path): string
130102 return str_replace ($ this ->projectDir .'/ ' , '' , $ path );
131103 }
132104
133- private function createManifestAndWriteFiles (SymfonyStyle $ io, string $ publicDir ): array
105+ private function createManifestAndWriteFiles (SymfonyStyle $ io ): array
134106 {
135107 $ allAssets = $ this ->assetMapper ->allAssets ();
136108
137- $ io ->comment (sprintf ('Compiling assets to <info>%s%s </info> ' , $ publicDir , $ this ->publicAssetsPathResolver -> resolvePublicPath ( '' )));
109+ $ io ->comment (sprintf ('Compiling and writing asset files to <info>%s</info> ' , $ this -> shortenPath ( $ this ->assetsFilesystem -> getDestinationPath () )));
138110 $ manifest = [];
139111 foreach ($ allAssets as $ asset ) {
140- // $asset->getPublicPath() will start with a "/"
141- $ targetPath = $ publicDir .$ asset ->publicPath ;
142112 if (null !== $ asset ->content ) {
143113 // The original content has been modified by the AssetMapperCompiler
144- $ this ->filesystem -> dumpFile ( $ targetPath , $ asset ->content );
114+ $ this ->assetsFilesystem -> write ( $ asset -> publicPath , $ asset ->content );
145115 } else {
146- $ this ->filesystem ->copy ($ asset ->sourcePath , $ targetPath , true );
116+ $ this ->assetsFilesystem ->copy ($ asset ->sourcePath , $ asset -> publicPath );
147117 }
148118
149119 $ manifest [$ asset ->logicalPath ] = $ asset ->publicPath ;
0 commit comments