Skip to content

Commit 43ad79d

Browse files
fracsibocharsky-bw
andauthored
Allow version configuration (#38)
* Allow version configuration * Test file cleanup fix * Apply suggestions from code review Co-authored-by: Victor Bocharsky <[email protected]> * Update doc/index.rst Co-authored-by: Victor Bocharsky <[email protected]> --------- Co-authored-by: Victor Bocharsky <[email protected]>
1 parent 3013811 commit 43ad79d

File tree

7 files changed

+42
-19
lines changed

7 files changed

+42
-19
lines changed

config/services.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
abstract_arg('path to source Tailwind CSS file'),
2020
param('kernel.project_dir').'/var/tailwind',
2121
abstract_arg('path to tailwind binary'),
22+
abstract_arg('Tailwind binary version'),
2223
])
2324

2425
->set('tailwind.command.build', TailwindBuildCommand::class)

doc/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,15 @@ To instruct the bundle to use that binary instead, set the ``binary`` option:
147147
# config/packages/symfonycasts_tailwind.yaml
148148
symfonycasts_tailwind:
149149
binary: 'node_modules/.bin/tailwindcss'
150+
151+
Using a Different Binary Version
152+
------------------------
153+
154+
By default the latest standalone Tailwind binary gets downloaded. However,
155+
if you want to use a different version, you can specify the version to use,
156+
set ``binary_version`` option:
157+
158+
.. code-block:: yaml
159+
# config/packages/symfonycasts_tailwind.yaml
160+
symfonycasts_tailwind:
161+
binary_version: 'v3.3.0'

src/DependencyInjection/TailwindExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function load(array $configs, ContainerBuilder $container): void
3030
$container->findDefinition('tailwind.builder')
3131
->replaceArgument(1, $config['input_css'])
3232
->replaceArgument(3, $config['binary'])
33+
->replaceArgument(4, $config['binary_version'])
3334
;
3435
}
3536

@@ -59,6 +60,10 @@ public function getConfigTreeBuilder(): TreeBuilder
5960
->info('The tailwind binary to use instead of downloading a new one')
6061
->defaultNull()
6162
->end()
63+
->scalarNode('binary_version')
64+
->info('Tailwind CLI version to download - null means the latest version')
65+
->defaultNull()
66+
->end()
6267
->end();
6368

6469
return $treeBuilder;

