1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-19 16:25:50 +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 uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: .temp/components_graph.json 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 - name: Determine which tests to run
id: determine id: determine
env: env:
@@ -226,7 +226,7 @@ jobs:
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: .temp/components_graph.json path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/__init__.py') }} key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
integration-tests: integration-tests:
name: Run integration tests name: Run integration tests

View File

@@ -759,7 +759,7 @@ def resolve_auto_load(
@cache @cache
def get_components_graph_cache_key() -> str: 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 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 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 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> # Format: <mode> <sha1> <stage> <path>
# This is fast and works consistently across CI and local dev # 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( result = subprocess.run(
cmd, capture_output=True, text=True, check=True, cwd=root_path, close_fds=False 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) # 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 = hashlib.sha256()
hasher.update(result.stdout.encode()) hasher.update(result.stdout.encode())

View File

@@ -1109,10 +1109,18 @@ def test_get_component_from_path(
@pytest.fixture @pytest.fixture
def mock_git_output() -> str: 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 ( return (
"100644 abc123... 0 esphome/components/wifi/__init__.py\n" "100644 abc123... 0 esphome/components/wifi/__init__.py\n"
"100644 def456... 0 esphome/components/api/__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: 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 = 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 = 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 mock_subprocess_run.return_value = mock_result1
key1 = helpers.get_components_graph_cache_key() key1 = helpers.get_components_graph_cache_key()
@@ -1197,7 +1215,7 @@ def test_cache_key_uses_git_ls_files(
"git", "git",
"ls-files", "ls-files",
"-s", "-s",
"esphome/components/**/__init__.py", "esphome/components/**/*.py",
] ]
assert call_args[1]["capture_output"] is True assert call_args[1]["capture_output"] is True
assert call_args[1]["text"] is True assert call_args[1]["text"] is True