scripts: compliance: add sphinx-lint linter
ReStructuredText can sometimes be tricky to get right, especially for
folks that might be more familiar with Markdown.
This adds a Sphinx/RST linter to the compliance check script to help
catch common issues that can easily go unnoticed and cause rendering
issues.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml
index 09168ab..39815d8 100644
--- a/.github/workflows/compliance.yml
+++ b/.github/workflows/compliance.yml
@@ -38,7 +38,7 @@
run: |
pip3 install setuptools
pip3 install wheel
- pip3 install python-magic lxml junitparser gitlint pylint pykwalify yamllint clang-format unidiff
+ pip3 install python-magic lxml junitparser gitlint pylint pykwalify yamllint clang-format unidiff sphinx-lint
pip3 install west
- name: west setup
diff --git a/.gitignore b/.gitignore
index f590a8a..266b95a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,4 +91,5 @@
ModulesMaintainers.txt
Nits.txt
Pylint.txt
+SphinxLint.txt
YAMLLint.txt
diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py
index 54964d4..58a2e6d 100755
--- a/scripts/ci/check_compliance.py
+++ b/scripts/ci/check_compliance.py
@@ -1495,6 +1495,49 @@
p.line, col=p.column, desc=p.desc)
+class SphinxLint(ComplianceTest):
+ """
+ SphinxLint
+ """
+
+ name = "SphinxLint"
+ doc = "Check Sphinx/reStructuredText files with sphinx-lint."
+ path_hint = "<git-top>"
+
+ # Checkers added/removed to sphinx-lint's default set
+ DISABLE_CHECKERS = ["horizontal-tab", "missing-space-before-default-role"]
+ ENABLE_CHECKERS = ["default-role"]
+
+ def run(self):
+ for file in get_files():
+ if not file.endswith(".rst"):
+ continue
+
+ try:
+ # sphinx-lint does not expose a public API so interaction is done via CLI
+ subprocess.run(
+ f"sphinx-lint -d {','.join(self.DISABLE_CHECKERS)} -e {','.join(self.ENABLE_CHECKERS)} {file}",
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ shell=True,
+ cwd=GIT_TOP,
+ )
+
+ except subprocess.CalledProcessError as ex:
+ for line in ex.output.decode("utf-8").splitlines():
+ match = re.match(r"^(.*):(\d+): (.*)$", line)
+
+ if match:
+ self.fmtd_failure(
+ "error",
+ "SphinxLint",
+ match.group(1),
+ int(match.group(2)),
+ desc=match.group(3),
+ )
+
+
class KeepSorted(ComplianceTest):
"""
Check for blocks of code or config that should be kept sorted.
diff --git a/scripts/requirements-compliance.txt b/scripts/requirements-compliance.txt
index 0d5fe21..a439698 100644
--- a/scripts/requirements-compliance.txt
+++ b/scripts/requirements-compliance.txt
@@ -9,3 +9,4 @@
pylint>=3
unidiff
yamllint
+sphinx-lint