Browse Source

Added main Datavars module and its functionality is almost implemented.

packages
Иванов Денис 8 months ago
parent
commit
2e5946ed6e
66 changed files with 998 additions and 239 deletions
  1. +7
    -0
      calculate/templates/template_engine.py
  2. +14
    -13
      calculate/utils/gentoo.py
  3. +0
    -0
      calculate/variables/__init__.py
  4. +101
    -29
      calculate/variables/datavars.py
  5. +153
    -37
      calculate/variables/loader.py
  6. +0
    -0
      calculate/variables/old_vars/datavars.py
  7. +5
    -0
      calculate/variables/old_vars/main/__init__.py
  8. +0
    -0
      calculate/variables/old_vars/os/__init__.py
  9. +88
    -0
      calculate/variables/old_vars/os/gentoo/__init__.py
  10. +3
    -2
      calculate/variables/old_vars/vars_loader.py
  11. +6
    -4
      calculate/vars/main/__init__.py
  12. +72
    -81
      calculate/vars/os/gentoo/__init__.py
  13. +13
    -0
      calculate/vars/system/__init__.py
  14. +2
    -2
      pytest.ini
  15. +0
    -0
      tests/variables/__init__.py
  16. +17
    -11
      tests/variables/old_vars/old_vars.py
  17. +0
    -0
      tests/variables/old_vars/variables/__init__.py
  18. +0
    -0
      tests/variables/old_vars/variables/level/__init__.py
  19. +0
    -0
      tests/variables/old_vars/variables/level/level2/__init__.py
  20. +0
    -0
      tests/variables/old_vars/variables/main/__init__.py
  21. +0
    -0
      tests/variables/old_vars/variables/os/__init__.py
  22. +11
    -22
      tests/variables/test_calculateini.py
  23. +126
    -18
      tests/variables/test_variables.py
  24. +9
    -0
      tests/variables/testfiles/calculate_0.ini
  25. +0
    -0
      tests/variables/testfiles/gentoo.backup/portage/calculate.ini
  26. +0
    -0
      tests/variables/testfiles/gentoo.backup/portage/profiles/calculate.ini
  27. +2
    -0
      tests/variables/testfiles/gentoo.backup/portage/profiles/main/calculate.ini
  28. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/calculate.ini
  29. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/20/calculate.ini
  30. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/calculate.ini
  31. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/desktop/calculate.ini
  32. +3
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/desktop/parent
  33. +2
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/parent
  34. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/calculate.ini
  35. +1
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/parent
  36. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/calculate.ini
  37. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/desktop/calculate.ini
  38. +1
    -0
      tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/parent
  39. +2
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/amd64/calculate.ini
  40. +2
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/amd64/parent
  41. +21
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/calculate.ini
  42. +1
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/parent
  43. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/amd64/calculate.ini
  44. +2
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/amd64/parent
  45. +0
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/calculate.ini
  46. +1
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/parent
  47. +3
    -0
      tests/variables/testfiles/gentoo.backup/repos/distros/profiles/calculate.ini
  48. +0
    -0
      tests/variables/testfiles/variables_0/__init__.py
  49. +6
    -0
      tests/variables/testfiles/variables_0/main/__init__.py
  50. +2
    -2
      tests/variables/testfiles/variables_0/os/__init__.py
  51. +3
    -3
      tests/variables/testfiles/variables_1/level/__init__.py
  52. +1
    -1
      tests/variables/testfiles/variables_1/level/level_2/__init__.py
  53. +4
    -0
      tests/variables/testfiles/variables_1/main/__init__.py
  54. +5
    -3
      tests/variables/testfiles/variables_1/os/__init__.py
  55. +4
    -0
      tests/variables/testfiles/variables_2/main/__init__.py
  56. +38
    -0
      tests/variables/testfiles/variables_2/os/__init__.py
  57. +57
    -0
      tests/variables/testfiles/variables_2/os/gentoo/__init__.py
  58. +4
    -0
      tests/variables/testfiles/variables_3/main/__init__.py
  59. +38
    -0
      tests/variables/testfiles/variables_3/os/__init__.py
  60. +57
    -0
      tests/variables/testfiles/variables_3/os/gentoo/__init__.py
  61. +62
    -0
      tests/variables/testfiles/variables_4/level/__init__.py
  62. +7
    -0
      tests/variables/testfiles/variables_4/level/level_2/__init__.py
  63. +4
    -0
      tests/variables/testfiles/variables_4/main/__init__.py
  64. +38
    -0
      tests/variables/testfiles/variables_4/os/__init__.py
  65. +0
    -6
      tests/vars/testfiles/variables_0/main/__init__.py
  66. +0
    -5
      tests/vars/testfiles/variables_1/main/__init__.py

