diff --git a/src/Symfony/Component/AssetMapper/Command/DebugAssetMapperCommand.php b/src/Symfony/Component/AssetMapper/Command/DebugAssetMapperCommand.php index 7021bba762cb6..a81857b5c14b2 100644 --- a/src/Symfony/Component/AssetMapper/Command/DebugAssetMapperCommand.php +++ b/src/Symfony/Component/AssetMapper/Command/DebugAssetMapperCommand.php @@ -15,7 +15,9 @@ use Symfony\Component\AssetMapper\AssetMapperRepository; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; @@ -40,10 +42,41 @@ public function __construct( protected function configure(): void { $this + ->addArgument('name', InputArgument::OPTIONAL, 'An asset name (or a path) to search for (e.g. "app")') + ->addOption('ext', null, InputOption::VALUE_REQUIRED, 'Filter assets by extension (e.g. "css")', null, ['js', 'css', 'png']) ->addOption('full', null, null, 'Whether to show the full paths') + ->addOption('vendor', null, InputOption::VALUE_NEGATABLE, 'Only show assets from vendor packages') ->setHelp(<<<'EOT' -The %command.name% command outputs all of the assets in -asset mapper for debugging purposes. +The %command.name% command displays information about the Asset +Mapper for debugging purposes. + +To list all configured paths (with local paths and their namespace prefixes) and +all mapped assets (with their logical path and filesystem path), run: + + php %command.full_name% + +You can filter the results by providing a name to search for in the asset name +or path: + + php %command.full_name% bootstrap.js + php %command.full_name% style/ + +To filter the assets by extension, use the --ext option: + + php %command.full_name% --ext=css + +To show only assets from vendor packages, use the --vendor option: + + php %command.full_name% --vendor + +To exclude assets from vendor packages, use the --no-vendor option: + + php %command.full_name% --no-vendor + +To see the full paths, use the --full option: + + php %command.full_name% --full + EOT ); } @@ -52,43 +85,83 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); - $allAssets = $this->assetMapper->allAssets(); + $name = $input->getArgument('name'); + $extensionFilter = $input->getOption('ext'); + $vendorFilter = $input->getOption('vendor'); + + if (!$extensionFilter) { + $io->section($name ? 'Matched Paths' : 'Asset Mapper Paths'); + $pathRows = []; + foreach ($this->assetMapperRepository->allDirectories() as $path => $namespace) { + $path = $this->relativizePath($path); + if (!$input->getOption('full')) { + $path = $this->shortenPath($path); + } + if ($name && !str_contains($path, $name) && !str_contains($namespace, $name)) { + continue; + } + $pathRows[] = [$path, $namespace]; + } + uasort($pathRows, static function (array $a, array $b): int { + return [(bool) $a[1], ...$a] <=> [(bool) $b[1], ...$b]; + }); + if ($pathRows) { + $io->table(['Path', 'Namespace prefix'], $pathRows); + } else { + $io->warning('No paths found.'); + } + } - $pathRows = []; - foreach ($this->assetMapperRepository->allDirectories() as $path => $namespace) { - $path = $this->relativizePath($path); + $io->section($name ? 'Matched Assets' : 'Mapped Assets'); + $rows = $this->searchAssets($name, $extensionFilter, $vendorFilter); + if ($rows) { if (!$input->getOption('full')) { - $path = $this->shortenPath($path); + $rows = array_map(fn (array $row): array => [ + $this->shortenPath($row[0]), + $this->shortenPath($row[1]), + ], $rows); } - - $pathRows[] = [$path, $namespace]; + uasort($rows, static function (array $a, array $b): int { + return [$a] <=> [$b]; + }); + $io->table(['Logical Path', 'Filesystem Path'], $rows); + if ($this->didShortenPaths) { + $io->note('To see the full paths, re-run with the --full option.'); + } + } else { + $io->warning('No assets found.'); } - $io->section('Asset Mapper Paths'); - $io->table(['Path', 'Namespace prefix'], $pathRows); + return 0; + } + + /** + * @return list + */ + private function searchAssets(?string $name, ?string $extension, ?bool $vendor): array + { $rows = []; - foreach ($allAssets as $asset) { + foreach ($this->assetMapper->allAssets() as $asset) { + if ($extension && $extension !== $asset->publicExtension) { + continue; + } + if (null !== $vendor && $vendor !== $asset->isVendor) { + continue; + } + if ($name && !str_contains($asset->logicalPath, $name) && !str_contains($asset->sourcePath, $name)) { + continue; + } + $logicalPath = $asset->logicalPath; $sourcePath = $this->relativizePath($asset->sourcePath); - if (!$input->getOption('full')) { - $logicalPath = $this->shortenPath($logicalPath); - $sourcePath = $this->shortenPath($sourcePath); - } - $rows[] = [ $logicalPath, $sourcePath, ]; } - $io->section('Mapped Assets'); - $io->table(['Logical Path', 'Filesystem Path'], $rows); - - if ($this->didShortenPaths) { - $io->note('To see the full paths, re-run with the --full option.'); - } - return 0; + return $rows; } private function relativizePath(string $path): string diff --git a/src/Symfony/Component/AssetMapper/Tests/Command/DebugAssetsMapperCommandTest.php b/src/Symfony/Component/AssetMapper/Tests/Command/DebugAssetsMapperCommandTest.php index 5d2530004096c..03fe35450a085 100644 --- a/src/Symfony/Component/AssetMapper/Tests/Command/DebugAssetsMapperCommandTest.php +++ b/src/Symfony/Component/AssetMapper/Tests/Command/DebugAssetsMapperCommandTest.php @@ -31,4 +31,57 @@ public function testCommandDumpsInformation() $this->assertStringContainsString('subdir/file6.js', $tester->getDisplay()); $this->assertStringContainsString('dir2'.\DIRECTORY_SEPARATOR.'subdir'.\DIRECTORY_SEPARATOR.'file6.js', $tester->getDisplay()); } + + public function testCommandFiltersName() + { + $application = new Application(new AssetMapperTestAppKernel('test', true)); + $command = $application->find('debug:asset-map'); + $tester = new CommandTester($command); + $res = $tester->execute(['name' => 'stimulus']); + + $this->assertSame(0, $res); + $this->assertStringContainsString('stimulus', $tester->getDisplay()); + $this->assertStringNotContainsString('lodash', $tester->getDisplay()); + + $res = $tester->execute(['name' => 'lodash']); + $this->assertSame(0, $res); + $this->assertStringNotContainsString('stimulus', $tester->getDisplay()); + $this->assertStringContainsString('lodash', $tester->getDisplay()); + } + + public function testCommandFiltersExtension() + { + $application = new Application(new AssetMapperTestAppKernel('test', true)); + $command = $application->find('debug:asset-map'); + $tester = new CommandTester($command); + $res = $tester->execute(['--ext' => 'css']); + + $this->assertSame(0, $res); + $this->assertStringNotContainsString('.js', $tester->getDisplay()); + + $this->assertStringContainsString('file1.css', $tester->getDisplay()); + $this->assertStringContainsString('file3.css', $tester->getDisplay()); + } + + public function testCommandFiltersVendor() + { + $application = new Application(new AssetMapperTestAppKernel('test', true)); + $command = $application->find('debug:asset-map'); + + $tester = new CommandTester($command); + $res = $tester->execute(['--vendor' => true]); + + $this->assertSame(0, $res); + $this->assertStringContainsString('vendor/lodash/', $tester->getDisplay()); + $this->assertStringContainsString('@hotwired/stimulus', $tester->getDisplay()); + $this->assertStringNotContainsString('dir2'.\DIRECTORY_SEPARATOR, $tester->getDisplay()); + + $tester = new CommandTester($command); + $res = $tester->execute(['--no-vendor' => true]); + + $this->assertSame(0, $res); + $this->assertStringNotContainsString('vendor/lodash/', $tester->getDisplay()); + $this->assertStringNotContainsString('@hotwired/stimulus', $tester->getDisplay()); + $this->assertStringContainsString('dir2'.\DIRECTORY_SEPARATOR, $tester->getDisplay()); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy