88 lines
2.3 KiB
Python
88 lines
2.3 KiB
Python
#! python
|
|
# $NetBSD: fill-placeholders.py,v 1.2 2019/11/04 18:58:30 rillig Exp $
|
|
|
|
"""
|
|
Fills in some sections of data that are determined directly from the
|
|
pkgsrc code, such as variable names or help topics.
|
|
"""
|
|
|
|
import filecmp
|
|
import os
|
|
import re
|
|
import sys
|
|
from typing import Callable, List, Match, Set
|
|
from xml.sax.saxutils import escape as to_xml
|
|
|
|
pkgsrcdir = os.environ['PKGSRCDIR']
|
|
|
|
|
|
def read_lines(filename: str) -> List[str]:
|
|
with open(filename, 'r') as f:
|
|
return f.readlines()
|
|
|
|
|
|
def help_topics() -> str:
|
|
# type="vert" would spread the columns over several pages,
|
|
# starting with aaaa | pppp on the first page, which is
|
|
# unintuitive in both the PDF and the HTML version.
|
|
out = ['<simplelist type="horiz" columns="2">']
|
|
for line in read_lines('help-topics.data')[2:]:
|
|
topic = line.strip()
|
|
out.append(f'<member>{to_xml(topic)}</member>')
|
|
out.append('</simplelist>')
|
|
|
|
return '\n'.join(out)
|
|
|
|
|
|
def master_sites() -> str:
|
|
sites = []
|
|
|
|
for line in read_lines(f'{pkgsrcdir}/mk/fetch/sites.mk'):
|
|
m = re.match(r'^(MASTER_SITE_\w+)', line)
|
|
if m:
|
|
sites.append(m[1])
|
|
|
|
out = ['<simplelist type="horiz" columns="2">']
|
|
for site in sorted(sites):
|
|
out.append(f'<member>{to_xml(site)}</member>')
|
|
out.append('</simplelist>')
|
|
|
|
return '\n'.join(out)
|
|
|
|
|
|
def process(filename: str, placeholders: Set[Callable[[], str]]):
|
|
tmpl_filename = f'{filename}.tmpl'
|
|
tmp_filename = f'{filename}.tmp'
|
|
in_filename = tmpl_filename if os.path.isfile(tmpl_filename) else filename
|
|
out_filename = filename
|
|
|
|
phs = dict()
|
|
for p in placeholders:
|
|
phs[p.__name__] = p
|
|
|
|
def repl(m: Match):
|
|
return phs[m[1]]() if m[1] in phs else m[0]
|
|
|
|
out = []
|
|
for line in read_lines(in_filename):
|
|
out.append(re.sub(r'@(\w+)@', repl, line))
|
|
|
|
with open(tmp_filename, 'w') as f:
|
|
f.writelines(out)
|
|
|
|
if filecmp.cmp(tmp_filename, out_filename):
|
|
os.remove(tmp_filename)
|
|
elif in_filename == tmpl_filename:
|
|
os.replace(tmp_filename, out_filename)
|
|
else:
|
|
os.rename(out_filename, tmpl_filename)
|
|
os.rename(tmp_filename, out_filename)
|
|
|
|
|
|
def main():
|
|
for filename in sys.argv[1:]:
|
|
process(filename, {help_topics, master_sites})
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|