1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-19 08:15:49 +00:00

handle AUTO_LOAD in sensor.py

This commit is contained in:
J. Nick Koston
2025-11-02 19:33:41 -06:00
parent 4d4cd6c86a
commit 4e47639ee6
3 changed files with 31 additions and 11 deletions

View File

@@ -196,7 +196,7 @@ jobs:
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/__init__.py') }}
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
- name: Determine which tests to run
id: determine
env:
@@ -226,7 +226,7 @@ jobs:
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/__init__.py') }}
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
integration-tests:
name: Run integration tests

View File

@@ -759,7 +759,7 @@ def resolve_auto_load(
@cache
def get_components_graph_cache_key() -> str:
"""Generate cache key based on all component __init__.py file hashes.
"""Generate cache key based on all component Python file hashes.
Uses git ls-files with sha1 hashes to generate a stable cache key that works
across different machines and CI runs. This is faster and more reliable than
@@ -769,16 +769,18 @@ def get_components_graph_cache_key() -> str:
SHA256 hex string uniquely identifying the current component state
"""
# Use git ls-files -s to get sha1 hashes of all component __init__.py files
# Use git ls-files -s to get sha1 hashes of all component Python files
# Format: <mode> <sha1> <stage> <path>
# This is fast and works consistently across CI and local dev
cmd = ["git", "ls-files", "-s", "esphome/components/**/__init__.py"]
# We hash all .py files because AUTO_LOAD, DEPENDENCIES, etc. can be defined
# in any Python file, not just __init__.py
cmd = ["git", "ls-files", "-s", "esphome/components/**/*.py"]
result = subprocess.run(
cmd, capture_output=True, text=True, check=True, cwd=root_path, close_fds=False
)
# Hash the git output (includes file paths and their sha1 hashes)
# This changes only when component __init__.py files actually change
# This changes only when component Python files actually change
hasher = hashlib.sha256()
hasher.update(result.stdout.encode())

View File

@@ -1109,10 +1109,18 @@ def test_get_component_from_path(
@pytest.fixture
def mock_git_output() -> str:
"""Fixture for mock git ls-files output."""
"""Fixture for mock git ls-files output with realistic component files.
Includes examples of AUTO_LOAD in sensor.py and binary_sensor.py files,
which is why we need to hash all .py files, not just __init__.py.
"""
return (
"100644 abc123... 0 esphome/components/wifi/__init__.py\n"
"100644 def456... 0 esphome/components/api/__init__.py\n"
"100644 ghi789... 0 esphome/components/xiaomi_lywsd03mmc/__init__.py\n"
"100644 jkl012... 0 esphome/components/xiaomi_lywsd03mmc/sensor.py\n"
"100644 mno345... 0 esphome/components/xiaomi_cgpr1/__init__.py\n"
"100644 pqr678... 0 esphome/components/xiaomi_cgpr1/binary_sensor.py\n"
)
@@ -1163,12 +1171,22 @@ def test_cache_key_consistent_for_same_files(
def test_cache_key_different_for_changed_files(mock_subprocess_run: Mock) -> None:
"""Test that different git output produces different cache key."""
"""Test that different git output produces different cache key.
This test demonstrates that changes to any .py file (not just __init__.py)
will invalidate the cache, which is important because AUTO_LOAD can be
defined in sensor.py, binary_sensor.py, etc.
"""
mock_result1 = Mock()
mock_result1.stdout = "100644 abc123... 0 esphome/components/wifi/__init__.py\n"
mock_result1.stdout = (
"100644 abc123... 0 esphome/components/xiaomi_lywsd03mmc/sensor.py\n"
)
mock_result2 = Mock()
mock_result2.stdout = "100644 xyz789... 0 esphome/components/wifi/__init__.py\n"
# Same file, different hash - simulates a change to AUTO_LOAD
mock_result2.stdout = (
"100644 xyz789... 0 esphome/components/xiaomi_lywsd03mmc/sensor.py\n"
)
mock_subprocess_run.return_value = mock_result1
key1 = helpers.get_components_graph_cache_key()
@@ -1197,7 +1215,7 @@ def test_cache_key_uses_git_ls_files(
"git",
"ls-files",
"-s",
"esphome/components/**/__init__.py",
"esphome/components/**/*.py",
]
assert call_args[1]["capture_output"] is True
assert call_args[1]["text"] is True