summaryrefslogtreecommitdiffstats
path: root/debian/lib/python/debian_linux/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'debian/lib/python/debian_linux/utils.py')
-rw-r--r--debian/lib/python/debian_linux/utils.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/debian/lib/python/debian_linux/utils.py b/debian/lib/python/debian_linux/utils.py
new file mode 100644
index 000000000..8f0463413
--- /dev/null
+++ b/debian/lib/python/debian_linux/utils.py
@@ -0,0 +1,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