Skip to content
Snippets Groups Projects
Commit 10861a1c authored by David Huss's avatar David Huss :speech_balloon:
Browse files

Format with black, add ability to supply suffix

This adds the ability to supply the suffix manually to the
initialize_config function, to allow multiple runs of the same function
with different suffices.
parent ea3b2421
No related branches found
No related tags found
No related merge requests found
.gitignore 100644 → 100755
File mode changed from 100644 to 100755
README.md 100644 → 100755
File mode changed from 100644 to 100755
__version__ = '0.1.17'
__version__ = "0.1.18"
from common_config.common import *
......@@ -45,12 +45,14 @@ def get_config_directories() -> List[dict]:
default_config_home = f"{get_home()}/.config/{APPLICATION_NAME}"
# Unless the XDG_CONFIG_HOME environment variable has been set, then use this instead
default_config_home = this_or_else(os.environ.get("XDG_CONFIG_HOME"), default_config_home)
default_config_home = this_or_else(
os.environ.get("XDG_CONFIG_HOME"), default_config_home
)
# Create the list of directories
config_directories = [
{"path": Path(etc_directory), "kind": "default", "source": None},
{ "path": Path(default_config_home), "kind": "default", "source": None }
{"path": Path(default_config_home), "kind": "default", "source": None},
]
# If the EIGENSERVICE_CONFIG_PATH environment variable exists append to list
......@@ -72,7 +74,7 @@ def get_potential_config_file_paths(suffix: str) -> List[dict]:
config_paths = []
for directory in get_config_directories():
for path in sorted(directory["path"].glob(f'*{suffix}.toml')):
for path in sorted(directory["path"].glob(f"*{suffix}.toml")):
path = {"path": path, "kind": "default", "source": None}
config_paths.append(path)
......@@ -96,7 +98,11 @@ def get_existing_config_file_paths(suffix: str) -> List[Path]:
(last overrides first)
"""
return [p["path"] for p in get_potential_config_file_paths(suffix) if p["path"].is_file()]
return [
p["path"]
for p in get_potential_config_file_paths(suffix)
if p["path"].is_file()
]
def has_no_existing_config(suffix: str) -> bool:
......@@ -106,7 +112,9 @@ def has_no_existing_config(suffix: str) -> bool:
return len(get_existing_config_file_paths(suffix)) == 0
def merge(this: Union[dict, MutableMapping], that: Union[dict, MutableMapping, Mapping]) -> Union[dict, MutableMapping[str, Any]]:
def merge(
this: Union[dict, MutableMapping], that: Union[dict, MutableMapping, Mapping]
) -> Union[dict, MutableMapping[str, Any]]:
"""
Merge dict this in to dict that
"""
......@@ -118,19 +126,26 @@ def merge(this: Union[dict, MutableMapping], that: Union[dict, MutableMapping, M
return this
def initialize_config(logger=None) -> MutableMapping[str, Any]:
def initialize_config(logger=None, suffix=None) -> MutableMapping[str, Any]:
"""
Initialize a configuration. If none exists, create a default one
"""
config = toml.loads(DEFAULT_CONFIG)
if suffix is None:
suffix = SUFFIX
# Return if there is no other config
if has_no_existing_config(SUFFIX):
if has_no_existing_config(suffix):
if logger is not None:
logger.warning("Using default configuration, create an override by running \"config create\"")
logger.warning(
'Using default configuration, create an override by running "config create"'
)
logger = set_loglevel(config, logger)
else:
print("Using default configuration, create an override by running config create")
print(
"Using default configuration, create an override by running config create"
)
return config
if logger is not None:
......@@ -141,7 +156,7 @@ def initialize_config(logger=None) -> MutableMapping[str, Any]:
print("Config [1]: DEFAULT_CONFIG (hardcoded)")
# Read all existing configs in order and merge/override the default one
for i, p in enumerate(get_existing_config_file_paths(SUFFIX)):
for i, p in enumerate(get_existing_config_file_paths(suffix)):
next_config = read_config(str(p))
config = merge(dict(config), dict(next_config))
if logger is not None:
......@@ -186,7 +201,9 @@ def set_loglevel(config, logger: logging.Logger) -> logging.Logger:
logger.info(f"Set loglevel to {level.upper()}")
logger.setLevel(logging.CRITICAL)
else:
logger.critical(f"The loglevel \"{config['application']['loglevel']}\" set in config.toml is invalid use one of the following: \"Debug\", \"Info\", \"Warning\", \"Error\" or \"Critical\"")
logger.critical(
f"The loglevel \"{config['application']['loglevel']}\" set in config.toml is invalid use one of the following: \"Debug\", \"Info\", \"Warning\", \"Error\" or \"Critical\""
)
exit(1)
return logger
......@@ -203,13 +220,11 @@ def main():
"paths": print_paths,
"directories": print_directories,
"create": create_config,
"test": test
"test": test,
}
# List of available options
availaible_options = [
["-h", "--help"]
]
availaible_options = [["-h", "--help"]]
# If no argument has been passed display the help and exit
if len(sys.argv) == 1:
......@@ -220,7 +235,11 @@ def main():
command_args = [c for c in sys.argv[1:] if not c.strip().startswith("-")]
# Extract the short_options
short_options = [c.lstrip("-") for c in sys.argv[1:] if c.strip().startswith("-") and not c.strip().startswith("--")]
short_options = [
c.lstrip("-")
for c in sys.argv[1:]
if c.strip().startswith("-") and not c.strip().startswith("--")
]
# Flatten the short_options to e.g. so -1234 will result in ["1", "2", "3", "4"]
short_options = [item for sublist in short_options for item in sublist]
......@@ -232,13 +251,13 @@ def main():
# Short Options
for o in short_options:
if o not in [a[0].lstrip("-") for a in availaible_options]:
print(f"Error: the option \"-{o}\" does not exist.", file=sys.stderr)
print(f'Error: the option "-{o}" does not exist.', file=sys.stderr)
errored = True
# Long Options
for o in long_options:
if o not in [a[0].lstrip("--") for a in availaible_options]:
print(f"Error: the option \"--{o}\" does not exist.", file=sys.stderr)
print(f'Error: the option "--{o}" does not exist.', file=sys.stderr)
errored = True
# If any of the above errored, exit. This allows to display all errors at once
......@@ -256,16 +275,35 @@ def main():
# No fitting command has been found, print helpt and exit
print_help()
exit()
elif len([c for c in commands.keys() if c.startswith(command.strip().lower())]) > 1:
elif (
len([c for c in commands.keys() if c.startswith(command.strip().lower())])
> 1
):
# More than one fitting command has been found, display this message
print("Ambiguous Input: There are {} commands starting with \"{}\": {}".format(
len([c for c in commands.keys() if c.startswith(command.strip().lower())]),
print(
'Ambiguous Input: There are {} commands starting with "{}": {}'.format(
len(
[
c
for c in commands.keys()
if c.startswith(command.strip().lower())
]
),
command,
", ".join([c for c in commands.keys() if c.startswith(command.strip().lower())])
))
", ".join(
[
c
for c in commands.keys()
if c.startswith(command.strip().lower())
]
),
)
)
else:
# A command has been found:
choice = [c for c in commands.keys() if c.startswith(command.strip().lower())][0]
choice = [
c for c in commands.keys() if c.startswith(command.strip().lower())
][0]
# If there is a -h or --help option, display the function's docstring
# otherwise execute the function
......@@ -284,6 +322,7 @@ def test():
Reads all configs like it would in production, prints out the order in which the config files are read and spits out the final resulting toml config
"""
import pprint
config = initialize_config()
print("\nvvvvvvvvvvvvv Below is the resulting config vvvvvvvvvvvvv\n")
print(toml.dumps(config))
......@@ -307,7 +346,9 @@ def print_paths():
if p["exists"]:
print(f"{p['path']} (set by environment variable {p['source']})")
else:
print(f"{p['path']} (set by environment variable {p['source']}, but doesn't exist)")
print(
f"{p['path']} (set by environment variable {p['source']}, but doesn't exist)"
)
else:
if p["exists"]:
print(f"{p['path']}")
......@@ -360,17 +401,23 @@ def create_config():
if not config_path.is_file():
print(f" [{i}] {p['path']} ({source}create 00-{SUFFIX}.toml there)")
else:
print(f" [{i}] {p['path']} ({source}override existing 00-{SUFFIX}.toml!)")
print(
f" [{i}] {p['path']} ({source}override existing 00-{SUFFIX}.toml!)"
)
elif p["path"].is_file():
pass
else:
print(f" [{i}] {p['path']} ({source}dir doesn't exist: create, then write 00-{SUFFIX}.toml there)")
print(
f" [{i}] {p['path']} ({source}dir doesn't exist: create, then write 00-{SUFFIX}.toml there)"
)
print(" [x] Do nothing")
print()
# Collect the selection input
selection = None
while selection is None or not selection in [str(i) for i, p in enumerate(config_directories)]:
while selection is None or not selection in [
str(i) for i, p in enumerate(config_directories)
]:
selection = input("Select one of the above: ")
if selection.lower() in ["x"]:
break
......@@ -389,14 +436,22 @@ def create_config():
python_path = f"{sys.prefix}/bin/python3"
script_path = f"{inspect.stack()[-1][1]}"
print()
print(f"Error: Didn't have the permissions to create the config directory at {selection['path']}", file=sys.stderr)
print(f"Hint: Change the owner of the directory temporarily to {getpass.getuser()} or run {APPLICATION_NAME} config create with more permissions", file=sys.stderr)
print(f"Hint: To run the script with this python executable run \"sudo {python_path} {script_path}\"", file=sys.stderr)
print(
f"Error: Didn't have the permissions to create the config directory at {selection['path']}",
file=sys.stderr,
)
print(
f"Hint: Change the owner of the directory temporarily to {getpass.getuser()} or run {APPLICATION_NAME} config create with more permissions",
file=sys.stderr,
)
print(
f'Hint: To run the script with this python executable run "sudo {python_path} {script_path}"',
file=sys.stderr,
)
sys.exit()
config_path = Path(f"{selection['path']}/00-{SUFFIX}.toml")
# If the 00-frontend.toml already exists, ask whether it shall be moved to 00-frontend.toml.old
if config_path.is_file():
# Create an alternate config path, incrementing up if .old already exists
......@@ -412,12 +467,14 @@ def create_config():
# Ask for confirmation
confirmation = None
while confirmation is None or not confirmation.lower().strip() in ["y", "n"]:
confirmation = input(f"Move existing file at \"{config_path}\" to \"{alt_config_path}\"? [Y/n]:\t")
confirmation = input(
f'Move existing file at "{config_path}" to "{alt_config_path}"? [Y/n]:\t'
)
if confirmation.lower().strip() != "y":
exit()
else:
config_path.rename(alt_config_path)
print(f"Moved existing file \"{config_path}\" to \"{alt_config_path}\"")
print(f'Moved existing file "{config_path}" to "{alt_config_path}"')
# Create the config.toml or display a hint if the permissions don't suffice
try:
......@@ -426,11 +483,22 @@ def create_config():
python_path = f"{sys.prefix}/bin/python3"
script_path = f"{inspect.stack()[-1][1]}"
print()
print(f"Error: Didn't have the permissions to write the file to {config_path}", file=sys.stderr)
print(f" Directory \"{selection['path']}\" belongs to user {selection['path'].owner()} (was running as user {getpass.getuser()})", file=sys.stderr)
print(
f"Error: Didn't have the permissions to write the file to {config_path}",
file=sys.stderr,
)
print(
f" Directory \"{selection['path']}\" belongs to user {selection['path'].owner()} (was running as user {getpass.getuser()})",
file=sys.stderr,
)
print()
print(f"Hint: Change the owner of the directory temporarily to {getpass.getuser()} or run {APPLICATION_NAME} config create with more permissions")
print(f"Hint: To run the script with this python executable run \"sudo {python_path} {script_path}\"", file=sys.stderr)
print(
f"Hint: Change the owner of the directory temporarily to {getpass.getuser()} or run {APPLICATION_NAME} config create with more permissions"
)
print(
f'Hint: To run the script with this python executable run "sudo {python_path} {script_path}"',
file=sys.stderr,
)
sys.exit()
print(f"Default Config has been written to {config_path}")
......
File mode changed from 100644 to 100755
poetry.lock 100644 → 100755
File mode changed from 100644 to 100755
pyproject.toml 100644 → 100755
[tool.poetry]
name = "common-config"
version = "0.1.17"
version = "0.1.18"
description = "A config library for eigenservice"
authors = ["David Huss <dh@atoav.com>"]
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment