fix(markdown): respect ignore rules when building wikilink index (#3822)

This commit is contained in:
abhirupone committed 2026-09-25 15:27:43 +05:30
1 parent 4c735618f3
commit 48a8da896b
2 files changed
+53 -6

No files matched your search

+13 -6
View File
@@ -147,20 +147,27 @@ def _build_link_index(root: Path) -> "dict[str, list[tuple[int, str, Path]]]":
"""Index every linkable document under *root* by NFC-normalized basename.
Each entry maps basename -> [(depth, root-relative posix path, absolute
path)]. Directories in detect._SKIP_DIRS and dot-directories are pruned —
the same corpus boundary the scanner draws, and Obsidian itself does not
index dot-folders.
path)]. Directories in detect._SKIP_DIRS, dot-directories, and paths
excluded by .graphifyignore/.gitignore are pruned — the same corpus
boundary the scanner draws, and Obsidian itself does not index dot-folders
or ignored paths (#3822).
"""
from graphify.detect import _SKIP_DIRS
from graphify.detect import _SKIP_DIRS, ignored_predicate
root = Path(root)
ignored = ignored_predicate(root)
index: dict[str, list[tuple[int, str, Path]]] = {}
for dirpath, dirnames, filenames in os.walk(root):
dp = Path(dirpath)
dirnames[:] = sorted(
d for d in dirnames if not d.startswith(".") and d not in _SKIP_DIRS
d for d in dirnames
if not d.startswith(".") and d not in _SKIP_DIRS and not ignored(dp / d)
)
for fname in filenames:
if Path(fname).suffix.lower() not in _MD_LINKABLE_EXTS:
continue
abs_path = Path(dirpath) / fname
abs_path = dp / fname
if ignored(abs_path):
continue
rel = os.path.relpath(str(abs_path), str(root)).replace("\\", "/")
index.setdefault(_nfc(fname), []).append(
(rel.count("/"), _nfc(rel), abs_path)
+40
View File
@@ -3119,6 +3119,46 @@ def test_markdown_wikilink_fallback_unicode_normalization(tmp_path):
for e in refs), f"NFD wikilink missed the NFC file: {refs}"
def test_markdown_wikilink_index_prunes_ignored_directories(tmp_path, monkeypatch):
"""#3822: _build_link_index must prune directories and files matched by
.graphifyignore/.gitignore, preventing both 50+ min directory walks on
large ignored trees and wikilinks erroneously resolving into ignored files."""
vault = tmp_path / "vault"
vault.mkdir()
(vault / ".graphifyignore").write_text("bigdata/\nsecret.md\n", encoding="utf-8")
(vault / "notes").mkdir()
(vault / "notes" / "hub.md").write_text("# Hub\nSee [[target]] and [[secret]].\n", encoding="utf-8")
(vault / "notes" / "target.md").write_text("# Target\n", encoding="utf-8")
(vault / "bigdata").mkdir()
(vault / "bigdata" / "sub").mkdir()
(vault / "bigdata" / "sub" / "secret.md").write_text("# Secret in bigdata\n", encoding="utf-8")
import os
visited = []
real_walk = os.walk
def spy_walk(top, *args, **kwargs):
for dirpath, dirnames, filenames in real_walk(top, *args, **kwargs):
visited.append(os.path.relpath(dirpath, str(vault)))
yield dirpath, dirnames, filenames
monkeypatch.setattr(os, "walk", spy_walk)
node_ids, refs, page_id = _vault_extract(
vault, [vault / "notes" / "hub.md", vault / "notes" / "target.md"]
)
bigdata_walked = [v for v in visited if v.startswith("bigdata")]
assert not bigdata_walked, f"ignored directory descended during index walk: {bigdata_walked}"
hub_id = page_id(vault / "notes" / "hub.md")
target_id = page_id(vault / "notes" / "target.md")
assert any(e["source"] == hub_id and e["target"] == target_id for e in refs), f"valid target link lost: {refs}"
assert not any("bigdata" in e["target"] for e in refs), f"wikilink resolved into ignored path: {refs}"
# ── Groovy ───────────────────────────────────────────────────────────────────