Skip to content
1 change: 1 addition & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
abstract_arg('path to css directory'),
param('kernel.project_dir'),
abstract_arg('path to binary'),
abstract_arg('path to binary version'),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not the path to binary version but simply the binary version ?

abstract_arg('embed sourcemap'),
])

Expand Down
13 changes: 13 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,17 @@ To see the full config from this bundle, run:

The main option is ``root_sass`` option, which defaults to ``assets/styles/app.scss``. This represents the source Sass file.

Using a different version
--------------------------
This bundle installs for you a default version. However, if you want an explicit version of Dart Sass you can instruct the bundle to download that version, set the ``version`` option:

.. code-block:: yaml

symfonycasts_sass:
version: 1.69.0

When you change this version, it will not be upgraded automatically. Remove the `var/dart-sass` directory first to rebuild with the configured version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using the binary version in the directory name containing the binary, so when we change the version it know that it should download the new version?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be sweet! It would solve WTF moments when it's cached with older version 👍

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like a great solution, I'll implement and document it!


Using a different binary
--------------------------

Expand All @@ -151,3 +162,5 @@ This bundle already installed for you the right binary. However, if you already

symfonycasts_sass:
binary: 'node_modules/.bin/sass'

This configuration overrides any specific version configuration.
Comment thread
bocharsky-bw marked this conversation as resolved.
Outdated
7 changes: 6 additions & 1 deletion src/DependencyInjection/SymfonycastsSassExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public function load(array $configs, ContainerBuilder $container): void
->replaceArgument(0, $config['root_sass'])
->replaceArgument(1, '%kernel.project_dir%/var/sass')
->replaceArgument(3, $config['binary'])
->replaceArgument(4, $config['embed_sourcemap'])
->replaceArgument(4, $config['version'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep the name binary_version. This is the naming we use in the code and it make think more clear.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

->replaceArgument(5, $config['embed_sourcemap'])
;

$container->findDefinition('sass.css_asset_compiler')
Expand Down Expand Up @@ -81,6 +82,10 @@ public function getConfigTreeBuilder(): TreeBuilder
->info('The Sass binary to use')
->defaultNull()
->end()
->scalarNode('version')
->info('The Sass binary version to download')
->defaultNull()
Comment thread
bocharsky-bw marked this conversation as resolved.
->end()
Comment thread
dorxy marked this conversation as resolved.
Outdated
->scalarNode('embed_sourcemap')
->info('Whether to embed the sourcemap in the compiled CSS. By default, enabled only when debug mode is on.')
->defaultValue('%kernel.debug%')
Expand Down
15 changes: 12 additions & 3 deletions src/SassBinary.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@

class SassBinary
{
private const VERSION = '1.63.6';
private const DEFAULT_VERSION = '1.63.6';
private HttpClientInterface $httpClient;

public function __construct(
private string $binaryDownloadDir,
private ?string $binaryPath = null,
private ?string $binaryVersion = null,
Comment thread
bocharsky-bw marked this conversation as resolved.
private ?SymfonyStyle $output = null,
HttpClientInterface $httpClient = null
) {
$this->httpClient = $httpClient ?? HttpClient::create();
$this->binaryVersion ??= self::DEFAULT_VERSION;
}

/**
Expand All @@ -49,7 +51,7 @@ public function createProcess(array $args): Process

public function downloadExecutable(): void
{
$url = sprintf('https://github.com/sass/dart-sass/releases/download/%s/%s', self::VERSION, $this->getBinaryName());
$url = sprintf('https://github.com/sass/dart-sass/releases/download/%s/%s', $this->binaryVersion, $this->getBinaryName());
$isZip = str_ends_with($url, '.zip');

$this->output?->note('Downloading Sass binary from '.$url);
Expand All @@ -75,6 +77,13 @@ public function downloadExecutable(): void
},
]);

if (404 === $response->getStatusCode()) {
if (self::DEFAULT_VERSION !== $this->binaryVersion) {
throw new \Exception(sprintf('Cannot download sass binary. Please verify version `%s` exists for your machine.', $this->binaryVersion));
Comment thread
bocharsky-bw marked this conversation as resolved.
Outdated
}
throw new \Exception(sprintf('Cannot download sass binary. Response code: %d', $response->getStatusCode()));
Comment thread
bocharsky-bw marked this conversation as resolved.
Outdated
}

$fileHandler = fopen($targetPath, 'w');
foreach ($this->httpClient->stream($response) as $chunk) {
fwrite($fileHandler, $chunk->getContent());
Expand Down Expand Up @@ -155,7 +164,7 @@ public function getBinaryName(): string

private function buildBinaryFileName(string $os, bool $isWindows = false): string
{
return 'dart-sass-'.self::VERSION.'-'.$os.($isWindows ? '.zip' : '.tar.gz');
return 'dart-sass-'.$this->binaryVersion.'-'.$os.($isWindows ? '.zip' : '.tar.gz');
}

private function getDefaultBinaryPath(): string
Expand Down
3 changes: 2 additions & 1 deletion src/SassBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public function __construct(
private readonly string $cssPath,
private readonly string $projectRootDir,
private readonly ?string $binaryPath,
private readonly ?string $binaryVersion,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, this will lead to BC breaks. What about to move this to the end instead?

private readonly bool $embedSourcemap,
) {
}
Expand Down Expand Up @@ -99,6 +100,6 @@ public static function guessCssNameFromSassFile(string $sassFile, string $output

private function createBinary(): SassBinary
{
return new SassBinary($this->projectRootDir.'/var', $this->binaryPath, $this->output);
return new SassBinary($this->projectRootDir.'/var', $this->binaryPath, $this->binaryVersion, $this->output);
}
}
1 change: 1 addition & 0 deletions tests/SassBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function testIntegration(): void
__DIR__.'/fixtures/assets',
__DIR__.'/fixtures',
null,
null,
false
);

Expand Down
40 changes: 40 additions & 0 deletions tests/VersionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test should be on the FunctionalTest class


declare(strict_types=1);

/*
* This file is part of the SymfonyCasts SassBundle package.
* Copyright (c) SymfonyCasts <https://symfonycasts.com/>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfonycasts\SassBundle\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;
use Symfonycasts\SassBundle\SassBinary;

class VersionTest extends TestCase
{
protected function tearDown(): void
{
if (file_exists(__DIR__.'/fixtures/var')) {
$filesystem = new Filesystem();
$filesystem->remove(__DIR__.'/fixtures/var');
}
}

public function testVersionDownloaded(): void
{
$testedVersion = '1.69.5'; // This should differ from the SassBinary::DEFAULT_VERSION constant
$binary = new SassBinary(__DIR__.'/fixtures/var/version', null, $testedVersion);

$binary->downloadExecutable();
$sassVersionProcess = new Process([__DIR__.'/fixtures/var/version/dart-sass/sass', '--version']);
$sassVersionProcess->run();

$this->assertSame(trim($sassVersionProcess->getOutput(), \PHP_EOL), $testedVersion);
}
}