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
80
|
import io
import os
import re
import textwrap
import typing
import jinja2
from .debian import SourcePackage, BinaryPackage, TestsControl
class Templates(object):
dirs: list[str]
_cache: dict[str, str]
_jinja2: jinja2.Environment
def __init__(self, dirs: list[str] = ["debian/templates"]) -> None:
self.dirs = dirs
self._cache = {}
self._jinja2 = jinja2.Environment(
# autoescape uses HTML safe escaping, which does not help us
autoescape=False,
keep_trailing_newline=True,
trim_blocks=True,
undefined=jinja2.StrictUndefined,
)
def _read(self, name: str) -> typing.Any:
pkgid, name = name.rsplit('.', 1)
for suffix in ['.j2', '.in', '']:
for dir in self.dirs:
filename = "%s/%s.%s%s" % (dir, pkgid, name, suffix)
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as f:
mode = os.stat(f.fileno()).st_mode
return (f.read(), mode, suffix)
raise KeyError(name)
def _get(self, key: str) -> typing.Any:
try:
return self._cache[key]
except KeyError:
self._cache[key] = value = self._read(key)
return value
def get(self, key: str, context: dict[str, str] = {}) -> str:
value = self._get(key)
suffix = value[2]
if context:
if suffix == '.in':
def subst(match):
return context[match.group(1)]
return re.sub(r'@([-_a-z0-9]+)@', subst, str(value[0]))
elif suffix == '.j2':
return self._jinja2.from_string(value[0]).render(context)
return value[0]
def get_mode(self, key: str) -> str:
return self._get(key)[1]
def get_control(self, key: str, context: dict[str, str] = {}) -> BinaryPackage:
return BinaryPackage.read_rfc822(io.StringIO(self.get(key, context)))
def get_source_control(self, key: str, context: dict[str, str] = {}) -> SourcePackage:
return SourcePackage.read_rfc822(io.StringIO(self.get(key, context)))
def get_tests_control(self, key: str, context: dict[str, str] = {}) -> TestsControl:
return TestsControl.read_rfc822(io.StringIO(self.get(key, context)))
class TextWrapper(textwrap.TextWrapper):
wordsep_re = re.compile(
r'(\s+|' # any whitespace
r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash
|