diff --git a/src/infra_controller/discovery.py b/src/infra_controller/discovery.py index 9958c2d..7575d16 100644 --- a/src/infra_controller/discovery.py +++ b/src/infra_controller/discovery.py @@ -139,6 +139,8 @@ class DiscoveryManager: for link_file in list(watch_path.glob("*.yml")) + list(watch_path.glob("*.yaml")): try: + if (watch_path / f"{link_file.stem}.toml").exists(): + continue if link_file.stem in apps: continue @@ -166,6 +168,8 @@ class DiscoveryManager: if not base_path.exists(): continue + toml_dirs: set[Path] = set() + for infra_file in base_path.rglob(".infra.toml"): if self._should_exclude(infra_file): continue @@ -180,13 +184,19 @@ class DiscoveryManager: last_seen=datetime.now(), discovery_method="scan", ) + toml_dirs.add(infra_file.parent) logger.info("Discovered app via scan: %s", md.project) except Exception as e: logger.error("Error reading %s: %s", infra_file, e) - for infra_file in base_path.rglob(".infra.yml"): + for infra_file in list(base_path.rglob(".infra.yml")) + list(base_path.rglob(".infra.yaml")): if self._should_exclude(infra_file): continue + if infra_file.parent in toml_dirs: + continue + if not self._is_active_project(infra_file.parent): + continue + try: md = InfraMetadata.from_file(infra_file) except Exception as e: @@ -195,8 +205,6 @@ class DiscoveryManager: if md.project in apps: continue - if not self._is_active_project(infra_file.parent): - continue apps[md.project] = AppRegistration( name=md.project, diff --git a/tests/test_infra_metadata.py b/tests/test_infra_metadata.py index 03103c9..9f9caf7 100644 --- a/tests/test_infra_metadata.py +++ b/tests/test_infra_metadata.py @@ -4,7 +4,9 @@ from pathlib import Path import pytest +from infra_controller.config import DiscoveryConfig from infra_controller.discovery import InfraMetadata +from infra_controller.discovery import DiscoveryManager def _write(path: Path, content: str) -> Path: @@ -112,3 +114,35 @@ requires: with pytest.raises(ValueError, match=r"requires\.services"): InfraMetadata.from_file(p) + + +def test_discover_scan_prefers_toml_over_yaml_in_same_dir(tmp_path: Path, monkeypatch) -> None: + base = tmp_path / "apps" + proj = base / "proj" + (proj / ".git").mkdir(parents=True) + (proj / ".git" / "HEAD").write_text("ref: refs/heads/main\n", encoding="utf-8") + + _write( + proj / ".infra.toml", + """ +project = "proj" + +[requires] +services = ["svc_toml"] +""".lstrip(), + ) + _write( + proj / ".infra.yml", + """ +project: proj +requires: + services: svc_yaml +""".lstrip(), + ) + + cfg = DiscoveryConfig(scan_enabled=True, scan_paths=[base], file_based_enabled=False) + mgr = DiscoveryManager(cfg) + + apps = mgr.discover_all() + assert set(apps.keys()) == {"proj"} + assert apps["proj"].metadata.requires["services"] == ["svc_toml"]