Added main Datavars module and its functionality is almost implemented.

packages
Иванов Денис 4 jaren geleden
bovenliggende 632b88b79f
commit 2e5946ed6e

@ -159,6 +159,7 @@ class ParametersProcessor:
def check_template_parameter(self, parameter_name, parameter_value,
template_type, lineno):
'''Метод, проверяющий указанный параметр.'''
self.lineno = lineno
self.template_type = template_type
@ -191,6 +192,7 @@ class ParametersProcessor:
{parameter_name: checked_value})
def check_postparse_parameters(self):
'''Метод, запускающий проверку параметров после их разбора.'''
for parameter, parameter_checker in\
self.postparse_checkers_list.items():
if parameter not in self._parameters_container:
@ -200,6 +202,7 @@ class ParametersProcessor:
parameter_checker(parameter_value)
def check_template_parameters(self, parameters, template_type, lineno):
'''Метод, запускающий проверку указанных параметров.'''
self.template_type = template_type
self.lineno = lineno
@ -230,6 +233,8 @@ class ParametersProcessor:
self._parameters_container.set_parameter(
parameter_name=checked_value)
# Методы для проверки параметров во время разбора шаблона.
def check_package_parameter(self, parameter_value):
try:
atom_object = self.package_atom_parser.parse_package_parameter(
@ -774,6 +779,8 @@ class CalculateExtension(Extension):
'''Метод для разбора тега save, сохраняющего значение указанной
переменной datavars.'''
lineno = next(self.stream).lineno
# Целового файла больше не будет.
target_file = nodes.Const('', lineno=lineno)
if self.stream.skip_if('dot'):

@ -1,30 +1,31 @@
import os
import re
import calculate.utils.fs as fs
from calculate.utils.files import read_file_lines
class ProfileWalker:
"""
Объект обходящий все директории профиля через parent файлы
"""
'''Объект обходящий все директории профиля через parent файлы.'''
def __init__(self, filename, repositories):
self.repositories = repositories
self.filename = filename
self.reReppath = re.compile("^({0})+:".format(
self.re_reppath = re.compile("^({0})+:".format(
"|".join(self.repositories.keys())))
def interpolate(self, path):
def subfunc(m):
return "{0}/profiles/".format(self.repositories.get(m.group(1)))
return self.reReppath.sub(subfunc, path)
return self.re_reppath.sub(subfunc, path)
def find(self, directory):
parent = os.path.join(directory, "parent")
for line in (x for x in fs.readFileLines(parent) if x.strip()):
parentdir = os.path.normpath(
os.path.join(directory, self.interpolate(line)))
if fs.exists(parentdir):
yield from self.find(parentdir)
'''Метод для поиска по профилю всех файлов с именем, указанным в
self.filename.'''
parent_file_path = os.path.join(directory, "parent")
for line in (parent_line for parent_line in
read_file_lines(parent_file_path) if parent_line.strip()):
parent_directory = os.path.normpath(
os.path.join(directory, self.interpolate(line)))
if os.path.exists(parent_directory):
yield from self.find(parent_directory)
findfile = os.path.normpath(os.path.join(directory, self.filename))
if fs.exists(findfile):
if os.path.exists(findfile):
yield findfile

@ -1,6 +1,6 @@
import ast
import dis
from typing import List, Union, Any
from typing import List, Any
from contextlib import contextmanager
from inspect import signature, getsource
from types import FunctionType, LambdaType
@ -36,9 +36,14 @@ class VariableType:
name = 'undefined'
@classmethod
def process_value(self, value, variable):
def process_value(cls, value, variable):
return value
@classmethod
def readonly(cls, variable_object) -> None:
variable_object.variable_type = cls
variable_object.readonly = True
class IniType(VariableType):
'''Класс, соответствующий типу переменных созданных в calculate.ini файлах.
@ -46,7 +51,7 @@ class IniType(VariableType):
name = 'ini'
@classmethod
def process_value(self, value, variable):
def process_value(cls, value, variable):
return value
@ -55,7 +60,7 @@ class StringType(VariableType):
name = 'string'
@classmethod
def process_value(self, value, variable) -> str:
def process_value(cls, value, variable) -> str:
if isinstance(value, str):
return value
else:
@ -73,7 +78,7 @@ class IntegerType(VariableType):
name = 'integer'
@classmethod
def process_value(self, value, variable) -> int:
def process_value(cls, value, variable) -> int:
if isinstance(value, int):
return value
else:
@ -91,7 +96,7 @@ class FloatType(VariableType):
name = 'float'
@classmethod
def process_value(self, value, variable) -> float:
def process_value(cls, value, variable) -> float:
if isinstance(value, float):
return value
else:
@ -111,13 +116,13 @@ class BooleanType(VariableType):
false_values = {'False', 'false'}
@classmethod
def process_value(self, value, variable) -> bool:
def process_value(cls, value, variable) -> bool:
if isinstance(value, bool):
return value
elif isinstance(value, str):
if value in self.true_values:
if value in cls.true_values:
return True
if value in self.false_values:
if value in cls.false_values:
return False
try:
return bool(value)
@ -132,7 +137,7 @@ class ListType(VariableType):
name = 'list'
@classmethod
def process_value(self, value, variable) -> list:
def process_value(cls, value, variable) -> list:
# TODO нормально все сделать.
if isinstance(value, list):
return value
@ -181,6 +186,7 @@ class Hash:
'''Класс реализующий контейнер для хранения хэша в переменной
соответствующего типа.'''
def __init__(self, values: dict, master_variable, parent=None):
self.fixed = master_variable.fixed
self._values = dict()
for key, value in values.items():
self._values.update({key: HashValue(key, value, master_variable,
@ -189,11 +195,27 @@ class Hash:
self.row_index = None
def get_hash(self) -> dict:
'''Метод для получения словаря из значений хэша.'''
dict_value = {}
for key in self._values.keys():
dict_value.update({key: self._values[key].get_value()})
return dict_value
def update_hash(self, values: dict) -> None:
'''Метод для обновления значения хэша.'''
print('UPDATE HASH')
for key, value in values.items():
if key in self._values:
self._values[key].value = value
elif self.fixed:
raise VariableError("key '{}' is unavailable for fixed"
" hash, available keys: '{}'".
format(key, ', '.join(self._fields)))
else:
self._values[key] = HashValue(key, value, self.master_variable,
self)
return self
def __getattr__(self, key: str):
'''Метод возвращает ноду пространства имен или значение переменной.'''
if key in self._values:
@ -226,12 +248,21 @@ class HashType(VariableType):
name = 'hash'
@classmethod
def process_value(self, value, variable) -> Hash:
if not isinstance(value, dict):
def process_value(cls, values, variable) -> Hash:
if not isinstance(values, dict):
raise VariableTypeError("can not set value with type '{_type}' to"
" hash variable: value must be 'dict' type"
.format(_type=type(value)))
return Hash(value, variable)
.format(_type=type(values)))
if variable.value is not None:
updated_hash = variable.value.update_hash(values)
else:
updated_hash = Hash(values, variable)
return updated_hash
@classmethod
def fixed(cls, variable_object) -> None:
variable_object.variable_type = cls
variable_object.fixed = True
class Table:
@ -487,8 +518,8 @@ class VariableNode:
# динамическом связывании.
self._subscriptions = set()
# Если значение переменной None -- значит она обнулена.
self.value = None
self._invalidated = True
# Источник значения переменной, может быть значением, а может быть
# зависимостью.
@ -501,6 +532,10 @@ class VariableNode:
self.set_by_user = False
self._readonly = False
# Флаг имеющий значение только для переменных типа HashType.
# Предназначен для включения проверки соответствия полей хэша при
# установке значения.
self._fixed = False
def update_value(self) -> None:
'''Метод для обновления значения переменной с помощью указанного
@ -537,6 +572,25 @@ class VariableNode:
value = self._source
self.value = self.variable_type.process_value(value, self)
self._invalidated = False
def set_variable_type(self, variable_type, readonly=None, fixed=None):
'''Метод для установки типа переменной.'''
if readonly is not None and isinstance(readonly, bool):
self._readonly = readonly
elif fixed is not None and isinstance(fixed, bool):
self._fixed = fixed
if self.variable_type is VariableType:
if isinstance(variable_type, type):
if issubclass(variable_type, VariableType):
self.variable_type = variable_type
else:
raise VariableError('variable type object must be'
' VariableType or its class method,'
' not {}'.format(type(variable_type)))
elif callable(variable_type):
variable_type(self)
def set(self, value):
self._invalidate()
@ -550,7 +604,8 @@ class VariableNode:
@source.setter
def source(self, source) -> None:
if self._readonly:
raise VariableError("can not change the variable '{}': read only")
raise VariableError("can not change the variable '{}': read only".
format(self.get_fullname()))
# Если источники не совпадают или текущее значение переменной было
# установлено пользователем, то инвалидируем переменную и меняем
@ -572,12 +627,22 @@ class VariableNode:
# self.update_value()
self._readonly = value
@property
def fixed(self) -> bool:
return self._fixed
@fixed.setter
def fixed(self, value) -> bool:
self._fixed = value
def _invalidate(self) -> None:
'''Метод для инвалидации данной переменной и всех зависящих от нее
переменных.'''
# print('{} is invalidated'.format(self.get_fullname()))
if self.value is not None and not self.set_by_user:
self.value = None
if not self._invalidated and not self.set_by_user:
if self.variable_type is not HashType:
self.value = None
self._invalidated = True
for subscriber in self.subscribers:
subscriber._invalidate()
@ -593,7 +658,7 @@ class VariableNode:
def get_value(self) -> Any:
'''Метод для получения значения переменной.'''
if self.value is None and not self.set_by_user:
if self._invalidated and not self.set_by_user:
self.update_value()
return self.value
@ -641,8 +706,8 @@ class NamespaceNode:
def clear(self):
'''Метод для очистки пространства имен. Очищает и пространства имен
и переменные. Предназначен только для использования в calculate.ini.'''
for namespace in self.namespaces:
namespace.clear()
for namespace_name in self.namespaces.keys():
self.namespaces[namespace_name].clear()
self.variables.clear()
self.namespaces.clear()
@ -653,7 +718,7 @@ class NamespaceNode:
else:
return self.name
def __getattr__(self, name: str) -> None:
def __getattr__(self, name: str):
'''Метод возвращает ноду пространства имен или значение переменной.'''
if name in self.namespaces:
return self.namespaces[name]
@ -747,14 +812,13 @@ class VariableAPI:
self.errors = []
def __call__(self, name: str, source=None, type=VariableType,
readonly=False, force=False):
readonly=False, fixed=False, force=False):
'''Метод для создания переменных внутри with Namespace('name').'''
if name not in self.current_namespace.variables:
print('CREATE VARIABLE: {}'.format('{}.{}'.format(
self.current_namespace.get_fullname(),
name)))
variable = VariableNode(name, self.current_namespace,
variable_type=type)
variable = VariableNode(name, self.current_namespace)
else:
print('MODIFY VARIABLE: {}'.format(name))
variable = self.current_namespace[name]
@ -770,7 +834,12 @@ class VariableAPI:
else:
variable.source = source
variable.readonly = readonly
if readonly:
variable.set_variable_type(type, readonly=True)
elif fixed:
variable.set_variable_type(type, fixed=True)
else:
variable.set_variable_type(type)
return variable
@ -798,15 +867,18 @@ class NamespaceAPI:
можно получить доступ к переменным.'''
return self._datavars
def set_root(self, datavars_root: NamespaceNode):
def set_datavars(self, datavars):
'''Метод для установки корневого пространства имен, которое пока что
будет использоваться для предоставления доступа к переменным.'''
self._datavars = datavars_root
self._datavars = datavars
self._variables_fabric.current_namespace = self._datavars
def reset(self):
'''Метод для сброса корневого пространства имен.'''
self._datavars = NamespaceNode('<root>')
if isinstance(self._datavars, NamespaceNode):
self._datavars = NamespaceNode('<root>')
else:
self._datavars.reset()
self.current_namespace = self._datavars
self._variables_fabric.current_namespace = self._datavars

@ -4,11 +4,12 @@ import os
import importlib
import importlib.util
import site
from calculate.vars.datavars import Variable, HashVariable, TableVariable
from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
ListType, IntegerType,\
FloatType, IniType, TableType,\
Namespace
from calculate.variables.old_vars.datavars import Variable, HashVariable,\
TableVariable
from calculate.variables.datavars import NamespaceNode, VariableNode,\
ListType, IntegerType,\
FloatType, IniType, TableType,\
Namespace, VariableError
from calculate.utils.gentoo import ProfileWalker
from calculate.utils.files import list_directory, read_file, FilesError
from pyparsing import Literal, Word, ZeroOrMore, Group, Optional, restOfLine,\
@ -182,17 +183,24 @@ class NamespaceIniFiller:
def start_section(self, sections: str) -> None:
'''Метод для получения доступа и создания пространств имен.'''
print('SECTIONS: {}'.format(sections))
if self.restricted:
self.modify_only = sections[0] not in self.available_sections
self.current_namespace = self.namespace
for section in sections:
if section not in self.current_namespace.namespaces:
if not self.modify_only:
self.current_namespace.add_namespace(
print('START SECTION: {}'.format(section))
if isinstance(self.current_namespace, Datavars):
if section not in self.current_namespace:
raise VariableError("variables package '{}' is not found".
format(section))
elif isinstance(self.current_namespace, NamespaceNode):
if section not in self.current_namespace.namespaces:
if not self.modify_only:
self.current_namespace.add_namespace(
NamespaceNode(section))
else:
self.current_namespace = None
return
else:
self.current_namespace = None
return
self.current_namespace = self.current_namespace.namespaces[section]
def clear_section(self, sections: list) -> None:
@ -202,18 +210,22 @@ class NamespaceIniFiller:
current_namespace = self.namespace
for section in sections:
if section in current_namespace.namespaces:
current_namespace = current_namespace.namespaces[section]
elif (section in current_namespace.variables and
current_namespace.variables[section].variable_type
is TableType):
table_variable = current_namespace.variables[section]
table_to_clear = table_variable.get_value()
table_to_clear.clear()
table_variable.source = table_to_clear
return
else:
return
if (isinstance(current_namespace, Datavars) and
section in current_namespace):
current_namespace = current_namespace[section]
elif isinstance(current_namespace, NamespaceNode):
if section in current_namespace.namespaces:
current_namespace = current_namespace[section]
elif (section in current_namespace.variables and
current_namespace.variables[section].variable_type
is TableType):
table_variable = current_namespace.variables[section]
table_to_clear = table_variable.get_value()
table_to_clear.clear()
table_variable.source = table_to_clear
return
else:
return
if not self.modify_only:
current_namespace.clear()
@ -249,6 +261,8 @@ class NamespaceIniFiller:
table_variable.source = table
def define_key(self, key: str, value: str, optype) -> None:
print('DEFINE KEY: {} -> {} TO {}'.format(key, value,
self.current_namespace))
if self.current_namespace is None:
return
@ -345,17 +359,35 @@ class NamespaceIniFiller:
class VariableLoader:
basename = "calculate.ini"
def load_variables(self, directory_path) -> NamespaceNode:
root = Namespace.datavars
package = '.'.join(directory_path.split('/'))
self._fill_from_package(root, directory_path, package)
return root
'''Класс загрузчика переменных из python-файлов и из ini-файлов.'''
ini_basename = "calculate.ini"
def __init__(self, datavars, variables_path, repository_map=None):
self.datavars = datavars
self.ini_filler = NamespaceIniFiller()
self.variables_path = variables_path
self.variables_package = '.'.join(variables_path.split('/'))
self.repository_map = repository_map
def load_variables_package(self, package_name: str) -> None:
'''Метод для загрузки пакетов с переменными.'''
directory_path = os.path.join(self.variables_path, package_name)
package = '{}.{}'.format(self.variables_package, package_name)
package_namespace = NamespaceNode(package_name)
self.datavars.root.add_namespace(package_namespace)
self._fill_from_package(package_namespace, directory_path, package)
def load_from_profile(self):
if self.repository_map != {}:
self.repository_map = (self.repository_map or
self._get_repository_map(self.datavars))
profile_path = self.datavars.os.gentoo.profile.path
self._fill_from_ini(profile_path)
def _fill_from_package(self, current_namespace: NamespaceNode,
directory_path: str, package: str) -> None:
print('FILL -> {}'.format(current_namespace))
'''Метод для зaполнения переменных из python-файла.'''
file_nodes = []
directory_nodes = []
# Просматриваем директорию
@ -385,21 +417,31 @@ class VariableLoader:
'{}.{}'.format(package,
directory_node.name))
def _fill_from_ini(self, datavars, profile_path):
ini_filler = NamespaceIniFiller()
profile_walker = ProfileWalker(self.basename,
self.get_repository_map(datavars))
def _fill_from_ini(self, profile_path):
'''Метод для зaполнения переменных из ini-файла.'''
print('PROCESSING INI FROM PROFILE')
profile_walker = ProfileWalker(self.ini_basename,
self.repository_map)
for file_path in profile_walker.find(profile_path):
try:
print('PROCESS FILE: {}'.format(file_path))
ini_file_text = read_file(file_path)
ini_filler.fill(datavars, ini_file_text)
self.ini_filler.fill(self.datavars, ini_file_text)
except FilesError:
# TODO продумать обработку ошибок.
pass
def get_repository_map(self, datavars):
def _get_repository_map(self, datavars):
return {repo['name']: repo['path']
for repo in datavars.os.gentoo.repositories}
def fill_from_custom_ini(self, file_path: str):
'''Метод для заполнения переменных из конкретного указанного файла.'''
print('LOAD FROM INI: {}'.format(file_path))
if os.path.exists(file_path):
ini_file_text = read_file(file_path)
self.ini_filler.fill(self.datavars, ini_file_text)
@contextmanager
def test(self, file_name, namespace):
print('IMPORT: {}.{}'.format(namespace.get_fullname(), file_name))
@ -410,6 +452,80 @@ class VariableLoader:
file_name))
class Datavars:
'''Класс для хранения переменных и управления ими.'''
def __init__(self, variables_path='calculate/vars', repository_map=None):
self._variables_path = variables_path
self._available_packages = self._get_available_packages()
self.root = NamespaceNode('<root>')
self._loader = VariableLoader(self, self._variables_path,
repository_map=repository_map)
Namespace.reset()
Namespace.set_datavars(self)
self._loader.load_from_profile()
def reset(self):
'''Метод для сброса модуля переменных.'''
self.root.clear()
self.root = NamespaceNode('<root>')
self._available_packages.clear()
self._available_packages = self._get_available_packages()
Namespace.set_datavars(self)
def _get_available_packages(self) -> dict:
'''Метод для получения словаря с имеющимися пакетами переменных
и путями к ним.'''
available_packages = dict()
for file_name in os.listdir(self._variables_path):
if file_name.startswith('__'):
continue
file_path = os.path.join(self._variables_path, file_name)
if os.path.isdir(file_path):
available_packages.update({file_name: file_path})
return available_packages
def __getattr__(self, package_name: str):
'''Метод возвращает ноду пространства имен, соответствующего искомому
пакету.'''
print('getattr: {}'.format(package_name))
if package_name in self.root.namespaces:
return self.root[package_name]
elif package_name not in self._available_packages:
raise VariableError("variables package '{}' is not found".
format(package_name))
else:
self._loader.load_variables_package(package_name)
return self.root[package_name]
def __getitem__(self, package_name: str) -> None:
'''Метод возвращает ноду пространства имен, соответствующего искомому
пакету.'''
print('getitem: {}'.format(package_name))
if package_name in self.root:
return self.root[package_name]
elif package_name not in self._available_packages:
raise VariableError("variables package '{}' is not found".
format(package_name))
else:
self._loader.load_variables_package(package_name)
return self.root[package_name]
def __contains__(self, package_name):
if package_name in self.root.namespaces:
return True
elif package_name not in self._available_packages:
return False
else:
self._loader.load_variables_package(package_name)
return True
@property
def namespaces(self):
return self.root.namespaces
class OldVariableLoader:
'''Класс, используемый для загрузки переменных из python модуля.'''
re_upper = re.compile("(.)([A-Z])")

@ -0,0 +1,5 @@
from calculate.vars.datavars import Variable, ReadonlyVariable
class Chroot(Variable):
properties = [ReadonlyVariable]
value = "/"

@ -0,0 +1,88 @@
from calculate.vars.datavars import Variable, ChoiceVariable, HashVariable, TableVariable, Namespace
from calculate.utils.files import stderr_devnull
import calculate.utils.fs as fs
import os
"""
gentoo
make_profile
profile.path
profile.name
repositories[*].name
repositories[*].path
config
"""
class MakeProfile(Variable):
"""
Путь до файла, указывающего на активный профиль
"""
value = '/etc/portage/make.profile'
class Profile(Namespace):
"""
Параметры текущего профиля
"""
class Path(Variable):
"""
Абсолютный путь до профиля
"""
def get(self):
make_profile = self.vars.parent.make_profile.getValue(self)
make_profile_dir = os.path.dirname(make_profile)
profileLink = fs.readlink(make_profile)
if profileLink:
profileLink = os.path.normpath(
os.path.join(make_profile_dir,profileLink))
return profileLink
else:
return ""
class Name(Variable):
"""
Название профиля
"""
def get(self):
profile_path = self.vars.path.getValue(self)
if not profile_path:
return ""
repositories = self.vars.parent.repositories
for rep in repositories:
reppath = rep.path.getValue(self)
repname = rep.name.getValue(self)
removepart = os.path.normpath(os.path.join(reppath,"profiles"))
if profile_path.startswith(removepart):
return "%s:%s"%(
repname,
profile_path[len(removepart)+1:])
return profile_path
class Repositories(TableVariable):
"""
Информация о репозиториях
name: имя репозитория
path: полный путь до репозитория
"""
class Data(TableVariable.Data):
def get(self):
config = self.vars.config.getValue(self)
return [
{
'name': name,
'path': path
}
for path, name in config.repositories.location_map.items()
]
hash_vars = ["name", "path"]
class Config(Variable):
"""
Объект текущей конфигурации Portage
"""
def get(self):
from portage.package.ebuild.config import config
chroot_path = self.vars.root.main.chroot.getValue(self)
if chroot_path == '/':
with stderr_devnull():
return config()

@ -4,8 +4,9 @@ import os
import importlib
import importlib.util
import site
from calculate.vars.datavars import Variable, Namespace, HashVariable,\
TableVariable, IniCreated, DefaultValue
from calculate.variables.old_vars.datavars import Variable, Namespace,\
HashVariable, TableVariable,\
IniCreated, DefaultValue
from calculate.utils.gentoo import ProfileWalker
from calculate.utils.fs import readFile
from calculate.utils.files import list_directory

@ -1,5 +1,7 @@
from calculate.vars.datavars import Variable, ReadonlyVariable
from calculate.variables.datavars import Variable, StringType
'''
main:
chroot -> string
'''
class Chroot(Variable):
properties = [ReadonlyVariable]
value = "/"
Variable('chroot', type=StringType.readonly, source='/')

@ -1,88 +1,79 @@
from calculate.vars.datavars import Variable, ChoiceVariable, HashVariable, TableVariable, Namespace
from calculate.utils.files import stderr_devnull
import calculate.utils.fs as fs
import os
from calculate.utils.files import stderr_devnull
from calculate.utils.files import read_link, FilesError
from calculate.variables.datavars import Variable, Namespace, Dependence,\
StringType, TableType
'''
gentoo:
make_profile -> string
profile:
path -> string
name -> string
repositories[*]{name, path} -> table
config -> undefined
'''
# Путь до файла, указывающего на активный профиль
Variable('make_profile', type=StringType, source='/etc/portage/make.profile')
# Параметры текущего профиля.
with Namespace('profile'):
def get_profile_link(make_profile):
make_profile_dir = os.path.dirname(make_profile.value)
try:
profile_link = read_link(make_profile)
except FilesError:
return ""
if profile_link:
profile_link = os.path.normpath(
os.path.join(make_profile_dir, profile_link))
return profile_link
else:
return ""
# Абсолютный путь до профиля
Variable('path', type=StringType,
source=Dependence('..make_profile', depend=get_profile_link))
def get_profile_name(path, repositories):
profile_path = path.value
if not profile_path:
return ""
for repository in repositories.value:
repository_path = repository['path']
repository_name = repository['name']
remove_part = os.path.normpath(os.path.join(repository_path,
"profiles"))
if profile_path.startswith(remove_part):
return "{}:{}".format(repository_name,
profile_path[len(remove_part) + 1:])
return profile_path
# Название профиля
Variable('name', type=StringType,
source=Dependence('.path', '..repositories',
depend=get_profile_link))
def get_repository_table(config):
return [{'name': name,
'path': path}
for path, name in config.value.repositories.location_map.items()]
"""
gentoo
make_profile
profile.path
profile.name
repositories[*].name
repositories[*].path
config
"""
class MakeProfile(Variable):
"""
Путь до файла, указывающего на активный профиль
"""
value = '/etc/portage/make.profile'
# Информация о репозиториях
# name: имя репозитория
# path: полный путь до репозитория
Variable('repositories', type=TableType,
source=Dependence('.config', depend=get_repository_table))
class Profile(Namespace):
"""
Параметры текущего профиля
"""
class Path(Variable):
"""
Абсолютный путь до профиля
"""
def get(self):
make_profile = self.vars.parent.make_profile.getValue(self)
make_profile_dir = os.path.dirname(make_profile)
profileLink = fs.readlink(make_profile)
if profileLink:
profileLink = os.path.normpath(
os.path.join(make_profile_dir,profileLink))
return profileLink
else:
return ""
class Name(Variable):
"""
Название профиля
"""
def get(self):
profile_path = self.vars.path.getValue(self)
if not profile_path:
return ""
repositories = self.vars.parent.repositories
for rep in repositories:
reppath = rep.path.getValue(self)
repname = rep.name.getValue(self)
removepart = os.path.normpath(os.path.join(reppath,"profiles"))
if profile_path.startswith(removepart):
return "%s:%s"%(
repname,
profile_path[len(removepart)+1:])
return profile_path
class Repositories(TableVariable):
"""
Информация о репозиториях
def get_config_object(chroot_path):
from portage.package.ebuild.config import config
if chroot_path.value == '/':
with stderr_devnull():
return config()
name: имя репозитория
path: полный путь до репозитория
"""
class Data(TableVariable.Data):
def get(self):
config = self.vars.config.getValue(self)
return [
{
'name': name,
'path': path
}
for path, name in config.repositories.location_map.items()
]
hash_vars = ["name", "path"]
class Config(Variable):
"""
Объект текущей конфигурации Portage
"""
def get(self):
from portage.package.ebuild.config import config
chroot_path = self.vars.root.main.chroot.getValue(self)
if chroot_path == '/':
with stderr_devnull():
return config()
# Объект текущей конфигурации Portage
Variable('config', source=Dependence('main.chroot', depend=get_config_object))

@ -0,0 +1,13 @@
from calculate.variables.datavars import Variable, ListType, HashType
'''
system:
env_order -> list
env_path -> hash
'''
# Список мест, где есть calculate.ini файлы.
Variable('env_order', type=ListType.readonly,
source=['grp', 'system', 'etc', 'local', 'remote'])
# Отображение множества мест, где есть calculate.ini файлы, на пути к ним.
Variable('env_path', type=HashType, source=dict())

@ -24,8 +24,8 @@ markers =
files_utils: marker for running tests for calculate.utils.files module.
package_utils: marker for running tests for calculate.utils.contents module.
vars: marker for running tests for datavars
alt_vars: marker for testing alternative version of the datavars module.
old_vars: marker for running tests for datavars
vars: marker for testing alternative version of the datavars module.
gentoo: marker for running tests for utils.gentoo
calculateini: marker for running tests for utils.calculateini
template_engine: marker for running tests for TemplateEngine.

@ -1,16 +1,22 @@
import pytest
import os
from calculate.vars.datavars import Namespace, Variable, CyclicVariableError,\
VariableError, ReadonlyVariable,\
ChoiceVariable, IntegerVariable,\
StringVariable, DefaultValue,\
TableVariable, HashVariable,\
VariableNotFoundError
from calculate.vars.vars_loader import NamespaceIniFiller, VariableLoader,\
ProfileFiller, NamespaceIniFillerStrict
@pytest.mark.vars
from calculate.variables.old_vars.datavars import Namespace, Variable,\
CyclicVariableError,\
VariableError,\
ReadonlyVariable,\
ChoiceVariable,\
IntegerVariable,\
StringVariable,\
DefaultValue,\
TableVariable, HashVariable,\
VariableNotFoundError
from calculate.variables.old_vars.vars_loader import NamespaceIniFiller,\
VariableLoader,\
ProfileFiller,\
NamespaceIniFillerStrict
@pytest.mark.old_vars
class TestNamespace:
def test_init_empty_namespace(self):
ns = Namespace()

@ -1,9 +1,8 @@
import pytest
from calculate.vars.vars_loader import CalculateIniParser, Define
from calculate.variables.loader import CalculateIniParser, Define
@pytest.mark.vars
@pytest.mark.calculateini
class TestCalculateIni:
def test_empty_calculate_ini(self):
pass
@ -17,8 +16,7 @@ class TestCalculateIni:
"varval1 = value1\n")
parsed_lines = [{'start_section': (['section'],)},
{'define_key': (['section'], 'varval1',
'value1', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
]
parse_result = list(ini_parser.parse(input_text))
@ -35,12 +33,9 @@ class TestCalculateIni:
"varval3 -= value3\n")
parsed_lines = [{'start_section': (['section'],)},
{'define_key': (['section'], 'varval1',
'value1', Define.assign)},
{'define_key': (['section'], 'varval2',
'value2', Define.append)},
{'define_key': (['section'], 'varval3',
'value3', Define.remove)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'define_key': ('varval2', 'value2', Define.append)},
{'define_key': ('varval3', 'value3', Define.remove)},
]
parse_result = list(ini_parser.parse(input_text))
@ -60,16 +55,12 @@ class TestCalculateIni:
"varval1 = value1\n")
parsed_lines = [{'start_section': (['section', 'sub'],)},
{'define_key': (['section', 'sub'],
'varval1', 'value1', Define.assign)},
{'define_key': (['section', 'sub'],
'varval2', 'value2', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'define_key': ('varval2', 'value2', Define.assign)},
{'start_section': (['section', 'sub2'],)},
{'define_key': (['section', 'sub2'],
'varval1', 'value1', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'start_section': (['section2'],)},
{'define_key': (['section2'], 'varval1',
'value1', Define.assign)}]
{'define_key': ('varval1', 'value1', Define.assign)}]
parse_result = list(ini_parser.parse(input_text))
for parsed_line, result_line in zip(parsed_lines, parse_result):
@ -92,10 +83,8 @@ class TestCalculateIni:
"[section][][sub][]\n")
parsed_lines = [{'start_section': (['section', 'sub2'],)},
{'define_key': (['section', 'sub2'],
'varval1', 'value1', Define.assign)},
{'define_key': (['section', 'sub2'],
'varval4', 'value4', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'define_key': ('varval4', 'value4', Define.assign)},
{'clear_section': (['section'],)}
]

@ -1,15 +1,22 @@
import os
import shutil
import pytest
from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
Namespace, Variable, Dependence,\
CyclicVariableError, HashType,\
StringType, IntegerType, VariableType,\
VariableError, TableType, BooleanType,\
VariableTypeError, FloatType, ListType
from calculate.vars.alt_vars_loader import NamespaceIniFiller, VariableLoader
from calculate.variables.datavars import NamespaceNode, VariableNode,\
Namespace, Variable, Dependence,\
CyclicVariableError, HashType,\
StringType, IntegerType,\
VariableType, VariableError,\
TableType, BooleanType,\
VariableTypeError, FloatType,\
ListType
from calculate.variables.loader import NamespaceIniFiller, Datavars
from calculate.utils.files import stderr_devnull
@pytest.mark.alt_vars
TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles')
@pytest.mark.vars
class TestNamespace:
# Сначала тестируем классы и методы необходимые для построения дерева
# переменных и пространств имен.
@ -364,7 +371,7 @@ class TestNamespace:
Namespace.reset()
with Namespace('namespace_1'):
Variable('var_1', source='value_1', type=StringType, readonly=True)
Variable('var_1', source='value_1', type=StringType.readonly)
with Namespace('namespace_1'):
with pytest.raises(VariableError):
@ -520,6 +527,47 @@ class TestNamespace:
assert datavars.namespace_1.var_4.key_2 == 'other_value'
assert datavars.namespace_1.var_4.key_3 == 'another_value'
def test_if_hash_variable_is_created_as_not_fixed_and_then_changed_using_dictionary_with_a_new_key__the_hash_adds_a_new_key_to_the_first_hash(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', type=HashType, source={'key_1': 'value_1',
'key_2': 'value_2'})
assert datavars.namespace_1.var_1.key_1 == 'value_1'
assert datavars.namespace_1.var_1.key_2 == 'value_2'
with Namespace('namespace_1'):
Variable('var_1', source={'key_1': 'another_value',
'key_2': 'other_value',
'key_3': 'new_value'})
assert datavars.namespace_1.var_1.key_1 == 'another_value'
assert datavars.namespace_1.var_1.key_2 == 'other_value'
assert datavars.namespace_1.var_1.key_3 == 'new_value'
def test_if_hash_variable_is_created_as_fixed_and_then_changed_using_dictionary_with_a_new_key__the_hash_raises_the_VariableError_exception(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', type=HashType.fixed, source={'key_1': 'value_1',
'key_2': 'value_2'})
assert datavars.namespace_1.var_1.key_1 == 'value_1'
assert datavars.namespace_1.var_1.key_2 == 'value_2'
with Namespace('namespace_1'):
Variable('var_1', source={'key_1': 'another_value',
'key_2': 'other_value',
'key_3': 'new_value'})
assert datavars.namespace_1['var_1'].fixed
with pytest.raises(VariableError):
datavars.namespace_1.var_1.key_1
def test_if_variable_is_created_with_dependence_and_one_of_arguments_of_a_depend_function_is_whole_hash__the_variable_will_set_this_argument_as_dictionary_of_the_whole_hash_in_a_depend_function(self):
Namespace.reset()
datavars = Namespace.datavars
@ -568,7 +616,7 @@ class TestNamespace:
datavars = Namespace.datavars
with Namespace('main'):
Variable('chroot', source='/', type=StringType, readonly=True)
Variable('chroot', source='/', type=StringType.readonly)
with Namespace('os'):
def source_function(chroot_path):
@ -901,22 +949,33 @@ value = another_value
{'name': 'common_name', 'value': 'another_value'},
{'name': 'name_3', 'value': 'value_3'}]
def test_loader(self):
Namespace.reset()
loader = VariableLoader()
datavars = loader.load_variables('tests/vars/testfiles/variables_0')
def test_if_a_Datavars_object_is_created_with_path_to_the_variables_without_any_Dependencies_and_then_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self):
datavars = Datavars(
variables_path='tests/variables/testfiles/variables_0',
repository_map={})
assert datavars.os.ns.var_1 == 'value_1'
assert datavars.os.ns.var_2 == 2
assert 'main' not in datavars.root
assert datavars.main.strange_variable == 'weird_value'
assert datavars.main.plain_variable is True
assert 'main' in datavars.root
def test_loader_2(self):
Namespace.reset()
loader = VariableLoader()
datavars = loader.load_variables('tests/vars/testfiles/variables_1')
def test_if_a_Datavars_object_is_created_with_path_to_the_variables_with_some_Dependencies_and_then_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self):
datavars = Datavars(
variables_path='tests/variables/testfiles/variables_1',
repository_map={})
assert datavars.main.chroot == '/'
assert 'os' not in datavars.root
assert datavars.os.calculate == 'test1 test2'
assert 'os' in datavars.root
assert datavars.level.level_2.vargetter == '/ test'
assert 'main' in datavars.root
assert datavars.level.simple == "simple value"
assert datavars.level.use_local_simple == "Using simple value"
assert datavars.level.use_full_simple == "Using simple value"
@ -927,3 +986,52 @@ value = another_value
{"dev": "/dev/sdb",
"type": "flash",
"name": "Transcend 64GB"}]
def test_if_a_Datavars_object_is_created_with_path_to_the_variables_with_Dependencies_and_then_the_variables_are_changed_using_calculate_ini_files_and_the_datavars_object_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self):
datavars = Datavars(
variables_path='tests/variables/testfiles/variables_4',
repository_map={})
assert datavars.main.chroot == '/'
assert 'os' not in datavars.root
assert datavars.level.level_2.vargetter == '/ test'
assert 'main' in datavars.root
assert datavars.level.simple == "simple value"
datavars._loader.fill_from_custom_ini(os.path.join(TESTFILES_PATH,
'calculate_0.ini'))
assert 'os' in datavars.root
assert datavars.level.simple == 'weird value'
assert datavars.main.chroot == '/any/other/path'
assert datavars.level.level_2.vargetter == '/any/other/path test'
def test_to_make_testfiles(self):
shutil.copytree(os.path.join(TESTFILES_PATH, 'gentoo.backup'),
os.path.join(TESTFILES_PATH, 'gentoo'),
symlinks=True)
def test_ini_loader(self):
repository_map = {'distros': os.path.join(TESTFILES_PATH,
"gentoo/repos/distros"),
'calculate': os.path.join(TESTFILES_PATH,
"gentoo/repos/calculate"),
'gentoo': os.path.join(TESTFILES_PATH,
"gentoo/portage")}
datavars = Datavars(
variables_path=os.path.join(TESTFILES_PATH, 'variables_2'),
repository_map=repository_map)
def test_get_repository_map(self):
datavars = Datavars(
variables_path=os.path.join(TESTFILES_PATH, 'variables_3'))
print('LOADING IS DONE')
print('hashvar.value1 = {}'.format(datavars.os.hashvar.value1))
print('hashvar.value2 = {}'.format(datavars.os.hashvar.value2))
assert False
def test_for_removing_testfile(self):
shutil.rmtree(os.path.join(TESTFILES_PATH, 'gentoo'))

@ -0,0 +1,9 @@
[main]
chroot = /any/other/path
[level]
simple = weird value
[os][linux]
fullname = full_name
shortname = SN

@ -0,0 +1,21 @@
[os][linux]
ver = 20
shortname = CLD
fullname = Calculate Linux Desktop
subname = KDE
[os][hashvar]
value1 = 20
value2 = 30
[os][tablevar][0]
dev = /dev/sda1
mount = swap
[os][tablevar][1]
dev = /dev/sda2
mount = /
[os][tablevar][2]
dev = /dev/sda5
mount = /var/calculate

@ -0,0 +1,6 @@
from calculate.variables.datavars import Namespace, Variable, StringType,\
IntegerType, BooleanType
Variable('strange_variable', source='weird_value', type=StringType)
Variable('plain_variable', source=True, type=BooleanType)

@ -1,5 +1,5 @@
from calculate.vars.alt_datavars import Namespace, Variable, StringType,\
IntegerType
from calculate.variables.datavars import Namespace, Variable, StringType,\
IntegerType
with Namespace('ns'):
Variable('var_1', source='value_1', type=StringType)

@ -1,6 +1,6 @@
from calculate.vars.alt_datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType,\
ListType, FloatType
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType,\
ListType, FloatType
Variable('simple', type=StringType, source='simple value')

@ -1,4 +1,4 @@
from calculate.vars.alt_datavars import Variable, StringType, Dependence
from calculate.variables.datavars import Variable, StringType, Dependence
Variable('vargetter', type=StringType,

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType.readonly, source='/')

@ -1,4 +1,4 @@
from calculate.vars.alt_datavars import Namespace, Variable, Dependence,\
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
@ -27,8 +27,10 @@ Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=lambda hashvar: "{} {}".format(hashvar.value['value1'],
hashvar.value['value2']))
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType, source='/')

@ -0,0 +1,38 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
Variable('shortname', source='', type=StringType)
Variable('ver', source='', type=StringType)
Variable('fullname', source='', type=StringType)
Variable('subname', source='', type=StringType)
Variable('arch', source='', type=StringType)
Variable('test', source='', type=StringType)
def get_title(subname, fullname, ver):
if subname.value:
return '{} {} {}'.format(fullname.value, subname.value, ver.value)
else:
return '{} {}'.format(fullname.value, ver.value)
Variable('title', type=StringType,
source=Dependence('.subname', '.fullname', '.ver',
depend=get_title))
Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},
{"dev": "/dev/sdb2",
"mount": "/var/calculate"}])

@ -0,0 +1,57 @@
import os
from calculate.variables.datavars import Variable, Namespace, Dependence,\
StringType, TableType
'''
gentoo:
make_profile -> string
profile:
path -> string
name -> string
repositories[*]{name, path} -> table
config -> undefined
'''
TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles')
# Путь до файла, указывающего на активный профиль
Variable('make_profile', type=StringType, source='/etc/portage/make.profile')
# Параметры текущего профиля.
with Namespace('profile'):
# Абсолютный путь до профиля
Variable('path', type=StringType,
source=os.path.join(TESTFILES_PATH,
"gentoo/repos/distros/profiles/CLD/amd64"))
def get_profile_name(path, repositories):
profile_path = path.value
if not profile_path:
return ""
for repository in repositories.value:
repository_path = repository['path']
repository_name = repository['name']
remove_part = os.path.normpath(os.path.join(repository_path,
"profiles"))
if profile_path.startswith(remove_part):
return "{}:{}".format(repository_name,
profile_path[len(remove_part) + 1:])
return profile_path
# Название профиля
Variable('name', type=StringType,
source=Dependence('.path', '..repositories',
depend=get_profile_name))
# Информация о репозиториях
# name: имя репозитория
# path: полный путь до репозитория
Variable('repositories', type=TableType,
source=[{'name': 'distros',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/distros")},
{'name': 'calculate',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/calculate")},
{'name': 'gentoo',
'path': os.path.join(TESTFILES_PATH,
"gentoo/portage")}])

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType, source='/')

@ -0,0 +1,38 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
Variable('shortname', source='', type=StringType)
Variable('ver', source='', type=StringType)
Variable('fullname', source='', type=StringType)
Variable('subname', source='', type=StringType)
Variable('arch', source='', type=StringType)
Variable('test', source='', type=StringType)
def get_title(subname, fullname, ver):
if subname.value:
return '{} {} {}'.format(fullname.value, subname.value, ver.value)
else:
return '{} {}'.format(fullname.value, ver.value)
Variable('title', type=StringType,
source=Dependence('.subname', '.fullname', '.ver',
depend=get_title))
Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},
{"dev": "/dev/sdb2",
"mount": "/var/calculate"}])

@ -0,0 +1,57 @@
import os
from calculate.variables.datavars import Variable, Namespace, Dependence,\
StringType, TableType
'''
gentoo:
make_profile -> string
profile:
path -> string
name -> string
repositories[*]{name, path} -> table
config -> undefined
'''
TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles')
# Путь до файла, указывающего на активный профиль
Variable('make_profile', type=StringType, source='/etc/portage/make.profile')
# Параметры текущего профиля.
with Namespace('profile'):
# Абсолютный путь до профиля
Variable('path', type=StringType,
source=os.path.join(TESTFILES_PATH,
"gentoo/repos/distros/profiles/CLD/amd64"))
def get_profile_name(path, repositories):
profile_path = path.value
if not profile_path:
return ""
for repository in repositories.value:
repository_path = repository['path']
repository_name = repository['name']
remove_part = os.path.normpath(os.path.join(repository_path,
"profiles"))
if profile_path.startswith(remove_part):
return "{}:{}".format(repository_name,
profile_path[len(remove_part) + 1:])
return profile_path
# Название профиля
Variable('name', type=StringType,
source=Dependence('.path', '..repositories',
depend=get_profile_name))
# Информация о репозиториях
# name: имя репозитория
# path: полный путь до репозитория
Variable('repositories', type=TableType,
source=[{'name': 'distros',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/distros")},
{'name': 'calculate',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/calculate")},
{'name': 'gentoo',
'path': os.path.join(TESTFILES_PATH,
"gentoo/portage")}])

@ -0,0 +1,62 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType,\
ListType, FloatType
Variable('simple', type=StringType, source='simple value')
Variable('use_local_simple', type=StringType,
source=Dependence('.simple',
depend=lambda simple: 'Using {}'.format(
simple.value)))
Variable('use_full_simple', type=StringType,
source=Dependence('level.simple',
depend=lambda simple: 'Using {}'.format(
simple.value)))
Variable('disks', type=ListType,
source=["/dev/sda1", "/dev/sda2", "/dev/sda3"])
Variable('version', type=FloatType, source='1.0')
Variable('my_shortname', type=StringType, source='CLD')
Variable('linux', type=HashType,
source=Dependence('.version', '.my_shortname',
depend=lambda version, my_shortname:
{'version': version.value,
'shortname': my_shortname.value}))
Variable('shortname_test', type=StringType,
source=Dependence('.linux.shortname',
depend=lambda shortname: '{} test'.format(
shortname.value)))
Variable('device_list', type=ListType,
source=["/dev/sda", "/dev/sdb"])
def get_device_table(device_list):
map_data = {'/dev/sda': ["hdd", "Samsung SSD"],
'/dev/sdb': ["flash", "Transcend 64GB"],
'/dev/sdc': ["usbhdd", "WD 1TB"]}
default_value = ["hdd", "Unknown"]
print('device_list = {}'.format(device_list.value))
return [{"dev": device,
"type": map_data.get(device, default_value)[0],
"name": map_data.get(device, default_value)[1]}
for device in device_list.value]
Variable('device', type=TableType, source=Dependence('.device_list',
depend=get_device_table))
Variable('device_child', type=StringType,
source=Dependence('.device',
depend=lambda device: device.value[0]['type']))
with Namespace('level_3'):
Variable('my_var_1', type=StringType, source='testing')
Variable('my_var_2', type=StringType, source='testing_2')

@ -0,0 +1,7 @@
from calculate.variables.datavars import Variable, StringType, Dependence
Variable('vargetter', type=StringType,
source=Dependence('main.chroot',
depend=lambda chroot:
'{} test'.format(chroot.value)))

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType, source='/')

@ -0,0 +1,38 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
Variable('shortname', source='', type=StringType)
Variable('ver', source='', type=StringType)
Variable('fullname', source='', type=StringType)
Variable('subname', source='', type=StringType)
Variable('arch', source='', type=StringType)
Variable('test', source='', type=StringType)
def get_title(subname, fullname, ver):
if subname.value:
return '{} {} {}'.format(fullname.value, subname.value, ver.value)
else:
return '{} {}'.format(fullname.value, ver.value)
Variable('title', type=StringType,
source=Dependence('.subname', '.fullname', '.ver',
depend=get_title))
Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},
{"dev": "/dev/sdb2",
"mount": "/var/calculate"}])

@ -1,6 +0,0 @@
from calculate.vars.alt_datavars import Namespace, Variable, StringType,\
IntegerType, BooleanType
Variable('strange_variable', source='weird_value', type=StringType)
Variable('plain_variable', source=True, type=BooleanType)

@ -1,5 +0,0 @@
from calculate.vars.alt_datavars import Variable, StringType
Variable('chroot', type=StringType, source='/', readonly=True)
print('chroot really created')
Laden…
Annuleren
Opslaan