From 63b8a219e606bf3b2d7b6321b057633d4926b0db Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 14 Jul 2025 20:26:39 -1000 Subject: [PATCH] Include entire platformio.ini in clang-tidy hash calculation (#9509) --- .clang-tidy.hash | 2 +- script/clang_tidy_hash.py | 27 ++------------ tests/script/test_clang_tidy_hash.py | 55 ++++++---------------------- 3 files changed, 17 insertions(+), 67 deletions(-) diff --git a/.clang-tidy.hash b/.clang-tidy.hash index d36ae1f164..18be8d78a9 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -a3cdfc378d28b53b416a1d5bf0ab9077ee18867f0d39436ea8013cf5a4ead87a +07f621354fe1350ba51953c80273cd44a04aa44f15cc30bd7b8fe2a641427b7a diff --git a/script/clang_tidy_hash.py b/script/clang_tidy_hash.py index 8cc135f5d0..19eb2a825e 100755 --- a/script/clang_tidy_hash.py +++ b/script/clang_tidy_hash.py @@ -62,26 +62,6 @@ def get_clang_tidy_version_from_requirements() -> str: return "clang-tidy version not found" -def extract_platformio_flags() -> str: - """Extract clang-tidy related flags from platformio.ini""" - flags: list[str] = [] - in_clangtidy_section = False - - platformio_path = Path(__file__).parent.parent / "platformio.ini" - lines = read_file_lines(platformio_path) - for line in lines: - line = line.strip() - if line.startswith("[flags:clangtidy]"): - in_clangtidy_section = True - continue - elif line.startswith("[") and in_clangtidy_section: - break - elif in_clangtidy_section and line and not line.startswith("#"): - flags.append(line) - - return "\n".join(sorted(flags)) - - def read_file_bytes(path: Path) -> bytes: """Read bytes from a file.""" with open(path, "rb") as f: @@ -101,9 +81,10 @@ def calculate_clang_tidy_hash() -> str: version = get_clang_tidy_version_from_requirements() hasher.update(version.encode()) - # Hash relevant platformio.ini sections - pio_flags = extract_platformio_flags() - hasher.update(pio_flags.encode()) + # Hash the entire platformio.ini file + platformio_path = Path(__file__).parent.parent / "platformio.ini" + platformio_content = read_file_bytes(platformio_path) + hasher.update(platformio_content) return hasher.hexdigest() diff --git a/tests/script/test_clang_tidy_hash.py b/tests/script/test_clang_tidy_hash.py index e4d4b40473..7b66a69adb 100644 --- a/tests/script/test_clang_tidy_hash.py +++ b/tests/script/test_clang_tidy_hash.py @@ -44,67 +44,36 @@ def test_get_clang_tidy_version_from_requirements( assert result == expected -@pytest.mark.parametrize( - ("platformio_content", "expected_flags"), - [ - ( - "[env:esp32]\n" - "platform = espressif32\n" - "\n" - "[flags:clangtidy]\n" - "build_flags = -Wall\n" - "extra_flags = -Wextra\n" - "\n" - "[env:esp8266]\n", - "build_flags = -Wall\nextra_flags = -Wextra", - ), - ( - "[flags:clangtidy]\n# Comment line\nbuild_flags = -O2\n\n[next_section]\n", - "build_flags = -O2", - ), - ( - "[flags:clangtidy]\nflag_c = -std=c99\nflag_b = -Wall\nflag_a = -O2\n", - "flag_a = -O2\nflag_b = -Wall\nflag_c = -std=c99", # Sorted - ), - ( - "[env:esp32]\nplatform = espressif32\n", # No clangtidy section - "", - ), - ], -) -def test_extract_platformio_flags(platformio_content: str, expected_flags: str) -> None: - """Test extracting clang-tidy flags from platformio.ini.""" - # Mock read_file_lines to return our test content - with patch("clang_tidy_hash.read_file_lines") as mock_read: - mock_read.return_value = platformio_content.splitlines(keepends=True) - - result = clang_tidy_hash.extract_platformio_flags() - - assert result == expected_flags - - def test_calculate_clang_tidy_hash() -> None: """Test calculating hash from all configuration sources.""" clang_tidy_content = b"Checks: '-*,readability-*'\n" requirements_version = "clang-tidy==18.1.5" - pio_flags = "build_flags = -Wall" + platformio_content = b"[env:esp32]\nplatform = espressif32\n" # Expected hash calculation expected_hasher = hashlib.sha256() expected_hasher.update(clang_tidy_content) expected_hasher.update(requirements_version.encode()) - expected_hasher.update(pio_flags.encode()) + expected_hasher.update(platformio_content) expected_hash = expected_hasher.hexdigest() # Mock the dependencies with ( - patch("clang_tidy_hash.read_file_bytes", return_value=clang_tidy_content), + patch("clang_tidy_hash.read_file_bytes") as mock_read_bytes, patch( "clang_tidy_hash.get_clang_tidy_version_from_requirements", return_value=requirements_version, ), - patch("clang_tidy_hash.extract_platformio_flags", return_value=pio_flags), ): + # Set up mock to return different content based on the file being read + def read_file_mock(path: Path) -> bytes: + if ".clang-tidy" in str(path): + return clang_tidy_content + elif "platformio.ini" in str(path): + return platformio_content + return b"" + + mock_read_bytes.side_effect = read_file_mock result = clang_tidy_hash.calculate_clang_tidy_hash() assert result == expected_hash