Skip to content

Commit

Permalink
EVA-3414 add Writable config script (#49)
Browse files Browse the repository at this point in the history
added writable config
  • Loading branch information
nitin-ebi authored Oct 9, 2023
1 parent a60a1fb commit b15ba91
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
77 changes: 77 additions & 0 deletions ebi_eva_common_pyutils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,80 @@ def __contains__(self, item):
"""
Provides a singleton that can be used as a central place for configuration.
"""




class WritableConfig(Configuration):
"""Configuration object that allows writes to the config file"""

def __init__(self, *search_path, version=None):
super().__init__(*search_path)
self.version = version

def load_config_file(self, *search_path):
try:
super().load_config_file(*search_path)
except FileNotFoundError:
# expected if it's the first time we are creating the config file
# In that case the first search path is set to be the config files
self.config_file = search_path[0]
pass

def backup(self):
"""
Rename the config file by adding a '.1' at the end. If the '.1' file exists it move it to a '.2' and so on.
"""
if os.path.isfile(self.config_file):
file_name = self.config_file
suffix = 1
backup_name = f'{file_name}.{suffix}'
while os.path.exists(backup_name):
suffix += 1
backup_name = f'{file_name}.{suffix}'

for i in range(suffix, 1, -1):
os.rename(f'{file_name}.{i - 1}', f'{file_name}.{i}')
os.rename(file_name, file_name + '.1')

def write(self):
if self.config_file and self.content and os.path.isdir(os.path.dirname(self.config_file)):
with open(self.config_file, 'w') as open_config:
yaml.safe_dump(self.content, open_config)

def set(self, *path, value):
self._set_version()
top_level = self.content
for p in path[:-1]:
if p not in top_level:
top_level[p] = {}
top_level = top_level[p]
top_level[path[-1]] = value

def pop(self, *path, default=None):
"""Recursive dictionary pop with default"""
top_level = self.content
for p in path[:-1]:
if p not in top_level:
return default
top_level = top_level[p]
return top_level.pop(path[-1], default)

def is_empty(self):
return not self.content

def clear(self):
self.content = {}

def _set_version(self):
# If we're starting to fill in an empty config, set the version if available
if self.is_empty() and self.version:
self.content['version'] = self.version

def __contains__(self, item):
return item in self.content

def __setitem__(self, item, value):
"""Allow dict-style write access, e.g. config['this']='that'."""
self._set_version()
self.content[item] = value
1 change: 0 additions & 1 deletion tests/common/test_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
from os import environ
from os.path import join

import pytest
Expand Down

0 comments on commit b15ba91

Please sign in to comment.