Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
system:packagemanager
mock
add-templated-directory.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File add-templated-directory.patch of Package mock
From 950ddc44ccdd04b50f8024cf8e31be5b4135a2b0 Mon Sep 17 00:00:00 2001 From: Miika Alikirri <miika.alikirri@suse.com> Date: Mon, 11 Sep 2023 10:06:20 +0300 Subject: Add TemplatedDictionary back to the project TemplatedDictionary is a small project that doesn't publish tito builds on GitHub and therefore would require tito to create package for it. Since TemplatedDictionary is a really small project and hasn't changed since Nov 18, 2020, it's easier to add it back to mock than it is to package tito to openSUSE products. See the project here: https://github.com/xsuchy/templated-dictionary --- mock/py/mockbuild/config.py | 3 +- mock/py/mockbuild/text.py | 85 +++++++++++++++++++++++++++++ mock/tests/test_config_templates.py | 2 +- mock/tests/test_package_manager.py | 2 +- 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/mock/py/mockbuild/config.py b/mock/py/mockbuild/config.py index 635bd7e..b834a9d 100644 --- a/py/mockbuild/config.py +++ b/py/mockbuild/config.py @@ -17,7 +17,6 @@ import socket import sys import warnings -from templated_dictionary import TemplatedDictionary from . import exception from . import text from .constants import MOCKCONFDIR, PKGPYTHONDIR, VERSION @@ -49,7 +48,7 @@ def nspawn_supported(): @traceLog() def setup_default_config_opts(): "sets up default configuration." - config_opts = TemplatedDictionary(alias_spec={'dnf.conf': ['yum.conf', 'dnf5.conf']}) + config_opts = text.TemplatedDictionary(alias_spec={'dnf.conf': ['yum.conf', 'dnf5.conf']}) config_opts['config_paths'] = [] config_opts['version'] = VERSION config_opts['basedir'] = '/var/lib/mock' # root name is automatically added to this diff --git a/mock/py/mockbuild/text.py b/mock/py/mockbuild/text.py index 0e3fa61..4221e82 100644 --- a/py/mockbuild/text.py +++ b/py/mockbuild/text.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- # vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:textwidth=0: +from collections.abc import MutableMapping import locale +import jinja2 from .trace_decorator import getLog @@ -20,6 +22,89 @@ def compat_expand_string(string, conf_dict): return string % conf_dict +# pylint: disable=no-member,unsupported-assignment-operation +class TemplatedDictionary(MutableMapping): + """ Dictionary where __getitem__() is run through Jinja2 template """ + def __init__(self, *args, alias_spec=None, **kwargs): + ''' + Use the object dict. + + Optional parameter 'alias_spec' is dictionary of form: + {'aliased_to': ['alias_one', 'alias_two', ...], ...} + When specified, and one of the aliases is accessed - the + 'aliased_to' config option is returned. + ''' + self.__dict__.update(*args, **kwargs) + + self._aliases = {} + if alias_spec: + for aliased_to, aliases in alias_spec.items(): + for alias in aliases: + self._aliases[alias] = aliased_to + + # The next five methods are requirements of the ABC. + def __setitem__(self, key, value): + key = self._aliases.get(key, key) + self.__dict__[key] = value + + def __getitem__(self, key): + key = self._aliases.get(key, key) + if '__jinja_expand' in self.__dict__ and self.__dict__['__jinja_expand']: + return self.__render_value(self.__dict__[key]) + return self.__dict__[key] + + def __delitem__(self, key): + del self.__dict__[key] + + def __iter__(self): + return iter(self.__dict__) + + def __len__(self): + return len(self.__dict__) + + # The final two methods aren't required, but nice to have + def __str__(self): + '''returns simple dict representation of the mapping''' + return str(self.__dict__) + + def __repr__(self): + '''echoes class, id, & reproducible representation in the REPL''' + return '{}, TemplatedDictionary({})'.format(super(TemplatedDictionary, self).__repr__(), + self.__dict__) + + def copy(self): + return TemplatedDictionary(self.__dict__) + + def __render_value(self, value): + if isinstance(value, str): + return self.__render_string(value) + elif isinstance(value, list): + # we cannot use list comprehension here, as we need to NOT modify the list (pointer to list) + # and we need to modifiy only individual values in the list + # If we would create new list, we cannot assign to it, which often happens in configs (e.g. plugins) + for i in range(len(value)): # pylint: disable=consider-using-enumerate + value[i] = self.__render_value(value[i]) + return value + elif isinstance(value, dict): + # we cannot use list comprehension here, same reasoning as for `list` above + for k in value.keys(): + value[k] = self.__render_value(value[k]) + return value + else: + return value + + def __render_string(self, value): + orig = last = value + max_recursion = self.__dict__.get('jinja_max_recursion', 5) + for _ in range(max_recursion): + template = jinja2.Template(value, keep_trailing_newline=True) + value = _to_native(template.render(self.__dict__)) + if value == last: + return value + last = value + raise ValueError("too deep jinja re-evaluation on '{}'".format(orig)) + + def _to_text(obj, arg_encoding='utf-8', errors='strict', nonstring='strict'): if isinstance(obj, str): return obj diff --git a/mock/tests/test_config_templates.py b/mock/tests/test_config_templates.py index 57b284c..cbe9c19 100644 --- a/tests/test_config_templates.py +++ b/tests/test_config_templates.py @@ -1,5 +1,5 @@ import pytest -from templated_dictionary import TemplatedDictionary +from mockbuild.text import TemplatedDictionary def test_transitive_expand(): diff --git a/mock/tests/test_package_manager.py b/mock/tests/test_package_manager.py index c26d6cc..441b836 100644 --- a/tests/test_package_manager.py +++ b/tests/test_package_manager.py @@ -6,7 +6,7 @@ import pytest from unittest import mock from unittest.mock import MagicMock -from templated_dictionary import TemplatedDictionary +from mockbuild.text import TemplatedDictionary from mockbuild.config import setup_default_config_opts from mockbuild.constants import PKGPYTHONDIR from mockbuild.buildroot import Buildroot -- 2.41.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor