2020-08-06 11:43:45 +00:00
|
|
|
import logging
|
2020-08-06 01:45:12 +00:00
|
|
|
import re
|
2020-08-06 12:34:25 +00:00
|
|
|
import os
|
2020-08-04 18:24:19 +00:00
|
|
|
import yaml
|
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
from .core import KIWI_ROOT, KIWI_CONF_NAME
|
2020-08-04 18:24:19 +00:00
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
###########
|
|
|
|
# CONSTANTS
|
2020-08-04 14:52:30 +00:00
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
DEFAULT_KIWI_CONF_NAME = KIWI_ROOT + "/default.kiwi.yml"
|
2020-08-08 17:41:11 +00:00
|
|
|
VERSION_TAG_NAME = KIWI_ROOT + "/version-tag"
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-04 14:52:30 +00:00
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
class Config:
|
|
|
|
__yml_content = {}
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
def __key_resolve(self, key):
|
2020-08-05 00:08:55 +00:00
|
|
|
# "a:b:c" => path = ['a', 'b'], key = 'c'
|
|
|
|
path = key.split(':')
|
2020-08-06 01:45:12 +00:00
|
|
|
path, key = path[:-1], path[-1]
|
2020-08-04 18:24:19 +00:00
|
|
|
|
2020-08-05 00:08:55 +00:00
|
|
|
# resolve path
|
2020-08-06 11:43:45 +00:00
|
|
|
container = self.__yml_content
|
2020-08-04 18:24:19 +00:00
|
|
|
for step in path:
|
2020-08-06 11:43:45 +00:00
|
|
|
container = container[step]
|
2020-08-04 18:24:19 +00:00
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
return container, key
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-06 12:34:25 +00:00
|
|
|
def __getitem__(self, key):
|
|
|
|
container, key = self.__key_resolve(key)
|
|
|
|
return container[key]
|
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
def __setitem__(self, key, value):
|
|
|
|
container, key = self.__key_resolve(key)
|
|
|
|
container[key] = value
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-06 12:34:25 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
# extract header comment from default config
|
|
|
|
with open(DEFAULT_KIWI_CONF_NAME, 'r') as stream:
|
|
|
|
yml_header = stream.read().strip()
|
|
|
|
yml_header = re.sub(r'^[^#].*', r'', yml_header, flags=re.MULTILINE).strip()
|
|
|
|
yml_string = "{}\n{}".format(yml_header, yml_string)
|
|
|
|
|
|
|
|
return yml_string
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-08 17:41:11 +00:00
|
|
|
def _update_from_file(self, filename):
|
2020-08-06 11:43:45 +00:00
|
|
|
with open(filename, 'r') as stream:
|
|
|
|
try:
|
|
|
|
self.__yml_content.update(yaml.safe_load(stream))
|
|
|
|
except yaml.YAMLError as exc:
|
|
|
|
logging.error(exc)
|
2020-08-04 18:24:19 +00:00
|
|
|
|
2020-08-08 17:41:11 +00:00
|
|
|
def save(self):
|
|
|
|
with open(KIWI_CONF_NAME, 'w') as stream:
|
2020-08-06 12:34:25 +00:00
|
|
|
stream.write(str(self))
|
|
|
|
|
2020-08-08 17:41:11 +00:00
|
|
|
|
|
|
|
class DefaultConfig(Config):
|
|
|
|
__instance = None
|
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
@classmethod
|
2020-08-08 17:41:11 +00:00
|
|
|
def get(cls):
|
|
|
|
if cls.__instance is None:
|
|
|
|
cls.__instance = cls()
|
|
|
|
cls.__instance._update_from_file(DEFAULT_KIWI_CONF_NAME)
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-08 17:41:11 +00:00
|
|
|
with open(VERSION_TAG_NAME, 'r') as stream:
|
|
|
|
cls.__instance["version"] = stream.read().strip()
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-08 17:41:11 +00:00
|
|
|
return cls.__instance
|
2020-08-06 01:45:12 +00:00
|
|
|
|
2020-08-08 17:41:11 +00:00
|
|
|
|
|
|
|
class LoadedConfig(Config):
|
2020-08-06 11:43:45 +00:00
|
|
|
@classmethod
|
2020-08-08 17:41:11 +00:00
|
|
|
def get(cls):
|
|
|
|
result = DefaultConfig.get()
|
2020-08-06 12:34:25 +00:00
|
|
|
|
|
|
|
if os.path.isfile(KIWI_CONF_NAME):
|
2020-08-08 17:41:11 +00:00
|
|
|
result._update_from_file(KIWI_CONF_NAME)
|
2020-08-04 18:24:19 +00:00
|
|
|
|
2020-08-06 11:43:45 +00:00
|
|
|
return result
|