+ 7
- 0
calculate/templates/template_engine.py View File

@@ -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'):


+ 14
- 13
calculate/utils/gentoo.py View File

@@ -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

calculate/vars/__init__.py → calculate/variables/__init__.py View File


calculate/vars/alt_datavars.py → calculate/variables/datavars.py View File

@@ -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

calculate/vars/alt_vars_loader.py → calculate/variables/loader.py View File

@@ -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])")

calculate/vars/datavars.py → calculate/variables/old_vars/datavars.py View File


+ 5
- 0
calculate/variables/old_vars/main/__init__.py View File

@@ -0,0 +1,5 @@
from calculate.vars.datavars import Variable, ReadonlyVariable

class Chroot(Variable):
properties = [ReadonlyVariable]
value = "/"

tests/vars/__init__.py → calculate/variables/old_vars/os/__init__.py View File


+ 88
- 0
calculate/variables/old_vars/os/gentoo/__init__.py View File

@@ -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()

calculate/vars/vars_loader.py → calculate/variables/old_vars/vars_loader.py View File

@@ -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

+ 6
- 4
calculate/vars/main/__init__.py View File

@@ -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='/')

+ 72
- 81
calculate/vars/os/gentoo/__init__.py View File

@@ -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))

+ 13
- 0
calculate/vars/system/__init__.py View File

@@ -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())

+ 2
- 2
pytest.ini View File

@@ -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.


tests/vars/testfiles/variables_0/__init__.py → tests/variables/__init__.py View File


tests/vars/test_namespace.py → tests/variables/old_vars/old_vars.py View File

@@ -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()

tests/vars/variables/__init__.py → tests/variables/old_vars/variables/__init__.py View File


tests/vars/variables/level/__init__.py → tests/variables/old_vars/variables/level/__init__.py View File


tests/vars/variables/level/level2/__init__.py → tests/variables/old_vars/variables/level/level2/__init__.py View File


tests/vars/variables/main/__init__.py → tests/variables/old_vars/variables/main/__init__.py View File


tests/vars/variables/os/__init__.py → tests/variables/old_vars/variables/os/__init__.py View File


tests/utils/test_calculateini.py → tests/variables/test_calculateini.py View File

@@ -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'],)}
]


tests/vars/test_alt_vars.py → tests/variables/test_variables.py View File

@@ -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'))

+ 9
- 0
tests/variables/testfiles/calculate_0.ini View File

@@ -0,0 +1,9 @@
[main]
chroot = /any/other/path

[level]
simple = weird value

[os][linux]
fullname = full_name
shortname = SN

+ 0
- 0
tests/variables/testfiles/gentoo.backup/portage/calculate.ini View File


+ 0
- 0
tests/variables/testfiles/gentoo.backup/portage/profiles/calculate.ini View File


+ 2
- 0
tests/variables/testfiles/gentoo.backup/portage/profiles/main/calculate.ini View File

@@ -0,0 +1,2 @@
[main]
chroot = /any/other/path

+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/calculate.ini View File


+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/20/calculate.ini View File


+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/calculate.ini View File


+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/desktop/calculate.ini View File


+ 3
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/desktop/parent View File

