mirror of
https://github.com/esphome/esphome.git
synced 2025-10-12 23:03:46 +01:00
fix
This commit is contained in:
@@ -51,6 +51,32 @@ VALID_BUS_CONFIGS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def uses_local_file_references(component_dir: Path) -> bool:
|
||||||
|
"""Check if a component uses local file references via $component_dir.
|
||||||
|
|
||||||
|
Components that reference local files cannot be grouped because each needs
|
||||||
|
a unique component_dir path pointing to their specific directory.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component_dir: Path to the component's test directory
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if the component uses $component_dir for local file references
|
||||||
|
"""
|
||||||
|
common_yaml = component_dir / "common.yaml"
|
||||||
|
if not common_yaml.exists():
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
content = common_yaml.read_text()
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Pattern to match $component_dir or ${component_dir} references
|
||||||
|
# These indicate local file usage that prevents grouping
|
||||||
|
return bool(re.search(r"\$\{?component_dir\}?", content))
|
||||||
|
|
||||||
|
|
||||||
def extract_common_buses(yaml_file: Path) -> set[str]:
|
def extract_common_buses(yaml_file: Path) -> set[str]:
|
||||||
"""Extract which common bus configs are included in a YAML test file.
|
"""Extract which common bus configs are included in a YAML test file.
|
||||||
|
|
||||||
@@ -110,23 +136,28 @@ def analyze_component(component_dir: Path) -> dict[str, list[str]]:
|
|||||||
return platform_buses
|
return platform_buses
|
||||||
|
|
||||||
|
|
||||||
def analyze_all_components(tests_dir: Path = None) -> dict[str, dict[str, list[str]]]:
|
def analyze_all_components(
|
||||||
|
tests_dir: Path = None,
|
||||||
|
) -> tuple[dict[str, dict[str, list[str]]], set[str]]:
|
||||||
"""Analyze all component test directories.
|
"""Analyze all component test directories.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tests_dir: Path to tests/components directory (defaults to auto-detect)
|
tests_dir: Path to tests/components directory (defaults to auto-detect)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Dictionary mapping component name to platform->buses mapping
|
Tuple of:
|
||||||
|
- Dictionary mapping component name to platform->buses mapping
|
||||||
|
- Set of component names that use local files (cannot be grouped)
|
||||||
"""
|
"""
|
||||||
if tests_dir is None:
|
if tests_dir is None:
|
||||||
tests_dir = Path("tests/components")
|
tests_dir = Path("tests/components")
|
||||||
|
|
||||||
if not tests_dir.exists():
|
if not tests_dir.exists():
|
||||||
print(f"Error: {tests_dir} does not exist", file=sys.stderr)
|
print(f"Error: {tests_dir} does not exist", file=sys.stderr)
|
||||||
return {}
|
return {}, set()
|
||||||
|
|
||||||
components = {}
|
components = {}
|
||||||
|
non_groupable = set()
|
||||||
|
|
||||||
for component_dir in sorted(tests_dir.iterdir()):
|
for component_dir in sorted(tests_dir.iterdir()):
|
||||||
if not component_dir.is_dir():
|
if not component_dir.is_dir():
|
||||||
@@ -138,7 +169,11 @@ def analyze_all_components(tests_dir: Path = None) -> dict[str, dict[str, list[s
|
|||||||
if platform_buses:
|
if platform_buses:
|
||||||
components[component_name] = platform_buses
|
components[component_name] = platform_buses
|
||||||
|
|
||||||
return components
|
# Check if component uses local file references
|
||||||
|
if uses_local_file_references(component_dir):
|
||||||
|
non_groupable.add(component_name)
|
||||||
|
|
||||||
|
return components, non_groupable
|
||||||
|
|
||||||
|
|
||||||
def create_grouping_signature(
|
def create_grouping_signature(
|
||||||
@@ -226,14 +261,17 @@ def main() -> None:
|
|||||||
if args.components:
|
if args.components:
|
||||||
# Analyze only specified components
|
# Analyze only specified components
|
||||||
components = {}
|
components = {}
|
||||||
|
non_groupable = set()
|
||||||
for comp in args.components:
|
for comp in args.components:
|
||||||
comp_dir = tests_dir / comp
|
comp_dir = tests_dir / comp
|
||||||
platform_buses = analyze_component(comp_dir)
|
platform_buses = analyze_component(comp_dir)
|
||||||
if platform_buses:
|
if platform_buses:
|
||||||
components[comp] = platform_buses
|
components[comp] = platform_buses
|
||||||
|
if uses_local_file_references(comp_dir):
|
||||||
|
non_groupable.add(comp)
|
||||||
else:
|
else:
|
||||||
# Analyze all components
|
# Analyze all components
|
||||||
components = analyze_all_components(tests_dir)
|
components, non_groupable = analyze_all_components(tests_dir)
|
||||||
|
|
||||||
# Output results
|
# Output results
|
||||||
if args.group and args.platform:
|
if args.group and args.platform:
|
||||||
@@ -256,12 +294,19 @@ def main() -> None:
|
|||||||
else:
|
else:
|
||||||
# Human-readable output
|
# Human-readable output
|
||||||
for component, platform_buses in sorted(components.items()):
|
for component, platform_buses in sorted(components.items()):
|
||||||
print(f"{component}:")
|
non_groupable_marker = (
|
||||||
|
" [NON-GROUPABLE]" if component in non_groupable else ""
|
||||||
|
)
|
||||||
|
print(f"{component}{non_groupable_marker}:")
|
||||||
for platform, buses in sorted(platform_buses.items()):
|
for platform, buses in sorted(platform_buses.items()):
|
||||||
bus_str = ", ".join(buses)
|
bus_str = ", ".join(buses)
|
||||||
print(f" {platform}: {bus_str}")
|
print(f" {platform}: {bus_str}")
|
||||||
print()
|
print()
|
||||||
print(f"Total components analyzed: {len(components)}")
|
print(f"Total components analyzed: {len(components)}")
|
||||||
|
if non_groupable:
|
||||||
|
print(f"Non-groupable components (use local files): {len(non_groupable)}")
|
||||||
|
for comp in sorted(non_groupable):
|
||||||
|
print(f" - {comp}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -331,13 +331,17 @@ def test_components(
|
|||||||
print("\n" + "=" * 80)
|
print("\n" + "=" * 80)
|
||||||
print("Analyzing components for intelligent grouping...")
|
print("Analyzing components for intelligent grouping...")
|
||||||
print("=" * 80)
|
print("=" * 80)
|
||||||
component_buses = analyze_all_components(tests_dir)
|
component_buses, non_groupable = analyze_all_components(tests_dir)
|
||||||
|
|
||||||
# Group by (platform, bus_signature)
|
# Group by (platform, bus_signature)
|
||||||
for component, platforms in component_buses.items():
|
for component, platforms in component_buses.items():
|
||||||
if component not in all_tests:
|
if component not in all_tests:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Skip components that use local file references
|
||||||
|
if component in non_groupable:
|
||||||
|
continue
|
||||||
|
|
||||||
for platform, buses in platforms.items():
|
for platform, buses in platforms.items():
|
||||||
# Skip if platform doesn't match filter
|
# Skip if platform doesn't match filter
|
||||||
if platform_filter and not platform.startswith(platform_filter):
|
if platform_filter and not platform.startswith(platform_filter):
|
||||||
@@ -352,6 +356,18 @@ def test_components(
|
|||||||
print("\nGrouping Plan:")
|
print("\nGrouping Plan:")
|
||||||
print("-" * 80)
|
print("-" * 80)
|
||||||
|
|
||||||
|
# Show excluded components
|
||||||
|
if non_groupable:
|
||||||
|
excluded_in_tests = [c for c in non_groupable if c in all_tests]
|
||||||
|
if excluded_in_tests:
|
||||||
|
print(
|
||||||
|
f"\n⚠ {len(excluded_in_tests)} components excluded from grouping (use local file references):"
|
||||||
|
)
|
||||||
|
for comp in sorted(excluded_in_tests[:5]):
|
||||||
|
print(f" - {comp}")
|
||||||
|
if len(excluded_in_tests) > 5:
|
||||||
|
print(f" ... and {len(excluded_in_tests) - 5} more")
|
||||||
|
|
||||||
groups_to_test = []
|
groups_to_test = []
|
||||||
individual_tests = []
|
individual_tests = []
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user