diff --git a/graphify/rcfile.py b/graphify/rcfile.py index 110c0eca1..d6a34091b 100644 --- a/graphify/rcfile.py +++ b/graphify/rcfile.py @@ -123,7 +123,10 @@ def load_graphifyrc(root: Path) -> dict: cfg: dict = {} languages: dict[str, str] = {} - content = rc_path.read_text(encoding="utf-8") + # utf-8-sig: Windows PowerShell 5.1 (`Set-Content -Encoding UTF8`) and older + # Notepad save UTF-8 with a BOM. Read as plain utf-8, the BOM became part of + # the first key, which then matched nothing and was ignored without a word. + content = rc_path.read_text(encoding="utf-8-sig") for line_num, raw in enumerate(content.splitlines(), 1): line = raw.strip() if not line or line.startswith("#"): diff --git a/tests/test_language_overrides.py b/tests/test_language_overrides.py index 9b38d398d..2bfbb5248 100644 --- a/tests/test_language_overrides.py +++ b/tests/test_language_overrides.py @@ -91,6 +91,19 @@ def test_language_line_maps_an_extension_to_a_canonical_suffix(tmp_path): assert load_graphifyrc(tmp_path) == {"languages": {".inc": ".php"}} +def test_a_utf8_bom_does_not_swallow_the_first_key(tmp_path): + """A .graphifyrc saved with a UTF-8 BOM (Windows PowerShell 5.1, older + Notepad) must not glue the BOM onto its first key, which then matched + nothing and was dropped without a warning.""" + (tmp_path / ".graphifyrc").write_bytes( + "\ufefflanguage.inc=php\nviz_node_limit=500\n".encode("utf-8") + ) + assert load_graphifyrc(tmp_path) == { + "languages": {".inc": ".php"}, + "viz_node_limit": 500, + } + + @pytest.mark.parametrize("key", ["language.inc", "language..inc", "language.INC", "language. inc "]) def test_the_extension_key_is_normalised(tmp_path, key): (tmp_path / ".graphifyrc").write_text(f"{key}=php\n", encoding="utf-8")