From 25194880f71f964fdcb825362e22a7c52898bc60 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Thu, 18 May 2023 16:47:55 -0400 Subject: [PATCH] build: remove prefixes from XModule resource copies The `xmodule_assets` command copies SCSS files from xmodule/css to common/static/xmodule/{modules|descriptors}/scss. It renames the files to the format: _{INDEX}-{HASH}.scss where an XModule's first SCSS resource will have INDEX==0, the next will have INDEX==1, ...and that's it because no XModule has more than two SCSS resources. The output looks like this: common/static/xmodule/descriptors/scss: _000-808fcbb4c5109c5156ae3c0c9729c8be.scss _000-9bdcda00f046f78be79aca7791e1d4fb.scss _000-d41921b4c5d45188759ef3d04fd9a78a.scss _001-901b985e5ea2dea2a89cce747cf4307d.scss _001-a10fc3e0fd6aca63426a89e75fe69c31.scss common/static/xmodule/modules/scss: _000-1ad2f05db822d3176affd203d70319c0.scss _000-1dc4276d3849a14ea538286e97740c14.scss _000-29baf1ef1af89b1051362f51124abd01.scss _000-6bf8c2340b013d835b25df13e03b8d33.scss _000-8b6bb50b058d34efefa40107307a32c6.scss _000-958d6ef6baa09be94bccaf488861c8e5.scss _000-a3c2cdf2141d24a76be9afa56f237c29.scss _000-b80300e1a5f290f6a850e35874068427.scss _001-482ebc752ab6e41946651ceb0f3e7f55.scss These indexes serve no purpose. Reading the comments and git-blame in xmodule/static_content.py, one can glean that the indexes might have been intended to enforce dependency relationships between the assets, but this is unnecessary, because the ordering of the copied SCSS is *already preserved* by the order which they're included into the `{BLOCK_NAME}{Studio|Preivew}.{HASH}.scss` SCSS entrypoint files. I have to assume that this is an unnecessary relic from the time when the XModule system was more heavily utilized, rather than just a legacy corner of the XBlock framework as it is today. So, we remove the indexes, which lets us simplify the logic of xmodule/static_content.py. This is a minor refactoring, but it'll make it easier for the next steps on our way to deleting xmodule/static_content.py entirely. The new output looks like this: common/static/xmodule/descriptors/scss: _808fcbb4c5109c5156ae3c0c9729c8be.scss _901b985e5ea2dea2a89cce747cf4307d.scss _9bdcda00f046f78be79aca7791e1d4fb.scss _a10fc3e0fd6aca63426a89e75fe69c31.scss _d41921b4c5d45188759ef3d04fd9a78a.scss common/static/xmodule/modules/scss: _1ad2f05db822d3176affd203d70319c0.scss _1dc4276d3849a14ea538286e97740c14.scss _29baf1ef1af89b1051362f51124abd01.scss _482ebc752ab6e41946651ceb0f3e7f55.scss _6bf8c2340b013d835b25df13e03b8d33.scss _8b6bb50b058d34efefa40107307a32c6.scss _958d6ef6baa09be94bccaf488861c8e5.scss _a3c2cdf2141d24a76be9afa56f237c29.scss _b80300e1a5f290f6a850e35874068427.scss Part of: https://github.com/openedx/edx-platform/issues/31624 --- xmodule/static_content.py | 42 ++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/xmodule/static_content.py b/xmodule/static_content.py index 58ffcb2de12b..57eb8ce23487 100755 --- a/xmodule/static_content.py +++ b/xmodule/static_content.py @@ -123,44 +123,36 @@ def _ensure_dir(directory): def _write_styles(selector, output_root, classes, css_attribute, suffix): """ Write the css fragments from all XModules in `classes` - into `output_root` as individual files, hashed by the contents to remove - duplicates + into `output_root` as individual files """ contents = {} - css_fragments = defaultdict(set) for class_ in classes: class_css = getattr(class_, css_attribute)() - for filetype in ('sass', 'scss', 'css'): - for idx, fragment_path in enumerate(class_css.get(filetype, [])): - with open(fragment_path, 'rb') as fragment_file: - fragment = fragment_file.read() - css_fragments[idx, filetype, fragment].add(class_.__name__) - css_imports = defaultdict(set) - for (idx, filetype, fragment), classes in sorted(css_fragments.items()): # lint-amnesty, pylint: disable=redefined-argument-from-local - fragment_name = "{idx:0=3d}-{hash}.{type}".format( - idx=idx, - hash=hashlib.md5(fragment).hexdigest(), - type=filetype) - # Prepend _ so that sass just includes the files into a single file - filename = '_' + fragment_name - contents[filename] = fragment + 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) - for class_ in classes: - css_imports[class_].add(fragment_name) - - for class_, fragment_names in sorted(css_imports.items()): module_styles_lines = [] - - fragment_names = sorted(fragment_names) - module_styles_lines.append("""{selector}.xmodule_{class_} {{""".format( + 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.append('}') file_hash = hashlib.md5("".join(fragment_names).encode('ascii')).hexdigest() - contents[f"{class_}{suffix}.{file_hash}.scss"] = '\n'.join(module_styles_lines) + contents[f"{class_.__name__}{suffix}.{file_hash}.scss"] = '\n'.join(module_styles_lines) _write_files(output_root, contents)