From fc64955f1dfa5b47447075bd65feca941f93b550 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 03:26:42 +0100 Subject: [PATCH 01/11] feat: Change input_css option to accept an array of input css files --- doc/index.rst | 7 ++- src/AssetMapper/TailwindCssAssetCompiler.php | 9 ++- src/Command/TailwindBuildCommand.php | 2 + src/Command/TailwindInitCommand.php | 2 +- src/DependencyInjection/TailwindExtension.php | 7 ++- src/TailwindBuilder.php | 60 ++++++++++++------- .../TailwindCssAssetCompilerTest.php | 4 +- tests/FunctionalTest.php | 6 +- tests/TailwindBuilderTest.php | 33 ++++++++-- tests/fixtures/TailwindTestKernel.php | 2 +- tests/fixtures/assets/styles/second.css | 7 +++ 11 files changed, 96 insertions(+), 43 deletions(-) create mode 100644 tests/fixtures/assets/styles/second.css diff --git a/doc/index.rst b/doc/index.rst index a235851..ab0fef7 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -151,15 +151,16 @@ To see the full config from this bundle, run: $ php bin/console config:dump symfonycasts_tailwind -The main option is ``input_css`` option, which defaults to ``assets/styles/app.css``. -This represents the "source" Tailwind file (the one that contains the ``@tailwind`` +The main option is ``input`` option, which defaults to ``assets/styles/app.css``. +This represents the "source" Tailwind files (the one that contains the ``@tailwind`` directives): .. code-block:: yaml # config/packages/symfonycasts_tailwind.yaml symfonycasts_tailwind: - input_css: 'assets/styles/other.css' + input: + - 'assets/styles/other.css' Another option is the ``config_file`` option, which defaults to ``tailwind.config.js``. This represents the Tailwind configuration file: diff --git a/src/AssetMapper/TailwindCssAssetCompiler.php b/src/AssetMapper/TailwindCssAssetCompiler.php index edd7264..c667b3b 100644 --- a/src/AssetMapper/TailwindCssAssetCompiler.php +++ b/src/AssetMapper/TailwindCssAssetCompiler.php @@ -25,13 +25,16 @@ public function __construct(private TailwindBuilder $tailwindBuilder) public function supports(MappedAsset $asset): bool { - return realpath($asset->sourcePath) === realpath($this->tailwindBuilder->getInputCssPath()); + return in_array( + realpath($asset->sourcePath), + array_map('realpath', $this->tailwindBuilder->getInputCssPaths()) + ); } public function compile(string $content, MappedAsset $asset, AssetMapperInterface $assetMapper): string { - $asset->addFileDependency($this->tailwindBuilder->getInternalOutputCssPath()); + $asset->addFileDependency($this->tailwindBuilder->getInternalOutputCssPath($asset->sourcePath)); - return $this->tailwindBuilder->getOutputCssContent(); + return $this->tailwindBuilder->getOutputCssContent($asset->sourcePath); } } diff --git a/src/Command/TailwindBuildCommand.php b/src/Command/TailwindBuildCommand.php index e8e505d..0ac928e 100644 --- a/src/Command/TailwindBuildCommand.php +++ b/src/Command/TailwindBuildCommand.php @@ -32,6 +32,7 @@ public function __construct( protected function configure(): void { $this + ->addOption('input', 'i', InputOption::VALUE_OPTIONAL, 'The input CSS file') ->addOption('watch', 'w', null, 'Watch for changes and rebuild automatically') ->addOption('poll', null, null, 'Use polling instead of filesystem events when watching') ->addOption('minify', 'm', InputOption::VALUE_NONE, 'Minify the output CSS') @@ -47,6 +48,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int watch: $input->getOption('watch'), poll: $input->getOption('poll'), minify: $input->getOption('minify'), + inputFile: $input->getOption('input'), ); $process->wait(function ($type, $buffer) use ($io) { $io->write($buffer); diff --git a/src/Command/TailwindInitCommand.php b/src/Command/TailwindInitCommand.php index 7e0af32..353f468 100644 --- a/src/Command/TailwindInitCommand.php +++ b/src/Command/TailwindInitCommand.php @@ -92,7 +92,7 @@ private function createTailwindConfig(SymfonyStyle $io): bool private function addTailwindDirectives(SymfonyStyle $io): void { - $inputFile = $this->tailwindBuilder->getInputCssPath(); + $inputFile = $this->tailwindBuilder->getInputCssPaths()[0]; $contents = is_file($inputFile) ? file_get_contents($inputFile) : ''; if (str_contains($contents, '@tailwind base')) { $io->note(sprintf('Tailwind directives already exist in "%s"', $inputFile)); diff --git a/src/DependencyInjection/TailwindExtension.php b/src/DependencyInjection/TailwindExtension.php index 586b0f9..6cfa1be 100644 --- a/src/DependencyInjection/TailwindExtension.php +++ b/src/DependencyInjection/TailwindExtension.php @@ -53,9 +53,10 @@ public function getConfigTreeBuilder(): TreeBuilder $rootNode ->children() - ->scalarNode('input_css') - ->info('Path to CSS file to process through Tailwind') - ->defaultValue('%kernel.project_dir%/assets/styles/app.css') + ->arrayNode('input_css') + ->prototype('scalar')->end() + ->info('Paths to CSS files to process through Tailwind') + ->defaultValue(['%kernel.project_dir%/assets/styles/app.css']) ->end() ->scalarNode('config_file') ->info('Path to the tailwind.config.js file') diff --git a/src/TailwindBuilder.php b/src/TailwindBuilder.php index 305c769..a10cb05 100644 --- a/src/TailwindBuilder.php +++ b/src/TailwindBuilder.php @@ -24,35 +24,39 @@ class TailwindBuilder { private ?SymfonyStyle $output = null; - private readonly string $inputPath; + private readonly array $inputPaths; public function __construct( private readonly string $projectRootDir, - string $inputPath, + array $inputPaths, private readonly string $tailwindVarDir, private CacheInterface $cache, private readonly ?string $binaryPath = null, private readonly ?string $binaryVersion = null, private readonly string $configPath = 'tailwind.config.js' ) { - if (is_file($inputPath)) { - $this->inputPath = $inputPath; - } else { - $this->inputPath = $projectRootDir.'/'.$inputPath; - - if (!is_file($this->inputPath)) { - throw new \InvalidArgumentException(sprintf('The input CSS file "%s" does not exist.', $inputPath)); - } + $paths = []; + foreach ($inputPaths as $inputPath) { + $paths[] = $this->validateInputFile($inputPath); } + + $this->inputPaths = $paths; } public function runBuild( - bool $watch, - bool $poll, - bool $minify, + bool $watch, + bool $poll, + bool $minify, + ?string $inputFile = null, ): Process { $binary = $this->createBinary(); - $arguments = ['-c', $this->configPath, '-i', $this->inputPath, '-o', $this->getInternalOutputCssPath()]; + + $inputPath = $this->validateInputFile($inputFile ?? $this->inputPaths[0]); + if (!in_array($inputPath, $this->inputPaths)) { + throw new \InvalidArgumentException(sprintf('The input CSS file "%s" is not one of the configured input files.', $inputPath)); + } + + $arguments = ['-c', $this->configPath, '-i', $inputPath, '-o', $this->getInternalOutputCssPath($inputPath)]; if ($watch) { $arguments[] = '--watch'; if ($poll) { @@ -102,14 +106,15 @@ public function setOutput(SymfonyStyle $output): void $this->output = $output; } - public function getInternalOutputCssPath(): string + public function getInternalOutputCssPath(string $inputPath): string { - return $this->tailwindVarDir.'/tailwind.built.css'; + $inputFileName = pathinfo($inputPath, PATHINFO_FILENAME); + return "{$this->tailwindVarDir}/{$inputFileName}.built.css"; } - public function getInputCssPath(): string + public function getInputCssPaths(): array { - return $this->inputPath; + return $this->inputPaths; } public function getConfigFilePath(): string @@ -117,13 +122,26 @@ public function getConfigFilePath(): string return $this->configPath; } - public function getOutputCssContent(): string + public function getOutputCssContent(?string $inputFile = null): string { - if (!is_file($this->getInternalOutputCssPath())) { + if (!is_file($this->getInternalOutputCssPath($inputFile))) { throw new \RuntimeException('Built Tailwind CSS file does not exist: run "php bin/console tailwind:build" to generate it'); } - return file_get_contents($this->getInternalOutputCssPath()); + return file_get_contents($this->getInternalOutputCssPath($inputFile)); + } + + private function validateInputFile(string $inputPath): string + { + if (is_file($inputPath)) { + return $inputPath; + } + + if (is_file($this->projectRootDir.'/'.$inputPath)) { + return $this->projectRootDir.'/'.$inputPath; + } + + throw new \InvalidArgumentException(sprintf('The input CSS file "%s" does not exist.', $inputPath)); } private function createBinary(): TailwindBinary diff --git a/tests/AssetMapper/TailwindCssAssetCompilerTest.php b/tests/AssetMapper/TailwindCssAssetCompilerTest.php index 32f9f55..93eb987 100644 --- a/tests/AssetMapper/TailwindCssAssetCompilerTest.php +++ b/tests/AssetMapper/TailwindCssAssetCompilerTest.php @@ -21,8 +21,8 @@ public function testCompile() { $builder = $this->createMock(TailwindBuilder::class); $builder->expects($this->any()) - ->method('getInputCssPath') - ->willReturn(__DIR__.'/../fixtures/assets/styles/app.css'); + ->method('getInputCssPaths') + ->willReturn([__DIR__.'/../fixtures/assets/styles/app.css']); $builder->expects($this->once()) ->method('getInternalOutputCssPath'); $builder->expects($this->once()) diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index aa86b12..949d07c 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -24,7 +24,7 @@ protected function setUp(): void $fs->remove($tailwindVarDir); } $fs->mkdir($tailwindVarDir); - file_put_contents($tailwindVarDir.'/tailwind.built.css', <<wait(); $this->assertTrue($process->isSuccessful()); - $this->assertFileExists(__DIR__.'/fixtures/var/tailwind/tailwind.built.css'); + $this->assertFileExists(__DIR__.'/fixtures/var/tailwind/app.built.css'); - $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/tailwind.built.css'); + $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/app.built.css'); $this->assertStringContainsString("body {\n background-color: red;\n}", $outputFileContents, 'The output file should contain non-minified CSS.'); } @@ -60,7 +60,7 @@ public function testIntegrationWithMinify(): void { $builder = new TailwindBuilder( __DIR__.'/fixtures', - __DIR__.'/fixtures/assets/styles/app.css', + [__DIR__.'/fixtures/assets/styles/app.css'], __DIR__.'/fixtures/var/tailwind', new ArrayAdapter(), null, @@ -71,9 +71,30 @@ public function testIntegrationWithMinify(): void $process->wait(); $this->assertTrue($process->isSuccessful()); - $this->assertFileExists(__DIR__.'/fixtures/var/tailwind/tailwind.built.css'); + $this->assertFileExists(__DIR__.'/fixtures/var/tailwind/app.built.css'); - $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/tailwind.built.css'); + $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/app.built.css'); $this->assertStringContainsString('body{background-color:red}', $outputFileContents, 'The output file should contain minified CSS.'); } + + public function testBuildProvidedInputFile(): void + { + $builder = new TailwindBuilder( + __DIR__.'/fixtures', + [__DIR__.'/fixtures/assets/styles/app.css', __DIR__.'/fixtures/assets/styles/second.css'], + __DIR__.'/fixtures/var/tailwind', + new ArrayAdapter(), + null, + null, + __DIR__.'/fixtures/tailwind.config.js' + ); + $process = $builder->runBuild(watch: false, poll: false, minify: true, inputFile: 'assets/styles/second.css'); + $process->wait(); + + $this->assertTrue($process->isSuccessful()); + $this->assertFileExists(__DIR__.'/fixtures/var/tailwind/second.built.css'); + + $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/second.built.css'); + $this->assertStringContainsString('body{background-color:blue}', $outputFileContents, 'The output file should contain minified CSS.'); + } } diff --git a/tests/fixtures/TailwindTestKernel.php b/tests/fixtures/TailwindTestKernel.php index d2a0127..98ed999 100644 --- a/tests/fixtures/TailwindTestKernel.php +++ b/tests/fixtures/TailwindTestKernel.php @@ -51,7 +51,7 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa ]); $container->loadFromExtension('symfonycasts_tailwind', [ - 'input_css' => __DIR__.'/assets/styles/app.css', + 'input_css' => [__DIR__.'/assets/styles/app.css'], ]); } diff --git a/tests/fixtures/assets/styles/second.css b/tests/fixtures/assets/styles/second.css new file mode 100644 index 0000000..e16ba4d --- /dev/null +++ b/tests/fixtures/assets/styles/second.css @@ -0,0 +1,7 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + background-color: blue; +} From 9d47f2875a131162cc9a9224f0566aa48326a231 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 03:40:39 +0100 Subject: [PATCH 02/11] feat: Allow backward compatibility by allowing to accept a string as input css --- src/DependencyInjection/TailwindExtension.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DependencyInjection/TailwindExtension.php b/src/DependencyInjection/TailwindExtension.php index 6cfa1be..5bb2912 100644 --- a/src/DependencyInjection/TailwindExtension.php +++ b/src/DependencyInjection/TailwindExtension.php @@ -55,6 +55,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->children() ->arrayNode('input_css') ->prototype('scalar')->end() + ->beforeNormalization()->castToArray()->end() ->info('Paths to CSS files to process through Tailwind') ->defaultValue(['%kernel.project_dir%/assets/styles/app.css']) ->end() From 2055597baffaa8afb5085a488eba926b7a569e92 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 04:09:46 +0100 Subject: [PATCH 03/11] fix: Fix "The input CSS file is not one of the configured input files." when css file is provided as relative path to tailwind:build command --- src/TailwindBuilder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TailwindBuilder.php b/src/TailwindBuilder.php index a10cb05..4d5fdd9 100644 --- a/src/TailwindBuilder.php +++ b/src/TailwindBuilder.php @@ -51,7 +51,7 @@ public function runBuild( ): Process { $binary = $this->createBinary(); - $inputPath = $this->validateInputFile($inputFile ?? $this->inputPaths[0]); + $inputPath = realpath($this->validateInputFile($inputFile ?? $this->inputPaths[0])); if (!in_array($inputPath, $this->inputPaths)) { throw new \InvalidArgumentException(sprintf('The input CSS file "%s" is not one of the configured input files.', $inputPath)); } @@ -86,7 +86,7 @@ public function runBuild( return $process; } - public function runInit() + public function runInit(): Process { $binary = $this->createBinary(); $process = $binary->createProcess(['init']); From dee9535a2aceb0c172692abb19e9db5fa1af70fa Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 04:10:33 +0100 Subject: [PATCH 04/11] feat: Provide input css file as an optional argument instead of an option to `tailwind:build` command --- src/Command/TailwindBuildCommand.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Command/TailwindBuildCommand.php b/src/Command/TailwindBuildCommand.php index 0ac928e..dfd60ed 100644 --- a/src/Command/TailwindBuildCommand.php +++ b/src/Command/TailwindBuildCommand.php @@ -11,6 +11,7 @@ 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; @@ -32,7 +33,7 @@ public function __construct( protected function configure(): void { $this - ->addOption('input', 'i', InputOption::VALUE_OPTIONAL, 'The input CSS file') + ->addArgument('input', InputArgument::OPTIONAL, 'The input CSS file to compile') ->addOption('watch', 'w', null, 'Watch for changes and rebuild automatically') ->addOption('poll', null, null, 'Use polling instead of filesystem events when watching') ->addOption('minify', 'm', InputOption::VALUE_NONE, 'Minify the output CSS') @@ -48,7 +49,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int watch: $input->getOption('watch'), poll: $input->getOption('poll'), minify: $input->getOption('minify'), - inputFile: $input->getOption('input'), + inputFile: $input->getArgument('input'), ); $process->wait(function ($type, $buffer) use ($io) { $io->write($buffer); From 51a0c53c8dfa093d7b64bdfb8278c956632f2103 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 17:52:01 +0100 Subject: [PATCH 05/11] fix: Fix failed PHPStan and PHP CS Fixer tests --- phpstan.neon.dist | 2 +- src/AssetMapper/TailwindCssAssetCompiler.php | 2 +- src/TailwindBuilder.php | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index d256b0e..1adc4ff 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -4,6 +4,6 @@ parameters: - src ignoreErrors: - - message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:scalarNode\\(\\)\\.$#" + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:beforeNormalization\\(\\)\\.$#" count: 1 path: src/DependencyInjection/TailwindExtension.php diff --git a/src/AssetMapper/TailwindCssAssetCompiler.php b/src/AssetMapper/TailwindCssAssetCompiler.php index c667b3b..6f43ce7 100644 --- a/src/AssetMapper/TailwindCssAssetCompiler.php +++ b/src/AssetMapper/TailwindCssAssetCompiler.php @@ -25,7 +25,7 @@ public function __construct(private TailwindBuilder $tailwindBuilder) public function supports(MappedAsset $asset): bool { - return in_array( + return \in_array( realpath($asset->sourcePath), array_map('realpath', $this->tailwindBuilder->getInputCssPaths()) ); diff --git a/src/TailwindBuilder.php b/src/TailwindBuilder.php index 4d5fdd9..7efa3c8 100644 --- a/src/TailwindBuilder.php +++ b/src/TailwindBuilder.php @@ -44,15 +44,15 @@ public function __construct( } public function runBuild( - bool $watch, - bool $poll, - bool $minify, + bool $watch, + bool $poll, + bool $minify, ?string $inputFile = null, ): Process { $binary = $this->createBinary(); $inputPath = realpath($this->validateInputFile($inputFile ?? $this->inputPaths[0])); - if (!in_array($inputPath, $this->inputPaths)) { + if (!\in_array($inputPath, $this->inputPaths)) { throw new \InvalidArgumentException(sprintf('The input CSS file "%s" is not one of the configured input files.', $inputPath)); } @@ -108,7 +108,8 @@ public function setOutput(SymfonyStyle $output): void public function getInternalOutputCssPath(string $inputPath): string { - $inputFileName = pathinfo($inputPath, PATHINFO_FILENAME); + $inputFileName = pathinfo($inputPath, \PATHINFO_FILENAME); + return "{$this->tailwindVarDir}/{$inputFileName}.built.css"; } From 52ae22ca557f22bf0b4c606aa8dbb2faa6371a20 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 18:55:07 +0100 Subject: [PATCH 06/11] fix: Store input files with their absolute path in Tailwind Builder --- src/AssetMapper/TailwindCssAssetCompiler.php | 2 +- src/TailwindBuilder.php | 6 +++--- tests/AssetMapper/TailwindCssAssetCompilerTest.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/AssetMapper/TailwindCssAssetCompiler.php b/src/AssetMapper/TailwindCssAssetCompiler.php index 6f43ce7..aa0dce7 100644 --- a/src/AssetMapper/TailwindCssAssetCompiler.php +++ b/src/AssetMapper/TailwindCssAssetCompiler.php @@ -27,7 +27,7 @@ public function supports(MappedAsset $asset): bool { return \in_array( realpath($asset->sourcePath), - array_map('realpath', $this->tailwindBuilder->getInputCssPaths()) + $this->tailwindBuilder->getInputCssPaths(), ); } diff --git a/src/TailwindBuilder.php b/src/TailwindBuilder.php index 7efa3c8..528caab 100644 --- a/src/TailwindBuilder.php +++ b/src/TailwindBuilder.php @@ -51,7 +51,7 @@ public function runBuild( ): Process { $binary = $this->createBinary(); - $inputPath = realpath($this->validateInputFile($inputFile ?? $this->inputPaths[0])); + $inputPath = $this->validateInputFile($inputFile ?? $this->inputPaths[0]); if (!\in_array($inputPath, $this->inputPaths)) { throw new \InvalidArgumentException(sprintf('The input CSS file "%s" is not one of the configured input files.', $inputPath)); } @@ -135,11 +135,11 @@ public function getOutputCssContent(?string $inputFile = null): string private function validateInputFile(string $inputPath): string { if (is_file($inputPath)) { - return $inputPath; + return realpath($inputPath); } if (is_file($this->projectRootDir.'/'.$inputPath)) { - return $this->projectRootDir.'/'.$inputPath; + return realpath($this->projectRootDir.'/'.$inputPath); } throw new \InvalidArgumentException(sprintf('The input CSS file "%s" does not exist.', $inputPath)); diff --git a/tests/AssetMapper/TailwindCssAssetCompilerTest.php b/tests/AssetMapper/TailwindCssAssetCompilerTest.php index 93eb987..2290b3a 100644 --- a/tests/AssetMapper/TailwindCssAssetCompilerTest.php +++ b/tests/AssetMapper/TailwindCssAssetCompilerTest.php @@ -22,7 +22,7 @@ public function testCompile() $builder = $this->createMock(TailwindBuilder::class); $builder->expects($this->any()) ->method('getInputCssPaths') - ->willReturn([__DIR__.'/../fixtures/assets/styles/app.css']); + ->willReturn([\dirname(__DIR__).'/fixtures/assets/styles/app.css']); $builder->expects($this->once()) ->method('getInternalOutputCssPath'); $builder->expects($this->once()) From 54d263ddc7fa36e56929fdcecff0a8fcdc18b344 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Mon, 3 Jun 2024 19:19:17 +0100 Subject: [PATCH 07/11] fix: Fix inconsistency in `getInputCssPaths` mocked return value. The mocked return value should use `realpath` --- tests/AssetMapper/TailwindCssAssetCompilerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/AssetMapper/TailwindCssAssetCompilerTest.php b/tests/AssetMapper/TailwindCssAssetCompilerTest.php index 2290b3a..30db211 100644 --- a/tests/AssetMapper/TailwindCssAssetCompilerTest.php +++ b/tests/AssetMapper/TailwindCssAssetCompilerTest.php @@ -22,7 +22,7 @@ public function testCompile() $builder = $this->createMock(TailwindBuilder::class); $builder->expects($this->any()) ->method('getInputCssPaths') - ->willReturn([\dirname(__DIR__).'/fixtures/assets/styles/app.css']); + ->willReturn([realpath(__DIR__.'/../fixtures/assets/styles/app.css')]); $builder->expects($this->once()) ->method('getInternalOutputCssPath'); $builder->expects($this->once()) From a718d866f8efd2533e0dd65b49218a9b3c8bd8ca Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Wed, 5 Jun 2024 08:31:42 +0100 Subject: [PATCH 08/11] fix: Revert the documentation to use the `input_css` config option --- doc/index.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index ab0fef7..57dbc38 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -151,7 +151,7 @@ To see the full config from this bundle, run: $ php bin/console config:dump symfonycasts_tailwind -The main option is ``input`` option, which defaults to ``assets/styles/app.css``. +The main option is ``input_css`` option, which defaults to ``assets/styles/app.css``. This represents the "source" Tailwind files (the one that contains the ``@tailwind`` directives): @@ -159,8 +159,16 @@ directives): # config/packages/symfonycasts_tailwind.yaml symfonycasts_tailwind: - input: - - 'assets/styles/other.css' + input_css: 'assets/styles/other.css' + +It's possible to use multiple input files by providing an array: +.. code-block:: yaml + + # config/packages/symfonycasts_tailwind.yaml + symfonycasts_tailwind: + input_css: + - 'assets/styles/other.css' + - 'assets/styles/another.css' Another option is the ``config_file`` option, which defaults to ``tailwind.config.js``. This represents the Tailwind configuration file: From 9c09e01c3eb7b29a1d9f99d505bf1de8ae90631e Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Wed, 5 Jun 2024 08:33:08 +0100 Subject: [PATCH 09/11] docs: Update the documentation to explain the current internal working --- doc/index.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index 57dbc38..6717670 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -94,9 +94,11 @@ download the correct Tailwind binary for your system into a ``var/tailwind/`` directory. When you run ``tailwind:build``, that binary is used to compile -your CSS file into a ``var/tailwind/tailwind.built.css`` file. Finally, -when the contents of ``assets/styles/app.css`` is requested, the bundle -swaps the contents of that file with the contents of ``var/tailwind/tailwind.built.css``. +each CSS file into a ``var/tailwind/.built.css`` file. +Finally, when the contents of the CSS file is requested, the bundle swaps the +contents of that file with the contents of ``var/tailwind/.built.css``. + +E.g. : A request for ``assets/styles/app.css`` will be replaced by ``var/tailwind/app.built.css``. Nice! Deploying From 123c504b0e21c1daed5548d8197a0def34811fe3 Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Wed, 5 Jun 2024 08:42:10 +0100 Subject: [PATCH 10/11] refactor: Rename `tailwind:bundle`'s argument from `input` to `input_css` for consistency with config file --- src/Command/TailwindBuildCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Command/TailwindBuildCommand.php b/src/Command/TailwindBuildCommand.php index dfd60ed..d86ee0b 100644 --- a/src/Command/TailwindBuildCommand.php +++ b/src/Command/TailwindBuildCommand.php @@ -33,7 +33,7 @@ public function __construct( protected function configure(): void { $this - ->addArgument('input', InputArgument::OPTIONAL, 'The input CSS file to compile') + ->addArgument('input_css', InputArgument::OPTIONAL, 'The input CSS file to compile') ->addOption('watch', 'w', null, 'Watch for changes and rebuild automatically') ->addOption('poll', null, null, 'Use polling instead of filesystem events when watching') ->addOption('minify', 'm', InputOption::VALUE_NONE, 'Minify the output CSS') @@ -49,7 +49,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int watch: $input->getOption('watch'), poll: $input->getOption('poll'), minify: $input->getOption('minify'), - inputFile: $input->getArgument('input'), + inputFile: $input->getArgument('input_css'), ); $process->wait(function ($type, $buffer) use ($io) { $io->write($buffer); From 8d6d8beb7498586e8d299d91d6d031188991924c Mon Sep 17 00:00:00 2001 From: Raphael Alogou Date: Wed, 5 Jun 2024 08:42:34 +0100 Subject: [PATCH 11/11] refactor: Change `getInputCssContent` parameter type from `?string` to `string` as it's always passed --- src/TailwindBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TailwindBuilder.php b/src/TailwindBuilder.php index 528caab..a8c2d4f 100644 --- a/src/TailwindBuilder.php +++ b/src/TailwindBuilder.php @@ -123,7 +123,7 @@ public function getConfigFilePath(): string return $this->configPath; } - public function getOutputCssContent(?string $inputFile = null): string + public function getOutputCssContent(string $inputFile): string { if (!is_file($this->getInternalOutputCssPath($inputFile))) { throw new \RuntimeException('Built Tailwind CSS file does not exist: run "php bin/console tailwind:build" to generate it');