improving _compile_root_stylesheet function and add folder stylesheets unit test

This commit is contained in:
KronosDev-Pro 2024-11-07 13:50:13 +00:00
parent 2ca363cfc0
commit 6898a266c9
2 changed files with 64 additions and 66 deletions

View File

@ -21,7 +21,7 @@ from reflex.components.component import (
from reflex.config import environment, get_config from reflex.config import environment, get_config
from reflex.state import BaseState from reflex.state import BaseState
from reflex.style import SYSTEM_COLOR_MODE from reflex.style import SYSTEM_COLOR_MODE
from reflex.utils import console from reflex.utils import console, path_ops
from reflex.utils.exec import is_prod_mode from reflex.utils.exec import is_prod_mode
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
from reflex.utils.prerequisites import get_web_dir from reflex.utils.prerequisites import get_web_dir
@ -195,67 +195,49 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
else [] else []
) )
try: sass_compile = None
sass_compile = None for stylesheet in stylesheets:
while len(stylesheets): if not utils.is_valid_url(stylesheet):
stylesheet = stylesheets.pop(0) # check if stylesheet provided exists.
if not utils.is_valid_url(stylesheet): assets_app_path = Path.cwd() / constants.Dirs.APP_ASSETS
# check if stylesheet provided exists. stylesheet_full_path = assets_app_path / stylesheet.strip("/")
assets_app_path = Path.cwd() / constants.Dirs.APP_ASSETS
stylesheet_full_path = assets_app_path / stylesheet.strip("/")
if not stylesheet_full_path.exists(): if not stylesheet_full_path.exists():
raise FileNotFoundError( raise FileNotFoundError(
f"The stylesheet file {stylesheet_full_path} does not exist." f"The stylesheet file {stylesheet_full_path} does not exist."
) )
elif not stylesheet_full_path.is_file():
if stylesheet_full_path.is_dir():
# NOTE: this can create an infinite loop, for example:
# assets/
# | dir_a/
# | | dir_c/ (symlink to "assets/dir_a")
# | dir_b/
# so to avoid the infinite loop, we don't include symbolic links
stylesheets += [
str(p.relative_to(assets_app_path))
for p in stylesheet_full_path.iterdir()
if not (p.is_symlink() and p.is_dir())
]
continue
else:
raise FileNotFoundError(
f'The stylesheet path "{stylesheet_full_path}" is not a valid path.'
)
elif (
stylesheet_full_path.suffix[1:]
not in constants.Reflex.STYLESHEETS_SUPPORTED
):
raise FileNotFoundError(
f'The stylesheet file "{stylesheet_full_path}" is not a valid file.'
)
if ( if stylesheet_full_path.is_dir():
stylesheet_full_path.suffix[1:] # NOTE: this can create an infinite loop, for example:
in constants.Reflex.STYLESHEETS_SUPPORTED # assets/
): # | dir_a/
target = ( # | | dir_c/ (symlink to "assets/dir_a")
Path.cwd() # | dir_b/
/ constants.Dirs.WEB # so to avoid the infinite loop, we don't include symbolic links
/ constants.Dirs.STYLES stylesheets += [
/ RE_SASS_SCSS_EXT.sub(".css", str(stylesheet)).strip("/") str(p.relative_to(assets_app_path))
) for p in stylesheet_full_path.iterdir()
target.parent.mkdir(parents=True, exist_ok=True) if not (p.is_symlink() and p.is_dir())
]
continue
if stylesheet_full_path.suffix == ".css": if (
target.write_text( stylesheet_full_path.suffix[1:].lower()
data=stylesheet_full_path.read_text(), in constants.Reflex.STYLESHEETS_SUPPORTED
encoding="utf8", ):
) target = (
else: Path.cwd()
if sass_compile is None: / constants.Dirs.WEB
from sass import compile as sass_compile / constants.Dirs.STYLES
else: / RE_SASS_SCSS_EXT.sub(".css", str(stylesheet)).strip("/")
pass )
target.parent.mkdir(parents=True, exist_ok=True)
if stylesheet_full_path.suffix == ".css":
path_ops.cp(src=stylesheet_full_path, dest=target, overwrite=True)
else:
try:
from sass import compile as sass_compile
target.write_text( target.write_text(
data=sass_compile( data=sass_compile(
@ -264,15 +246,18 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
), ),
encoding="utf8", encoding="utf8",
) )
else: except ImportError:
pass sass_compile = None
else:
stylesheet = ( raise FileNotFoundError(
f"./{RE_SASS_SCSS_EXT.sub('.css', str(stylesheet)).strip('/')}" f'The stylesheet file "{stylesheet_full_path}" is not a valid file.'
) )
sheets.append(stylesheet) if stylesheet not in sheets else None stylesheet = f"./{str(stylesheet).replace(stylesheet_full_path.suffix, ".css").strip('/')}"
except ImportError:
sheets.append(stylesheet) if stylesheet not in sheets else None
if sass_compile is None:
console.error( console.error(
"""The `libsass` package is required to compile sass/scss stylesheet files. Run `pip install "libsass>=0.23.0"`.""" """The `libsass` package is required to compile sass/scss stylesheet files. Run `pip install "libsass>=0.23.0"`."""
) )

View File

@ -187,6 +187,19 @@ def test_compile_stylesheets_scss_sass(tmp_path: Path, mocker):
f"@import url('./preprocess/styles_b.css'); \n", f"@import url('./preprocess/styles_b.css'); \n",
) )
stylesheets = [
"/styles.css",
"/preprocess", # this is a folder containing "styles_a.sass" and "styles_b.scss"
]
assert compiler.compile_root_stylesheet(stylesheets) == (
str(Path(".web") / "styles" / "styles.css"),
f"@import url('./tailwind.css'); \n"
f"@import url('./styles.css'); \n"
f"@import url('./preprocess/styles_b.css'); \n"
f"@import url('./preprocess/styles_a.css'); \n",
)
assert (project / ".web" / "styles" / "styles.css").read_text() == ( assert (project / ".web" / "styles" / "styles.css").read_text() == (
assets_dir / "styles.css" assets_dir / "styles.css"
).read_text() ).read_text()