Files
MeshTerm/tests/test_spdx.py
T
Jean-Pierre MartineauandClaude Opus 5.5 11b5274b31 Docstrings and comments of the tests are in ASD-STE100
Each test docstring states the behaviour that the test proves, in the
simple present. No assertion message, test id, or other string literal
changed. Four statements now agree with the code: the Trace highlight
stays on the last row, a menu count, and two others.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 21:36:50 -04:00

48 lines
2.1 KiB
Python

# SPDX-License-Identifier: Apache-2.0
"""Make sure that all Python files have an SPDX licence identifier.
Each Python source file in the MeshTerm project must declare its licence with a
SPDX-License-Identifier comment on line 1 (or on line 2 if the file starts with a shebang).
This test examines the entire code base and asserts that the identifier is there. If
someone copies a file out of the repository, the file has no licence marking without this
identifier. Thus this gate makes sure that no file has no marking.
"""
from pathlib import Path
def test_spdx_headers():
"""Each Python file must have an SPDX-License-Identifier header."""
repo_root = Path(__file__).parent.parent
python_files = []
# Collect all the Python files from the necessary directories
for directory in ["meshterm", "tests", "packaging", "scripts/picocalc-lyra/xiao-radio"]:
dir_path = repo_root / directory
if dir_path.exists():
if directory == "packaging":
# For packaging, include the .py files and the .spec files
python_files.extend(dir_path.glob("*.py"))
python_files.extend(dir_path.glob("*.spec"))
else:
python_files.extend(dir_path.rglob("*.py"))
# Also examine the script scripts/uconsole/meshterm-spi-bridge, which has no extension
spi_bridge = repo_root / "scripts" / "uconsole" / "meshterm-spi-bridge"
if spi_bridge.exists():
python_files.append(spi_bridge)
missing_spdx = []
for filepath in sorted(python_files):
# A file that MeshTerm cannot read as UTF-8 is a finding. The test must not skip it.
# Each source file here is UTF-8, and a skip with no message lets a file with no
# marking pass.
head = filepath.read_text(encoding="utf-8").split("\n", 2)[:2]
if not any("SPDX-License-Identifier:" in line for line in head):
missing_spdx.append(str(filepath.relative_to(repo_root)))
assert not missing_spdx, (
f"Found {len(missing_spdx)} Python file(s) without SPDX-License-Identifier:\n"
+ "\n".join(f" {f}" for f in missing_spdx)
)