kiwi-scp/src/kiwi/config.py

94 lines
2.4 KiB
Python

import copy
import logging
import re
import os
import yaml
from ._constants import KIWI_ROOT, KIWI_CONF_NAME
###########
# CONSTANTS
HEADER_KIWI_CONF_NAME = f"{KIWI_ROOT}/kiwi_header.yml"
DEFAULT_KIWI_CONF_NAME = f"{KIWI_ROOT}/kiwi_default.yml"
VERSION_TAG_NAME = f"{KIWI_ROOT}/version-tag"
class Config:
__yml_content = {}
def __key_resolve(self, key):
# "a:b:c" => path = ['a', 'b'], key = 'c'
path = key.split(':')
path, key = path[:-1], path[-1]
# resolve path
container = self.__yml_content
for step in path:
container = container[step]
return container, key
def __getitem__(self, key):
container, key = self.__key_resolve(key)
return container[key]
def __setitem__(self, key, value):
container, key = self.__key_resolve(key)
container[key] = value
def __str__(self):
# dump yml content
yml_string = yaml.dump(self.__yml_content, default_flow_style=False, sort_keys=False)
# insert newline before every main key
yml_string = re.sub(r'^(\S)', r'\n\1', yml_string, flags=re.MULTILINE)
# load header comment from file
with open(HEADER_KIWI_CONF_NAME, 'r') as stream:
yml_string = stream.read() + yml_string
return yml_string
def _update_from_file(self, filename):
with open(filename, 'r') as stream:
try:
self.__yml_content.update(yaml.safe_load(stream))
except yaml.YAMLError as exc:
logging.error(exc)
def clone(self):
result = Config()
result.__yml_content = copy.deepcopy(self.__yml_content)
return result
def save(self):
with open(KIWI_CONF_NAME, 'w') as stream:
stream.write(str(self))
class DefaultConfig(Config):
__instance = None
@classmethod
def get(cls):
if cls.__instance is None:
cls.__instance = cls()
cls.__instance._update_from_file(DEFAULT_KIWI_CONF_NAME)
with open(VERSION_TAG_NAME, 'r') as stream:
cls.__instance["version"] = stream.read().strip()
return cls.__instance
class LoadedConfig(Config):
@classmethod
def get(cls):
result = DefaultConfig.get().clone()
if os.path.isfile(KIWI_CONF_NAME):
result._update_from_file(KIWI_CONF_NAME)
return result