Skip to content

Commit

Permalink
build: remove prefixes from XModule resource copies
Browse files Browse the repository at this point in the history
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: openedx#31624
  • Loading branch information
kdmccormick committed Jun 2, 2023
1 parent f7a3faa commit 2519488
Showing 1 changed file with 17 additions and 25 deletions.
42 changes: 17 additions & 25 deletions xmodule/static_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 2519488

Please sign in to comment.