cmds.projects.lib.templates: Don't replace escaped markers
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m43s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m42s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m13s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m21s
CI / Packaging test (push) Successful in 0s

format_list_dict() substitutes {key} markers with str.replace(), which also
matches the marker inside ${key} and {{key}}, mangling text meant to
survive verbatim, e.g. the ${prefix} variable reference of a pkg-config
file. The built-in pkg-config template works around that with doubled
braces, which produces {/usr}-style output instead.

Replace the markers with a regular expression that skips markers preceded
by '$' or '{', and let the pkg-config template use the ${prefix} and
${exec_prefix} references pkg-config expects.

Extend the unit tests with marker escaping, value escaping, quoting,
indentation, and the rendering of the built-in templates.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.84.2
Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-09-08 21:45:22 +02:00
commit 61280e4695
Signed by: Jan Lindemann
GPG key ID: 3750640C9E25DD61
2 changed files with 100 additions and 10 deletions

View file

@ -1,3 +1,4 @@
import re
import textwrap
from typing import Any, Iterable, TypeAlias, TypeGuard
@ -95,12 +96,17 @@ def format_list_dict(
parts = template.splitlines(keepends = True)
for line in parts:
for key, value in fmt_dict.items():
marker = '{' + key + '}'
if marker in line:
indent = line[:line.index(marker)]
value = str(value).replace('\n', '\n' + indent)
line = line.replace(marker, value)
for key, val in fmt_dict.items():
# -- A marker preceded by '$' or '{' is literal text rather
# than a placeholder, so that e.g. ${prefix} survives as a
# pkg-config variable reference
rx = re.compile(r'(?<![${])\{' + re.escape(key) + r'\}')
m = rx.search(line)
if m is None:
continue
indent = line[:m.start()]
sub = str(val).replace('\n', '\n' + indent)
line = rx.sub(lambda _m: sub, line)
ret.append(line)
return ''.join(ret)
@ -114,9 +120,9 @@ _templates = {
'pkg-config':
"""\
prefix = {prefix}
exec_prefix = {{prefix}}
includedir = {{prefix}}/include
libdir = {{exec_prefix}}/lib
exec_prefix = ${prefix}
includedir = ${prefix}/include
libdir = ${exec_prefix}/lib
Name: {name}
Description: {description}