|
|
|
@ -81,6 +81,8 @@ class ParametersProcessor:
|
|
|
|
|
inheritable_parameters = {'chmod', 'chown', 'autoupdate', 'env',
|
|
|
|
|
'package', 'action'}
|
|
|
|
|
|
|
|
|
|
to_check_while_parsing = {'package'}
|
|
|
|
|
|
|
|
|
|
available_appends = set()
|
|
|
|
|
|
|
|
|
|
available_formats = set()
|
|
|
|
@ -94,6 +96,8 @@ class ParametersProcessor:
|
|
|
|
|
datavars_module=Variables()):
|
|
|
|
|
self.chroot_path = chroot_path
|
|
|
|
|
|
|
|
|
|
self.template_type = DIR
|
|
|
|
|
|
|
|
|
|
self.datavars_module = datavars_module
|
|
|
|
|
|
|
|
|
|
self._parameters_container = parameters_container
|
|
|
|
@ -479,6 +483,7 @@ class ParametersProcessor:
|
|
|
|
|
def resolve_or_missing(context, key, missing=missing, env={}):
|
|
|
|
|
'''Переопределение функции из для поиска значений переменных из jinja2.
|
|
|
|
|
Ищет переменные в datavars.'''
|
|
|
|
|
print('THERE IS MY RESOLVE_OR_MISSING')
|
|
|
|
|
datavars = context.parent['__datavars__']
|
|
|
|
|
|
|
|
|
|
if key in context.vars:
|
|
|
|
@ -601,15 +606,17 @@ class CalculateExtension(Extension):
|
|
|
|
|
'''Класс расширения для jinja2, поддерживающий теги calculate-шаблонов.'''
|
|
|
|
|
_parameters_set = set()
|
|
|
|
|
|
|
|
|
|
_datavars = Variables()
|
|
|
|
|
|
|
|
|
|
parameters_processor = None
|
|
|
|
|
|
|
|
|
|
def __init__(self, environment):
|
|
|
|
|
def __init__(self, environment, datavars_module=Variables()):
|
|
|
|
|
super().__init__(environment)
|
|
|
|
|
self.environment = environment
|
|
|
|
|
|
|
|
|
|
self.environment.globals.update({'pkg': self.pkg})
|
|
|
|
|
|
|
|
|
|
self._datavars = datavars_module
|
|
|
|
|
self.template_type = DIR
|
|
|
|
|
|
|
|
|
|
self.tags = {'calculate', 'save', 'set_var'}
|
|
|
|
|
self.CONDITION_TOKENS_TYPES = {'eq', 'ne', 'lt', 'gt', 'lteq', 'gteq'}
|
|
|
|
|
self.LITERAL_TOKENS_TYPES = {'string', 'integer', 'float'}
|
|
|
|
@ -618,6 +625,9 @@ class CalculateExtension(Extension):
|
|
|
|
|
self.parse_methods = {'calculate': self.parse_calculate,
|
|
|
|
|
'save': self.parse_save}
|
|
|
|
|
|
|
|
|
|
def __call__(self, env):
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def parse(self, parser):
|
|
|
|
|
self.parser = parser
|
|
|
|
|
self.stream = parser.stream
|
|
|
|
@ -663,7 +673,6 @@ class CalculateExtension(Extension):
|
|
|
|
|
def parse_calculate(self):
|
|
|
|
|
'''Метод для разбора тега calculate, содержащего значения параметров и
|
|
|
|
|
условия выполнения шаблона.'''
|
|
|
|
|
pairs_list = []
|
|
|
|
|
expect_comma_flag = False
|
|
|
|
|
|
|
|
|
|
lineno = next(self.stream).lineno
|
|
|
|
@ -680,12 +689,22 @@ class CalculateExtension(Extension):
|
|
|
|
|
# разбираем параметр.
|
|
|
|
|
# pairs_list.append(self.get_parameter_node())
|
|
|
|
|
name_node, value_node = self.get_parameter()
|
|
|
|
|
|
|
|
|
|
check_node = self.call_method('check_parameter',
|
|
|
|
|
[name_node,
|
|
|
|
|
value_node,
|
|
|
|
|
nodes.ContextReference()],
|
|
|
|
|
lineno=lineno)
|
|
|
|
|
pairs_list.append(check_node)
|
|
|
|
|
check_template_node = nodes.Template(
|
|
|
|
|
[nodes.Output([check_node])])
|
|
|
|
|
|
|
|
|
|
check_template_node = check_template_node.set_environment(
|
|
|
|
|
self.environment)
|
|
|
|
|
|
|
|
|
|
check_template = self.environment.from_string(
|
|
|
|
|
check_template_node)
|
|
|
|
|
check_template.render(__datavars__=self._datavars)
|
|
|
|
|
|
|
|
|
|
elif (self.stream.current.type == 'name'
|
|
|
|
|
or self.stream.current.type == 'lparen'):
|
|
|
|
|
# разбираем условие. Если условие False -- кидаем исключение.
|
|
|
|
@ -707,49 +726,74 @@ class CalculateExtension(Extension):
|
|
|
|
|
# lineno=lineno)
|
|
|
|
|
# return nodes.Output([save_node], lineno=lineno)
|
|
|
|
|
|
|
|
|
|
return nodes.Output(pairs_list, lineno=lineno)
|
|
|
|
|
return nodes.Output([nodes.Const('')], lineno=lineno)
|
|
|
|
|
|
|
|
|
|
def check_parameter(self, parameter_name, parameter_value, context):
|
|
|
|
|
template_type = context.parent['__template_type__']
|
|
|
|
|
|
|
|
|
|
self.parameters_processor.check_template_parameter(
|
|
|
|
|
parameter_name,
|
|
|
|
|
parameter_value,
|
|
|
|
|
template_type,
|
|
|
|
|
self.template_type,
|
|
|
|
|
self.stream.current.lineno)
|
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
def get_condition_result(self):
|
|
|
|
|
'''Метод для разбора условий из тега calculate.'''
|
|
|
|
|
condition_list = []
|
|
|
|
|
# лучший способ -- парсим в AST дерево, после чего компилируем и
|
|
|
|
|
# выполняем его.
|
|
|
|
|
self.condition_result = False
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
condition_node = self.parser.parse_expression(with_condexpr=True)
|
|
|
|
|
condition_node = self.call_method(
|
|
|
|
|
'set_condition_result',
|
|
|
|
|
[condition_node],
|
|
|
|
|
lineno=self.stream.current.lineno)
|
|
|
|
|
condition_template = nodes.Template(
|
|
|
|
|
[nodes.Output([condition_node])])
|
|
|
|
|
|
|
|
|
|
condition_template = condition_template.set_environment(
|
|
|
|
|
self.environment)
|
|
|
|
|
template = self.environment.from_string(condition_template)
|
|
|
|
|
|
|
|
|
|
template.render(__datavars__=self._datavars)
|
|
|
|
|
except Exception:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
return self.condition_result
|
|
|
|
|
|
|
|
|
|
# собираем исходный код условия из токенов.
|
|
|
|
|
# вероятно, следует придумать лучший способ.
|
|
|
|
|
while (self.stream.current.type != 'block_end' and
|
|
|
|
|
self.stream.current.type != 'comma'):
|
|
|
|
|
if self.stream.current.type == 'string':
|
|
|
|
|
condition_list.append("'{}'".format(
|
|
|
|
|
self.stream.current.value
|
|
|
|
|
))
|
|
|
|
|
elif self.stream.current.type == 'dot':
|
|
|
|
|
self.stream.skip(1)
|
|
|
|
|
if self.stream.current.type == 'name':
|
|
|
|
|
next_name = '.' + self.stream.current.value
|
|
|
|
|
else:
|
|
|
|
|
raise TemplateSyntaxError(
|
|
|
|
|
'Variable name is not correct.',
|
|
|
|
|
lineno=self.stream.current.lineno
|
|
|
|
|
)
|
|
|
|
|
condition_list[-1] = condition_list[-1] + next_name
|
|
|
|
|
else:
|
|
|
|
|
condition_list.append(str(self.stream.current.value))
|
|
|
|
|
self.stream.skip(1)
|
|
|
|
|
|
|
|
|
|
condition = ' '.join(condition_list)
|
|
|
|
|
# while (self.stream.current.type != 'block_end' and
|
|
|
|
|
# self.stream.current.type != 'comma'):
|
|
|
|
|
# if self.stream.current.type == 'string':
|
|
|
|
|
# condition_list.append("'{}'".format(
|
|
|
|
|
# self.stream.current.value
|
|
|
|
|
# ))
|
|
|
|
|
# elif self.stream.current.type == 'dot':
|
|
|
|
|
# self.stream.skip(1)
|
|
|
|
|
# if self.stream.current.type == 'name':
|
|
|
|
|
# next_name = '.' + self.stream.current.value
|
|
|
|
|
# else:
|
|
|
|
|
# raise TemplateSyntaxError(
|
|
|
|
|
# 'Variable name is not correct.',
|
|
|
|
|
# lineno=self.stream.current.lineno
|
|
|
|
|
# )
|
|
|
|
|
# condition_list[-1] = condition_list[-1] + next_name
|
|
|
|
|
# else:
|
|
|
|
|
# condition_list.append(str(self.stream.current.value))
|
|
|
|
|
# self.stream.skip(1)
|
|
|
|
|
|
|
|
|
|
# condition = ' '.join(condition_list)
|
|
|
|
|
|
|
|
|
|
# компилируем исходный код условия и получаем результат его вычисления.
|
|
|
|
|
cond_expr = self.environment.compile_expression(condition)
|
|
|
|
|
condition_result = cond_expr(__datavars__=self._datavars)
|
|
|
|
|
return condition_result
|
|
|
|
|
|
|
|
|
|
# cond_expr = self.environment.compile_expression(condition)
|
|
|
|
|
# condition_result = cond_expr(__datavars__=self._datavars)
|
|
|
|
|
# return condition_result
|
|
|
|
|
|
|
|
|
|
def set_condition_result(self, condition_result):
|
|
|
|
|
self.condition_result = condition_result
|
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
def save_variable(self, variable_name, right_value, target_file, context):
|
|
|
|
|
'''Метод для сохранения значений переменных указанных в теге save.'''
|
|
|
|
@ -774,8 +818,10 @@ class CalculateExtension(Extension):
|
|
|
|
|
def get_parameter(self):
|
|
|
|
|
'''Метод для разбра параметров, содержащихся в теге calculate.'''
|
|
|
|
|
lineno = self.stream.current.lineno
|
|
|
|
|
|
|
|
|
|
parameter_name = self.stream.expect('name').value
|
|
|
|
|
parameter_name_node = nodes.Const(parameter_name, lineno=lineno)
|
|
|
|
|
|
|
|
|
|
if self.stream.skip_if('assign'):
|
|
|
|
|
parameter_value = self.stream.current.value
|
|
|
|
|
parameter_rvalue = self.parser.parse_expression(with_condexpr=True)
|
|
|
|
@ -787,7 +833,8 @@ class CalculateExtension(Extension):
|
|
|
|
|
CalculateContext._env_set.add(name.strip())
|
|
|
|
|
else:
|
|
|
|
|
parameter_rvalue = nodes.Const(True, lineno=lineno)
|
|
|
|
|
# return nodes.Pair(parameter_name_node, parameter_rvalue)
|
|
|
|
|
parameter_value = True
|
|
|
|
|
|
|
|
|
|
return (parameter_name_node, parameter_rvalue)
|
|
|
|
|
|
|
|
|
|
def save_parameters(cls, parameters_dictionary, context):
|
|
|
|
@ -828,7 +875,9 @@ class TemplateEngine:
|
|
|
|
|
|
|
|
|
|
self.available_formats = ParametersProcessor.available_formats
|
|
|
|
|
self.available_appends = appends_set
|
|
|
|
|
|
|
|
|
|
ParametersProcessor.available_appends = appends_set
|
|
|
|
|
|
|
|
|
|
self._datavars_module = datavars_module
|
|
|
|
|
self._template_text = ''
|
|
|
|
|
|
|
|
|
@ -839,8 +888,14 @@ class TemplateEngine:
|
|
|
|
|
|
|
|
|
|
CalculateExtension.parameters_processor = self.parameters_processor
|
|
|
|
|
|
|
|
|
|
self.environment = Environment(loader=FileSystemLoader(directory_path),
|
|
|
|
|
extensions=[CalculateExtension])
|
|
|
|
|
self.environment = Environment(loader=FileSystemLoader(directory_path))
|
|
|
|
|
|
|
|
|
|
self.calculate_extension = CalculateExtension(
|
|
|
|
|
self.environment,
|
|
|
|
|
datavars_module=datavars_module)
|
|
|
|
|
|
|
|
|
|
self.environment.add_extension(self.calculate_extension)
|
|
|
|
|
|
|
|
|
|
self.environment.context_class = CalculateContext
|
|
|
|
|
|
|
|
|
|
def change_directory(self, directory_path):
|
|
|
|
@ -853,6 +908,8 @@ class TemplateEngine:
|
|
|
|
|
пути.'''
|
|
|
|
|
if parameters is not None:
|
|
|
|
|
self._parameters_object = parameters
|
|
|
|
|
else:
|
|
|
|
|
self._parameters_object = ParametersContainer()
|
|
|
|
|
|
|
|
|
|
if self._parameters_object.env:
|
|
|
|
|
CalculateContext._env_set = self._parameters_object.env.copy()
|
|
|
|
@ -862,12 +919,13 @@ class TemplateEngine:
|
|
|
|
|
self.parameters_processor._parameters_container =\
|
|
|
|
|
self._parameters_object
|
|
|
|
|
|
|
|
|
|
self.calculate_extension.template_type = template_type
|
|
|
|
|
|
|
|
|
|
template = self.environment.get_template(template_path)
|
|
|
|
|
self._template_text = template.render(
|
|
|
|
|
__datavars__=self._datavars_module,
|
|
|
|
|
__parameters__=self._parameters_object,
|
|
|
|
|
__template_type__=template_type,
|
|
|
|
|
__DIR__=DIR, __FILE__=FILE
|
|
|
|
|
Version=Version
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def process_template_from_string(self, string, template_type,
|
|
|
|
@ -875,6 +933,9 @@ class TemplateEngine:
|
|
|
|
|
'''Метод для обработки текста шаблона.'''
|
|
|
|
|
if parameters is not None:
|
|
|
|
|
self._parameters_object = parameters
|
|
|
|
|
else:
|
|
|
|
|
self._parameters_object = ParametersContainer(
|
|
|
|
|
parameters_dictionary={})
|
|
|
|
|
|
|
|
|
|
if self._parameters_object.env:
|
|
|
|
|
CalculateContext._env_set = self._parameters_object.env.copy()
|
|
|
|
@ -884,12 +945,12 @@ class TemplateEngine:
|
|
|
|
|
self.parameters_processor._parameters_container =\
|
|
|
|
|
self._parameters_object
|
|
|
|
|
|
|
|
|
|
self.calculate_extension.template_type = template_type
|
|
|
|
|
|
|
|
|
|
template = self.environment.from_string(string)
|
|
|
|
|
self._template_text = template.render(
|
|
|
|
|
__datavars__=self._datavars_module,
|
|
|
|
|
__parameters__=self._parameters_object,
|
|
|
|
|
__template_type__=template_type,
|
|
|
|
|
__DIR__=DIR, __FILE__=FILE,
|
|
|
|
|
Version=Version
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|