diff --git a/git_hg_sync/config.py b/git_hg_sync/config.py index abe7bea..4fc6141 100644 --- a/git_hg_sync/config.py +++ b/git_hg_sync/config.py @@ -1,4 +1,5 @@ import pathlib +from collections import Counter from typing import Annotated, Self, override import tomllib @@ -81,6 +82,18 @@ def verify_all_mappings_reference_tracked_repositories( ) return self + @model_validator(mode="after") + def verify_unique_tracked_repositories_name(self) -> Self: + tracked_names = Counter( + tracked_repo.name for tracked_repo in self.tracked_repositories + ) + non_unique = [name for name in tracked_names if tracked_names[name] > 1] + if non_unique: + raise ValueError( + f"Found non-unique names in tracked_repositories: {', '.join(non_unique)}" + ) + return self + @override @classmethod def settings_customise_sources( diff --git a/tests/test_config.py b/tests/test_config.py index 5a1c6c4..18f0af0 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -55,6 +55,18 @@ def test_load_config_env_override(monkeypatch: pytest.MonkeyPatch) -> None: ) +def test_unique_tracked_repository_name() -> None: + config = tomllib.loads((HERE / "data" / "config.toml").read_text()) + + # Ensure this doesn't fail without duplicates. + _ = Config(**config) + + config["tracked_repositories"].append(config["tracked_repositories"][0]) + + with pytest.raises(ValueError, match="non-unique names"): + _ = Config(**config) + + @pytest.mark.parametrize( "source_url,source_branch,expected_urls,expected_branches", [ diff --git a/tests/test_config_files.py b/tests/test_config_files.py index cf03aea..318f340 100644 --- a/tests/test_config_files.py +++ b/tests/test_config_files.py @@ -24,7 +24,7 @@ def test_config_files(monkeypatch: pytest.MonkeyPatch, config_file: Path) -> Non try: config = Config.from_file(config_file) except ValidationError as exc: - raise AssertionError(f"Syntax error in {config_file}") from exc + raise AssertionError(f"Syntax error in {config_file}: {exc}") from exc # We just do a shallow verification. What we really care is that the file could be # loaded correctly.