Files
edx-platform/scripts/eslint.py
Kyle McCormick 3e9158e9a8 build(eslint): Ignore Symlinks and Reduce Violation Limit (#36010)
Background: We have a large number of standing eslint violations in our
legacy frontends. Rather than fixing or amnesty-ing all of them, we've
opted to use a simple integer limit of violations. Exceeding this
limit causes the quality check to fail.

Before we moved eslint off of Paver [1], the limit was unreasonably
high (probably due to deprecations that removed violation-rich frontend
code). This was good, except for the fact that we essentially weren't
catching when new violations creeped into the JS code.

So, in [1], we lowered the limit down to the lowest possible value,
which we thought was 1285. However, we've found that this made the check
flaky-- turned out, we have been unintentionally double-counting various
violations due to the symlinks in edx-platform. Some of those symlinks'
existence is dependent on whether and how `npm ci` and `npm run build`
have been run. As a result, 1285 would pass in some contexts, and fail
in other contexts.

The fix is to simply add all the relevant edx-platform symlinks to
.eslintignore. This allows us to lower the violations limit to 734.

[1] https://github.com/openedx/edx-platform/pull/35159
2024-12-11 17:06:53 +00:00

74 lines
1.9 KiB
Python

""" # pylint: disable=django-not-configured
Check code quality using eslint.
"""
import re
import subprocess
import shlex
import sys
class BuildFailure(Exception):
pass
def fail_quality(message):
"""
Fail the specified quality check.
"""
raise BuildFailure(message)
def run_eslint():
"""
Runs eslint on static asset directories.
If limit option is passed, fails build if more violations than the limit are found.
"""
violations_limit = 734
command = [
"node",
"--max_old_space_size=4096",
"node_modules/.bin/eslint",
"--ext", ".js",
"--ext", ".jsx",
"--format=compact",
"lms",
"cms",
"common",
"openedx",
"xmodule",
]
print("Running command:", shlex.join(command))
result = subprocess.run(
command,
text=True,
check=False,
capture_output=True
)
print(result.stdout)
last_line = result.stdout.strip().splitlines()[-1] if result.stdout.strip().splitlines() else ""
regex = r'^\d+'
try:
num_violations = int(re.search(regex, last_line).group(0)) if last_line else 0
# Fail if number of violations is greater than the limit
if num_violations > violations_limit:
fail_quality(
"FAILURE: Too many eslint violations ({count}).\nThe limit is {violations_limit}.".format(count=num_violations, violations_limit=violations_limit))
else:
print(f"successfully run eslint with '{num_violations}' violations")
# An AttributeError will occur if the regex finds no matches.
except (AttributeError, ValueError):
fail_quality(f"FAILURE: Number of eslint violations could not be found in '{last_line}'")
if __name__ == "__main__":
try:
run_eslint()
except BuildFailure as e:
print(e)
sys.exit(1)