[object Object]

← back to Designer Wallcoverings

patcher: make .value regex non-backtracking ((?!\\w)) so re-runs are truly idempotent

005ffea3870051050d8cda9b6dc5a5dcd5f2ecde · 2026-06-24 15:42:24 -0700 · Steve

Prevents silent .valueX corruption if the patcher is ever run on an
already-fixed snippet (the old lookahead let the key backtrack to a truncated
form). Unit-tested: no-op on fixed text, correct on bare text, double-run safe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 005ffea3870051050d8cda9b6dc5a5dcd5f2ecde
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jun 24 15:42:24 2026 -0700

    patcher: make .value regex non-backtracking ((?!\\w)) so re-runs are truly idempotent
    
    Prevents silent .valueX corruption if the patcher is ever run on an
    already-fixed snippet (the old lookahead let the key backtrack to a truncated
    form). Unit-tested: no-op on fixed text, correct on bare text, double-run safe.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 shopify/push-spec-metafield-value-fix.sh | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/shopify/push-spec-metafield-value-fix.sh b/shopify/push-spec-metafield-value-fix.sh
index ceac50b0..4adff5e6 100755
--- a/shopify/push-spec-metafield-value-fix.sh
+++ b/shopify/push-spec-metafield-value-fix.sh
@@ -58,8 +58,11 @@ stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
 bk = f"{bkdir}/product-description-meta.{label}.{tid}.{stamp}.bak"
 open(bk, "w").write(cur); print(f"backup: {bk} ({len(cur)} bytes)")
 
-# idempotent: append .value to bare metafield refs (dotted + bracket keys)
-pat = re.compile(r"(product\.metafields\.\w+(?:\.\w+|\['[^']*'\]))(?!\.value)")
+# idempotent: append .value to bare metafield refs (dotted + bracket keys).
+# (?!\w) anchors the key to its full length so the match can't backtrack to a
+# truncated key on already-fixed text (e.g. custom.width.value) — making re-runs
+# safe (true idempotency, no .valueX corruption).
+pat = re.compile(r"(product\.metafields\.\w+(?:\.\w+|\['[^']*'\]))(?!\w)(?!\.value)")
 before = len(pat.findall(cur))
 src = pat.sub(r"\1.value", cur)
 after_bare = len(pat.findall(src))

← 75e798ac Add reusable Shopify theme duplication script (asset-copy +  ·  back to Designer Wallcoverings  ·  Fix double-encoded metafield leak: unwrap {type,value} blobs b25933f1 →