mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-12 18:37:12 +00:00
f9174943a2
#1649: detect_incremental tracks the converted markdown sidecar, and convert_office_file early-returned whenever the sidecar existed — so a .docx/ .xlsx edited after its first conversion never updated its sidecar and was reported "unchanged" forever, freezing the graph. It now re-converts when the source is newer than the sidecar (bumping the sidecar so the hash check catches it); an unchanged source still skips the rewrite (#1226). #1655: _md5_file/save_manifest/count_words used plain open()/stat(), which the Windows file APIs reject for absolute paths over 260 chars unless prefixed with `\\?\`. Deeply-nested files never hashed, their manifest entry never stabilized, and detect_incremental re-flagged them as changed every run. A new _os_path adds the extended-length prefix on win32 for change-detection I/O (mirror of cache._normalize_path, which strips it for keys). No-op elsewhere. #1656: detect() re-parsed every PDF/docx/text file to size the corpus on each run. Word counts are now memoized in the existing content-hash stat index (keyed by size + mtime_ns), so an unchanged file is parsed once. file_hash's fastpath is guarded so a word-count-only entry (no hash) can't KeyError, and both writers augment a co-located entry in place instead of clobbering the other's field. Full suite: 2906 passed, 3 skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
"""#1649 — a modified .docx/.xlsx must re-enter --update.
|
|
|
|
detect_incremental tracks the converted markdown SIDECAR, not the Office
|
|
source. convert_office_file used to early-return whenever the sidecar existed,
|
|
so a source edited after its first conversion never updated its sidecar and was
|
|
reported "unchanged" forever. It now re-converts when the source is newer than
|
|
the sidecar (and still skips an unchanged source so it never churns, #1226).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from graphify import detect
|
|
|
|
docx = pytest.importorskip("docx")
|
|
|
|
|
|
def _make_docx(path: Path, text: str) -> None:
|
|
d = docx.Document()
|
|
d.add_paragraph(text)
|
|
d.save(str(path))
|
|
|
|
|
|
def _bump_mtime(path: Path, offset: float) -> None:
|
|
"""Set path's mtime relative to now so ordering is deterministic."""
|
|
st = path.stat()
|
|
os.utime(path, (st.st_atime, st.st_mtime + offset))
|
|
|
|
|
|
def test_modified_docx_reconverts_sidecar(tmp_path: Path):
|
|
src = tmp_path / "doc.docx"
|
|
out = tmp_path / "converted"
|
|
_make_docx(src, "original alpha content")
|
|
|
|
sidecar = detect.convert_office_file(src, out)
|
|
assert sidecar is not None
|
|
assert "original alpha content" in sidecar.read_text(encoding="utf-8")
|
|
|
|
# Edit the source and make it newer than the sidecar.
|
|
_make_docx(src, "revised beta content")
|
|
_bump_mtime(sidecar, -10) # sidecar older than the freshly-written source
|
|
|
|
sidecar2 = detect.convert_office_file(src, out)
|
|
assert sidecar2 == sidecar # same deterministic name
|
|
body = sidecar2.read_text(encoding="utf-8")
|
|
assert "revised beta content" in body
|
|
assert "original alpha content" not in body
|
|
|
|
|
|
def test_unchanged_docx_sidecar_not_rewritten(tmp_path: Path):
|
|
src = tmp_path / "doc.docx"
|
|
out = tmp_path / "converted"
|
|
_make_docx(src, "stable content")
|
|
|
|
sidecar = detect.convert_office_file(src, out)
|
|
assert sidecar is not None
|
|
# Make the sidecar clearly newer than the (unchanged) source.
|
|
_bump_mtime(sidecar, 100)
|
|
before = sidecar.stat().st_mtime
|
|
|
|
sidecar2 = detect.convert_office_file(src, out)
|
|
assert sidecar2 == sidecar
|
|
# Not rewritten: mtime unchanged, so detect_incremental won't see churn (#1226).
|
|
assert sidecar2.stat().st_mtime == before
|