@@ -0,0 +1,3 @@
gentoo:main
..
../../../desktop

+ 2
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/20/parent View File

@@ -0,0 +1,2 @@
..
../../20

+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/calculate.ini View File


+ 1
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/amd64/parent View File

@@ -0,0 +1 @@
..

+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/calculate.ini View File


+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/desktop/calculate.ini View File


+ 1
- 0
tests/variables/testfiles/gentoo.backup/repos/calculate/profiles/default/parent View File

@@ -0,0 +1 @@
..

+ 2
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/amd64/calculate.ini View File

@@ -0,0 +1,2 @@
[os][linux]
arch = amd64

+ 2
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/amd64/parent View File

@@ -0,0 +1,2 @@
calculate:default/amd64/20/desktop
..

+ 21
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/calculate.ini View File

@@ -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

+ 1
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLD/parent View File

@@ -0,0 +1 @@
..

+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/amd64/calculate.ini View File


+ 2
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/amd64/parent View File

@@ -0,0 +1,2 @@
calculate:default/amd64/20/desktop
..

+ 0
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/calculate.ini View File


+ 1
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/CLDX/parent View File

@@ -0,0 +1 @@
..

+ 3
- 0
tests/variables/testfiles/gentoo.backup/repos/distros/profiles/calculate.ini View File

@@ -0,0 +1,3 @@
[os][linux]
shortname = Calculate
test = test

+ 0
- 0
tests/variables/testfiles/variables_0/__init__.py View File


+ 6
- 0
tests/variables/testfiles/variables_0/main/__init__.py View File

@@ -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)

tests/vars/testfiles/variables_0/os/__init__.py → tests/variables/testfiles/variables_0/os/__init__.py View File

@@ -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)

tests/vars/testfiles/variables_1/level/__init__.py → tests/variables/testfiles/variables_1/level/__init__.py View File

@@ -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')

tests/vars/testfiles/variables_1/level/level_2/__init__.py → tests/variables/testfiles/variables_1/level/level_2/__init__.py View File

@@ -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,

+ 4
- 0
tests/variables/testfiles/variables_1/main/__init__.py View File

@@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType


Variable('chroot', type=StringType.readonly, source='/')

tests/vars/testfiles/variables_1/os/__init__.py → tests/variables/testfiles/variables_1/os/__init__.py View File

@@ -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": "/"},

+ 4
- 0
tests/variables/testfiles/variables_2/main/__init__.py View File

@@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType


Variable('chroot', type=StringType, source='/')

+ 38
- 0
tests/variables/testfiles/variables_2/os/__init__.py View File

@@ -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"}])

+ 57
- 0
tests/variables/testfiles/variables_2/os/gentoo/__init__.py View File

@@ -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")}])

+ 4
- 0
tests/variables/testfiles/variables_3/main/__init__.py View File

@@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType


Variable('chroot', type=StringType, source='/')

+ 38
- 0
tests/variables/testfiles/variables_3/os/__init__.py View File

@@ -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"}])

+ 57
- 0
tests/variables/testfiles/variables_3/os/gentoo/__init__.py View File

@@ -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")}])

+ 62
- 0
tests/variables/testfiles/variables_4/level/__init__.py View File

@@ -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')

+ 7
- 0
tests/variables/testfiles/variables_4/level/level_2/__init__.py View File

@@ -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)))

+ 4
- 0
tests/variables/testfiles/variables_4/main/__init__.py View File

@@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType


Variable('chroot', type=StringType, source='/')

+ 38
- 0
tests/variables/testfiles/variables_4/os/__init__.py View File

@@ -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
- 6
tests/vars/testfiles/variables_0/main/__init__.py View File

@@ -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)

+ 0
- 5
tests/vars/testfiles/variables_1/main/__init__.py View File

@@ -1,5 +0,0 @@
from calculate.vars.alt_datavars import Variable, StringType


Variable('chroot', type=StringType, source='/', readonly=True)
print('chroot really created')

Loading…
Cancel
Save