Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/codealmanac/services/wiki/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ def iter_page_paths(almanac_path: Path) -> Iterator[Path]:
if not almanac_path.is_dir():
return
for path in sorted(almanac_path.rglob("*.md")):
# `rglob` is case-insensitive on Windows and on default macOS volumes, so
# it also matches ".MD" and ".Md". `page_id_for_path` compares the suffix
# exactly, so yielding one of those raises and takes down every command
# that reindexes. Linux never matched them at all, so skipping here is
# what makes the three platforms agree on the same wiki tree.
if path.suffix != ".md":
continue
if is_reserved_page_path(almanac_path, path):
continue
yield path
Expand Down
34 changes: 34 additions & 0 deletions tests/test_wiki_parsing.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from pathlib import Path

from codealmanac.services.wiki.frontmatter import parse_frontmatter
from codealmanac.services.wiki.links import extract_page_links, resolve_page_href
from codealmanac.services.wiki.paths import (
escape_glob_meta,
iter_page_paths,
normalize_reference_path,
page_id_for_path,
)


Expand All @@ -19,6 +22,37 @@ def test_page_iteration_excludes_repository_manuals(tmp_path):
assert tuple(iter_page_paths(almanac_path)) == (page,)


def test_page_iteration_excludes_uppercase_markdown_suffixes(tmp_path):
almanac_path = tmp_path / "almanac"
almanac_path.mkdir(parents=True)
page = almanac_path / "wiki.md"
page.write_text("# Wiki\n", encoding="utf-8")
(almanac_path / "NOTES.MD").write_text("# Notes\n", encoding="utf-8")
(almanac_path / "Mixed.Md").write_text("# Mixed\n", encoding="utf-8")

assert tuple(iter_page_paths(almanac_path)) == (page,)


def test_page_iteration_filters_case_insensitive_glob_matches(tmp_path, monkeypatch):
# `rglob` only returns uppercase suffixes on a case-insensitive filesystem,
# so on Linux the test above cannot reach the filter at all. Feeding the
# match in directly pins the behaviour on every runner, and keeps
# `iter_page_paths` and `page_id_for_path` provably in agreement.
almanac_path = tmp_path / "almanac"
almanac_path.mkdir(parents=True)
page = almanac_path / "wiki.md"
page.write_text("# Wiki\n", encoding="utf-8")
upper = almanac_path / "NOTES.MD"
upper.write_text("# Notes\n", encoding="utf-8")
monkeypatch.setattr(Path, "rglob", lambda self, pattern: iter((page, upper)))

iterated = tuple(iter_page_paths(almanac_path))

assert iterated == (page,)
for path in iterated:
assert page_id_for_path(almanac_path, path)


def test_frontmatter_uses_pydantic_validated_shape():
parsed = parse_frontmatter(
"""---
Expand Down