Skip to content
Snippets Groups Projects
config.py 3.77 KiB
Newer Older
#!/usr/bin/env python3

"""EnvSetup config utilities."""

from collections import OrderedDict
from pathlib import Path
import re

from .logging import log
from .os import get_dir

DEFAULT_CONF_PATH = "global-conf.sh"
AUTO_CONF_PATH = "auto-generated-conf.sh"
CONF_PATH = "conf.sh"

_conf_cache = None


def load_conf() -> dict:
    """Load EnvSetup configuration settings.

    :return: Configuration settings
    :rtype: dict
    """

    conf = {}
    base_dir = str(Path(get_dir(__file__)).parent)
    files = (
        (str(Path(base_dir, DEFAULT_CONF_PATH)), True),
        (str(Path(base_dir, AUTO_CONF_PATH)), False),
        (str(Path(base_dir, CONF_PATH)), False),
    )
    only_default = True
    override = OrderedDict()
    for path, is_default in files:
        if not Path(path).exists():
            if is_default:
                log(
                    "The configuration file '{}' does not exist.".format(path),
                    error=True,
                )
                return dict()
            continue
        # Load conf
        with open(path, "r") as fo:
            content = fo.read()
        # Parse conf
        for line in content.split("\n"):
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                name, *val = line.split("=")
                name = name.strip(" \t'\"")
                val = ("=".join(val)).strip(" \t'\"")
                conf[name] = val
                if is_default:
                    override[name] = False
                else:
                    only_default = False
                    override[name] = True
    conf["_override"] = override
    # Check a value to know if the config file has been changed
    if only_default:
        log("\033[93mWarning:\033[0m")
        log("The configuration is using only default values.")
        log("Perhaps you forget to change the configuration.")
        log("Path of configuration file: %s" % str(Path(base_dir, CONF_PATH)))
        log("Perhaps you want to quit this script to change the configuration?\n")
    global _conf_cache
    _conf_cache = conf
    return conf


def get_conf(name: str, default: str = None) -> str:
    """Get the given configuration parameter.

    :param name: Parameter name
    :type name: str
    :param default: Default parameter value, defaults to None
    :type default: str, optional
    :return: Parameter value
    :rtype: str
    """

    global _conf_cache
    if _conf_cache is None:
        load_conf()

    return _conf_cache.get(name, default)


def set_conf(key: str, value: str, override: bool = False) -> bool:
    """Write the given configuration option in `conf.sh`.

    :param key: Option name
    :type key: str
    :param value: Option value
    :type value: str
    :param override: Wether to override the option if it already exists, defaults to False
    :type override: bool, optional
    :return: True if the option have changed, False otherwise
    :rtype: bool
    """

    base_dir = Path(__file__).resolve().parent
    conf_path = Path(base_dir, CONF_PATH).resolve()
    # read conf.sh
    with open(conf_path) as read_conf_fh:
        conf = read_conf_fh.read()

    # check if option already exists
    regex = re.compile(r"^" + key.upper() + "=(.*)$", flags=re.M)
    match = regex.search(conf)
    if match and override:
        # override option
        conf = regex.sub("{}='{}'".format(key.upper(), str(value)), conf)
        with open(conf_path, "w") as conf_fh:
            conf_fh.write(conf)
        success = True
    elif not match:
        # add option
        with open(conf_path, "a") as conf_fh:
            conf_fh.write("\n{}='{}'\n".format(key.upper(), str(value)))
        success = True
    else:
        # no match or no override
        success = False
    # reload conf
    load_conf()
    return success