src/TailwindBinary.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121
*/
2222
class TailwindBinary
2323
{
24-
private const DEFAULT_VERSION = 'v3.3.5';
2524
private HttpClientInterface $httpClient;
25+
private ?string $cachedVersion = null;
2626

2727
public function __construct(
2828
private string $binaryDownloadDir,
2929
private string $cwd,
3030
private ?string $binaryPath,
31+
private ?string $binaryVersion,
3132
private ?SymfonyStyle $output = null,
3233
HttpClientInterface $httpClient = null,
3334
) {
@@ -37,7 +38,7 @@ public function __construct(
3738
public function createProcess(array $arguments = []): Process
3839
{
3940
if (null === $this->binaryPath) {
40-
$binary = $this->binaryDownloadDir.'/'.self::getBinaryName();
41+
$binary = $this->binaryDownloadDir.'/'.$this->getVersion().'/'.self::getBinaryName();
4142
if (!is_file($binary)) {
4243
$this->downloadExecutable();
4344
}
@@ -53,15 +54,15 @@ public function createProcess(array $arguments = []): Process
5354

5455
private function downloadExecutable(): void
5556
{
56-
$url = sprintf('https://github.com/tailwindlabs/tailwindcss/releases/download/%s/%s', $this->getLatestVersion(), self::getBinaryName());
57+
$url = sprintf('https://github.com/tailwindlabs/tailwindcss/releases/download/%s/%s', $this->getVersion(), self::getBinaryName());
5758

5859
$this->output?->note(sprintf('Downloading TailwindCSS binary from %s', $url));
5960

60-
if (!is_dir($this->binaryDownloadDir)) {
61-
mkdir($this->binaryDownloadDir, 0777, true);
61+
if (!is_dir($this->binaryDownloadDir.'/'.$this->getVersion())) {
62+
mkdir($this->binaryDownloadDir.'/'.$this->getVersion(), 0777, true);
6263
}
6364

64-
$targetPath = $this->binaryDownloadDir.'/'.self::getBinaryName();
65+
$targetPath = $this->binaryDownloadDir.'/'.$this->getVersion().'/'.self::getBinaryName();
6566
$progressBar = null;
6667

6768
$response = $this->httpClient->request('GET', $url, [
@@ -89,14 +90,19 @@ private function downloadExecutable(): void
8990
chmod($targetPath, 0777);
9091
}
9192

93+
private function getVersion(): string
94+
{
95+
return $this->cachedVersion ??= $this->binaryVersion ?? $this->getLatestVersion();
96+
}
97+
9298
private function getLatestVersion(): string
9399
{
94100
try {
95101
$response = $this->httpClient->request('GET', 'https://api.github.com/repos/tailwindlabs/tailwindcss/releases/latest');
96102

97-
return $response->toArray()['name'] ?? self::DEFAULT_VERSION;
98-
} catch (\Throwable) {
99-
return self::DEFAULT_VERSION;
103+
return $response->toArray()['name'] ?? throw new \Exception('Cannot get the latest version name from response JSON.');
104+
} catch (\Throwable $e) {
105+
throw new \Exception('Cannot determine latest Tailwind CLI binary version. Please specify a version in the configuration.', previous: $e);
100106
}
101107
}
102108

src/TailwindBuilder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function __construct(
3030
string $inputPath,
3131
private readonly string $tailwindVarDir,
3232
private readonly ?string $binaryPath = null,
33+
private readonly ?string $binaryVersion = null,
3334
) {
3435
if (is_file($inputPath)) {
3536
$this->inputPath = $inputPath;
@@ -115,6 +116,6 @@ public function getOutputCssContent(): string
115116

116117
private function createBinary(): TailwindBinary
117118
{
118-
return new TailwindBinary($this->tailwindVarDir, $this->projectRootDir, $this->binaryPath, $this->output);
119+
return new TailwindBinary($this->tailwindVarDir, $this->projectRootDir, $this->binaryPath, $this->binaryVersion, $this->output);
119120
}
120121
}

tests/TailwindBinaryTest.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,18 @@ public function testBinaryIsDownloadedAndProcessCreated()
2727
$fs->mkdir($binaryDownloadDir);
2828

2929
$client = new MockHttpClient([
30-
new MockResponse('{}'),
3130
new MockResponse('fake binary contents'),
3231
]);
3332

34-
$binary = new TailwindBinary($binaryDownloadDir, __DIR__, null, null, $client);
33+
$binary = new TailwindBinary($binaryDownloadDir, __DIR__, null, 'fake-version', null, $client);
3534
$process = $binary->createProcess(['-i', 'fake.css']);
36-
$this->assertFileExists($binaryDownloadDir.'/'.TailwindBinary::getBinaryName());
35+
$this->assertFileExists($binaryDownloadDir.'/fake-version/'.TailwindBinary::getBinaryName());
3736

3837
// Windows doesn't wrap arguments in quotes
3938
$expectedTemplate = '\\' === \DIRECTORY_SEPARATOR ? '"%s" -i fake.css' : "'%s' '-i' 'fake.css'";
4039

4140
$this->assertSame(
42-
sprintf($expectedTemplate, $binaryDownloadDir.'/'.TailwindBinary::getBinaryName()),
41+
sprintf($expectedTemplate, $binaryDownloadDir.'/fake-version/'.TailwindBinary::getBinaryName()),
4342
$process->getCommandLine()
4443
);
4544
}
@@ -48,7 +47,7 @@ public function testCustomBinaryUsed()
4847
{
4948
$client = new MockHttpClient();
5049

51-
$binary = new TailwindBinary('', __DIR__, 'custom-binary', null, $client);
50+
$binary = new TailwindBinary('', __DIR__, 'custom-binary', null, null, null, $client);
5251
$process = $binary->createProcess(['-i', 'fake.css']);
5352
// on windows, arguments are not wrapped in quotes
5453
$expected = '\\' === \DIRECTORY_SEPARATOR ? 'custom-binary -i fake.css' : "'custom-binary' '-i' 'fake.css'";

tests/TailwindBuilderTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@ protected function setUp(): void
2727

2828
protected function tearDown(): void
2929
{
30+
$fs = new Filesystem();
3031
$finder = new Finder();
31-
$finder->in(__DIR__.'/fixtures/var/tailwind')->files();
32-
foreach ($finder as $file) {
33-
unlink($file->getRealPath());
34-
}
32+
$finder->in(__DIR__.'/fixtures/var/tailwind');
33+
$fs->remove($finder);
3534
}
3635

3736
public function testIntegrationWithDefaultOptions(): void

0 commit comments

Comments
 (0)