build: remove prefixes from XModule resource copies (#32287)
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
...
_001-a10fc3e0fd6aca63426a89e75fe69c31.scss
common/static/xmodule/modules/scss:
_000-1ad2f05db822d3176affd203d70319c0.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
...
_d41921b4c5d45188759ef3d04fd9a78a.scss
common/static/xmodule/modules/scss:
_1ad2f05db822d3176affd203d70319c0.scss
...
_b80300e1a5f290f6a850e35874068427.scss
Part of: https://github.com/openedx/edx-platform/issues/32292
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user