From c90964ea4c487953702e54a597c376f8e7880d75 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Thu, 18 May 2023 17:06:42 -0400 Subject: [PATCH] build: import XModule source SCSS directly rather than copying The `xmodule_assets` command copies SCSS source files from xmodule/css to common/static/xmodule/scss, renaming them to `{MD5_HASH}.scss` in order to "remove duplicates". The copied files are then included into the generated SCSS entrypoint files (eg AnnotatableBlockStudio.scss). The "de-deplication" is completely unnecessary: there are only a couple dozen SCSS files, and none of them are duplicates. This copying process is confusing, it complicates our build process, and it makes our SCSS harder to understand. So, in the generated SCSS entrypoint files, we stop importing the *copied* SCSS sources, and just import the *original* SCSS sources instead. For example, common/static/xmodule/descriptors/scss/AboutBlockStudio.scss is changed from: .xmodule_edit.xmodule_AboutBlock { @import "9bdcda00f046f78be79aca7791e1d4fb.scss"; @import "a10fc3e0fd6aca63426a89e75fe69c31.scss"; } to: .xmodule_edit.xmodule_AboutBlock { @import "editor/edit.scss"; @import "html/edit.scss"; } In order to make the `@import` lines work, we add xmodule/css to the list of lookup dirs for XModule SCSS compilation. We also remove the copying logic from `xmodule_assets`, as it is no longer needed. Part of: https://github.com/openedx/edx-platform/issues/32292 --- pavelib/assets.py | 10 ++++++++-- xmodule/static_content.py | 21 ++++++--------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/pavelib/assets.py b/pavelib/assets.py index 991fb7f914b1..19bb98ea071e 100644 --- a/pavelib/assets.py +++ b/pavelib/assets.py @@ -172,6 +172,7 @@ def get_theme_sass_dirs(system, theme_dir): certs_css_dir = theme_dir / system / "static" / "certificates" / "css" xmodule_sass_folder = "modules" if system == 'lms' else "descriptors" xmodule_sass_dir = path("common") / "static" / "xmodule" / xmodule_sass_folder / "scss" + xmodule_lookup_dir = path("xmodule") / "css" dependencies = SASS_LOOKUP_DEPENDENCIES.get(system, []) if sass_dir.isdir(): @@ -202,7 +203,9 @@ def get_theme_sass_dirs(system, theme_dir): dirs.append({ "sass_source_dir": xmodule_sass_dir, "css_destination_dir": path("common") / "static" / "css" / "xmodule", - "lookup_paths": dependencies + [ + "lookup_paths": [ + xmodule_lookup_dir, + *dependencies, sass_dir / "partials", system_sass_dir / "partials", system_sass_dir, @@ -237,6 +240,7 @@ def get_system_sass_dirs(system): css_dir = path(system) / "static" / "css" xmodule_sass_folder = "modules" if system == 'lms' else "descriptors" xmodule_sass_dir = path("common") / "static" / "xmodule" / xmodule_sass_folder / "scss" + xmodule_lookup_dir = path("xmodule") / "css" dependencies = SASS_LOOKUP_DEPENDENCIES.get(system, []) dirs.append({ @@ -251,7 +255,9 @@ def get_system_sass_dirs(system): dirs.append({ "sass_source_dir": xmodule_sass_dir, "css_destination_dir": path("common") / "static" / "css" / "xmodule", - "lookup_paths": dependencies + [ + "lookup_paths": [ + xmodule_lookup_dir, + *dependencies, sass_dir / "partials", sass_dir, ], diff --git a/xmodule/static_content.py b/xmodule/static_content.py index a89ab1bf3b31..6730dcb7a0ea 100755 --- a/xmodule/static_content.py +++ b/xmodule/static_content.py @@ -126,29 +126,20 @@ def _write_styles(selector, output_root, classes, css_attribute, suffix): into `output_root` as individual files """ contents = {} + xmodule_scss_path = resource_filename(__name__, "") + "/css/" for class_ in classes: class_css = getattr(class_, css_attribute)() - fragment_paths = class_css.get('scss', []) - if not fragment_paths: - continue - fragment_names = [] - for fragment_path in fragment_paths: - with open(fragment_path, 'rb') as fragment_file: - fragment = fragment_file.read() - fragment_name = "{hash}.{type}".format( - hash=hashlib.md5(fragment).hexdigest(), - type='scss') - # Prepend _ so that sass just includes the files into a single file - filename = '_' + fragment_name - contents[filename] = fragment - fragment_names.append(fragment_name) + rel_fragment_paths = [] + for fragment_path in class_css.get('scss', []): + rel_fragment_path = fragment_path.split(xmodule_scss_path)[1] + rel_fragment_paths.append(rel_fragment_path) module_styles_lines = [] module_styles_lines.append("""{selector}.xmodule_{class_.__name__} {{""".format( class_=class_, selector=selector )) - module_styles_lines.extend(f' @import "{name}";' for name in fragment_names) + module_styles_lines.extend(f' @import "{path}";' for path in rel_fragment_paths) module_styles_lines.append('}') contents[f"{class_.__name__}{suffix}.scss"] = '\n'.join(module_styles_lines)