-
Notifications
You must be signed in to change notification settings - Fork 2
/
regen.py
executable file
·79 lines (58 loc) · 2.41 KB
/
regen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env python
# This is intended to be run with the 'skel' branch of some other repo checked
# out.
import configparser
import re
from pathlib import Path
from typing import Match
THIS_DIR = Path(__file__).absolute().parent
TEMPLATE_DIR = THIS_DIR / "templates"
# This is very simplistic...
VARIABLE_RE = re.compile(r"(?<!{){(@?[\w,]+)}")
VARS_FILENAME = ".vars.ini"
def variable_format(tmpl: str, **kwargs: str) -> str:
"""
This is similar to string.format but uses the regex above.
This means that '{ foo }' is not an interpolation, nor is '{{foo}}', but we
also don't get '!r' suffix for free. Maybe someday.
Non-interpolations can be written '{@foo}' which becomes '{foo}' when
rendered.
"""
def replace(match: Match[str]) -> str:
g = match.group(1)
if g[:1] == "@":
return match.group(0).replace("@", "", 1)
if g in kwargs:
return kwargs[g]
return match.group(0)
return VARIABLE_RE.sub(replace, tmpl)
def main() -> None:
# In case we've answered anything before, attempt load.
parser = configparser.RawConfigParser()
parser.read([VARS_FILENAME])
if "vars" not in parser:
parser.add_section("vars")
for template_path in TEMPLATE_DIR.glob("**/*"):
if template_path.suffix == ".in":
data = template_path.read_text()
variables = []
variables.extend(VARIABLE_RE.findall(data))
variables.extend(VARIABLE_RE.findall(str(template_path)))
for v in variables:
if v[:1] != "@" and v not in parser["vars"]:
parser["vars"][v] = input(f"Value for {v}? ").strip()
with open(VARS_FILENAME, "w") as f:
parser.write(f)
interpolated_data = variable_format(data, **parser["vars"])
local_path = template_path.with_suffix("").relative_to(TEMPLATE_DIR)
local_path = Path(variable_format(str(local_path), **parser["vars"]))
if local_path.exists():
existing_data = local_path.read_text()
if existing_data == interpolated_data:
print(f"Unchanged {local_path}")
continue
print(f"Writing {local_path}")
local_path.parent.mkdir(parents=True, exist_ok=True)
local_path.write_text(interpolated_data)
if __name__ == "__main__":
main()