diff --git a/ignis/app.py b/ignis/app.py index fe6ec39..dc63087 100644 --- a/ignis/app.py +++ b/ignis/app.py @@ -168,7 +168,7 @@ class IgnisApp(Gtk.Application, IgnisGObject): """ Apply a CSS/SCSS/SASS style from a path. If ``style_path`` has a ``.sass`` or ``.scss`` extension, it will be automatically compiled. - Requires ``dart-sass`` for SASS/SCSS compilation. + Requires either ``dart-sass`` or ``grass-sass`` for SASS/SCSS compilation. Args: style_path: Path to the .css/.scss/.sass file. diff --git a/ignis/exceptions.py b/ignis/exceptions.py index f3a2ed5..e803171 100644 --- a/ignis/exceptions.py +++ b/ignis/exceptions.py @@ -227,7 +227,7 @@ class GstPluginNotFoundError(Exception): class SassCompilationError(Exception): """ - Raised when Dart Sass compilation fails. + Raised when the Sass compilation fails. """ def __init__(self, stderr: str, *args: object) -> None: @@ -239,19 +239,19 @@ class SassCompilationError(Exception): """ - required, read-only - The stderr output from Dart Sass. + The stderr output from the Sass compiler. """ return self._stderr -class DartSassNotFoundError(Exception): +class SassNotFoundError(Exception): """ - Raised when Dart Sass is not found. + Raised when a compatible Sass compiler is not found. """ def __init__(self, *args: object) -> None: super().__init__( - "Dart Sass not found! To compile SCSS/SASS, install dart-sass", *args + "Sass compiler not found! To compile SCSS/SASS, install either dart-sass or grass-sass", *args ) diff --git a/ignis/utils/sass.py b/ignis/utils/sass.py index 9bd829d..a25fb2e 100644 --- a/ignis/utils/sass.py +++ b/ignis/utils/sass.py @@ -1,14 +1,31 @@ import os +import shutil import subprocess -from ignis.exceptions import SassCompilationError, DartSassNotFoundError +from ignis.exceptions import SassCompilationError, SassNotFoundError TEMP_DIR = "/tmp/ignis" COMPILED_CSS = f"{TEMP_DIR}/compiled.css" os.makedirs(TEMP_DIR, exist_ok=True) +# pick a Sass compiler +sass_compiler = None + +sass_compilers = [ + "sass", # dart-sass + "grass" # grass-sass +] + +for compiler in sass_compilers: + sass_compiler = shutil.which(compiler) + + if sass_compiler: + break + def compile_file(path: str) -> str: - result = subprocess.run(["sass", path, COMPILED_CSS], capture_output=True) + assert sass_compiler + + result = subprocess.run([sass_compiler, path, COMPILED_CSS], capture_output=True) if result.returncode != 0: raise SassCompilationError(result.stderr.decode()) @@ -18,8 +35,10 @@ def compile_file(path: str) -> str: def compile_string(string: str) -> str: + assert sass_compiler + process = subprocess.Popen( - ["sass", "--stdin"], + [sass_compiler, "--stdin"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -35,7 +54,8 @@ def compile_string(string: str) -> str: def sass_compile(path: str | None = None, string: str | None = None) -> str: """ Compile a SASS/SCSS file or string. - Requires `Dart Sass `_. + Requires either `Dart Sass `_ + or `Grass `_. Args: path: The path to the SASS/SCSS file. @@ -43,11 +63,11 @@ def sass_compile(path: str | None = None, string: str | None = None) -> str: Raises: TypeError: If neither of the arguments is provided. - DartSassNotFoundError: If Dart Sass not found. + SassNotFoundError: If no Sass compiler is available. SassCompilationError: If an error occurred while compiling SASS/SCSS. """ - if not os.path.exists("/bin/sass"): - raise DartSassNotFoundError() + if not sass_compiler: + raise SassNotFoundError() if string: return compile_string(string)