# pylint: disable=missing-function-docstring,invalid-name,global-statement,missing-module-docstring # Copyright 2025 The Helium Authors # You can use, redistribute, and/or modify this source code under # the terms of the GPL-3.0 license that can be found in the LICENSE file. from third_party import unidiff LICENSE_HEADER_IGNORES = ["html", "license", "readme"] patches_dir = None series = None def _read_text(path): with open(patches_dir / path, "r", encoding="utf-8") as f: return filter(str, f.read().splitlines()) def _read_patch(path): return unidiff.PatchSet('\n'.join(_read_text(path))) def _init(root): global patches_dir global series patches_dir = root / "patches" series = set(_read_text("series")) def a_all_patches_in_series_exist(): for patch in series: assert (patches_dir / patch).is_file(), \ f"{patch} is in series, but does not exist in the source tree" def a_all_patches_in_tree_are_in_series(): for patch in patches_dir.rglob('*'): if not patch.is_file() or patch == patches_dir / "series": continue assert str(patch.relative_to(patches_dir)) in series, \ f"{patch} exists in source tree, but is not included in the series" def b_all_patches_have_meaningful_contents(): for patch in series: assert any(l.startswith('+++ ') for l in _read_text(patch)), \ f"{patch} does not have any meaningful content" def b_all_patches_have_no_trailing_whitespace(): for patch in series: for i, line in enumerate(_read_text(patch)): if not line.startswith('+ '): continue assert not line.endswith(' '), \ f"{patch} contains trailing whitespace on line {i + 1}" def c_all_new_files_have_license_header(): for patch in series: if 'helium' not in patch: continue added_files = filter(lambda f: f.is_added_file, _read_patch(patch)) for file in added_files: if any(p in file.path.lower() for p in LICENSE_HEADER_IGNORES): continue assert any('terms of the GPL-3.0 license' in str(hunk) for hunk in file), \ f"File {file.path} was added in {patch}, but contains no Helium license header" def c_all_new_headers_have_correct_guard(): for patch in series: if 'helium' not in patch: continue added_files = filter(lambda f: f.is_added_file and f.path.endswith('.h'), _read_patch(patch)) for file in added_files: expected_macro_name = file.path.upper() \ .replace('.', '_') \ .replace('/', '_') + '_' assert len(file) == 1 expected = { "ifndef": f'#ifndef {expected_macro_name}', "define": f'#define {expected_macro_name}' } found = { "ifndef": None, "define": None, } for _line in file[0]: line = str(_line) if expected["ifndef"] in line: assert found["define"] is None assert found["ifndef"] is None found["ifndef"] = line elif expected["define"] in line: assert found["ifndef"] is not None assert found["define"] is None found["define"] = line for macro_type, value in found.items(): value_print = (value or '(none)').rstrip() assert value == f"+{expected[macro_type]}\n", \ f"Patch {patch} has unexpected {macro_type} in {file.path}:" \ f"{value_print}, expecting: {expected[macro_type]}" def d_no_whitespace_only_changes(): for patch in series: if 'helium' not in patch: continue for file in _read_patch(patch): for hunk in file: seen_nonws = False for line in hunk: line = str(line) if line.startswith('+') or line.startswith('-'): seen_nonws = seen_nonws or len(line.rstrip()) > 1 assert seen_nonws, \ f"Patch {patch} contains hunk consisting of "\ f"only whitespace characters in {file.path}: {hunk}"