mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-28 17:26:48 +00:00
fix(export)+test: all-dots Obsidian label falls back to unnamed; .env.example regression test (#2205, #2184)
Follow-ups on the cherry-picked #2242/#2232: an all-dots label ('...') no
longer produces an empty 'dot-' Obsidian stem (falls back to 'unnamed'),
and the .env.example carve-out gets the regression test it shipped without
(templates graphable, real .env still sensitive, secrets/.env.example still dropped).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2099873ae6
commit
829224acd0
+5
-2
@@ -444,8 +444,11 @@ def _obsidian_safe_stem(label: str) -> str:
|
||||
label.replace("\r\n", " ").replace("\r", " ").replace("\n", " "),
|
||||
).strip()
|
||||
cleaned = re.sub(r"\.(md|mdx|qmd|markdown)$", "", cleaned, flags=re.IGNORECASE)
|
||||
# Obsidian treats a leading-dot filename as a hidden file (#2205).
|
||||
if cleaned.startswith("."):
|
||||
# Obsidian treats a leading-dot filename as a hidden file (#2205). Only
|
||||
# prefix when something nameable remains after the dots: an all-dots label
|
||||
# like "..." would otherwise become the meaningless stem "dot-" instead of
|
||||
# falling through to the "unnamed" guard below (#1409).
|
||||
if cleaned.startswith(".") and re.search(r"\w", cleaned.lstrip("."), flags=re.UNICODE):
|
||||
cleaned = "dot-" + cleaned.lstrip(".")
|
||||
# A stem of only punctuation (e.g. "@", "*", "#") survives the unsafe-char
|
||||
# strip above but is empty once a downstream tool re-slugs on word chars
|
||||
|
||||
@@ -2530,3 +2530,42 @@ def test_sensitive_bare_keyword_prose_still_dropped():
|
||||
assert _is_sensitive(Path("secrets.md"))
|
||||
assert _is_sensitive(Path("token.rst"))
|
||||
assert not _is_sensitive(Path("token-lifecycle.md")) # multi-word slug indexed
|
||||
|
||||
|
||||
# ── #2232 / #2184: committed dotenv templates (.env.example etc.) are graphable ──
|
||||
|
||||
@pytest.mark.parametrize("path", [
|
||||
".env.example",
|
||||
".env.sample",
|
||||
".env.template",
|
||||
".env.dist",
|
||||
".ENV.EXAMPLE", # case-insensitive, real on macOS/Windows
|
||||
".envrc.sample", # direnv template
|
||||
".env.production.example", # per-environment template
|
||||
])
|
||||
def test_sensitive_filter_indexes_env_templates(path):
|
||||
"""Placeholder-only committed templates must not be treated as live secrets."""
|
||||
assert not _is_sensitive(Path(path)), f"{path} is a committed template, must be indexed (#2184)"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", [
|
||||
".env",
|
||||
".env.local",
|
||||
".env.production",
|
||||
".envrc",
|
||||
".env.example.local", # template suffix not final -> a real local override
|
||||
".env.example.bak", # backup of a (possibly filled-in) env file
|
||||
])
|
||||
def test_sensitive_filter_still_excludes_real_env_files(path):
|
||||
"""The template carve-out is suffix-anchored; live env files stay excluded."""
|
||||
assert _is_sensitive(Path(path)), f"{path} is a live env file, must stay excluded (#2184)"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", [
|
||||
"secrets/.env.example",
|
||||
"deploy/credentials/.env.example",
|
||||
])
|
||||
def test_sensitive_env_template_inside_secrets_dir_still_dropped(path):
|
||||
"""Stage 1 dir guard runs before the Stage 2 template exemption: anything
|
||||
under a secrets/credentials dir stays excluded, template suffix or not."""
|
||||
assert _is_sensitive(Path(path)), f"{path} is under a secrets dir, must stay excluded (#2184)"
|
||||
|
||||
@@ -459,6 +459,16 @@ def test_to_obsidian_leading_dot_labels_are_not_hidden_filenames():
|
||||
assert not any(s.startswith(".") for s in file_stems), file_stems
|
||||
|
||||
|
||||
def test_obsidian_safe_stem_all_dots_label_falls_back_to_unnamed():
|
||||
"""#2205 follow-up: the `dot-` prefix only applies when a word char survives
|
||||
the dot strip. An all-dots label like "..." must hit the #1409 "unnamed"
|
||||
fallback, not produce the meaningless stem "dot-"."""
|
||||
from graphify.export import _obsidian_safe_stem
|
||||
assert _obsidian_safe_stem(".env") == "dot-env" # #2205 fix unchanged
|
||||
assert _obsidian_safe_stem("...") == "unnamed" # not "dot-"
|
||||
assert _obsidian_safe_stem("Database") == "Database" # normal labels untouched
|
||||
|
||||
|
||||
# ── Existing-vault safety: graphify must not clobber user notes / .obsidian (#1506) ──
|
||||
|
||||
def _two_node_graph():
|
||||
|
||||
Reference in New Issue
Block a user