diff options
author | Magnus Hagander | 2023-08-25 07:56:10 +0000 |
---|---|---|
committer | Magnus Hagander | 2023-08-25 07:56:10 +0000 |
commit | f755c6379d042f99bb7780c784047164062a977a (patch) | |
tree | d6c1e884ce5a3fc7ffe321a8b175fb8bc880c75c /postgresqleu/confreg/contextutil.py | |
parent | db6c77d069d7522f8c211c5ce27a8e6e6ed5f2f5 (diff) |
Support YAML as well as JSON for context files
Previously only json as supported for the template integration for
context.json and context.override.d. This adds support for yaml as well
both for a context.yaml file, and for putting yaml files in
context.override.d. If both a json and yaml exists with the same name
(in the root or in the override), then the json will be loaded first and
then the yaml merged on top of it.
YAML has a few features that are really useful for the context file such
as comments and easier on the eyes multi-line string handling, but
fundamentally the handling is exactly the same.
If the `yaml` module is not importable, then yaml files are simply
ignored.
Diffstat (limited to 'postgresqleu/confreg/contextutil.py')
-rw-r--r-- | postgresqleu/confreg/contextutil.py | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/postgresqleu/confreg/contextutil.py b/postgresqleu/confreg/contextutil.py index 591cb4c5..a8bb4399 100644 --- a/postgresqleu/confreg/contextutil.py +++ b/postgresqleu/confreg/contextutil.py @@ -6,6 +6,13 @@ import copy from postgresqleu.util.context_processors import settings_context +try: + import yaml + _has_yaml = True +except ImportError: + _has_yaml = False + + # XXX: keep in sync with deploystatic.py! def deep_update_context(target, source): for k, v in source.items(): @@ -23,22 +30,29 @@ def deep_update_context(target, source): target[k] = copy.copy(v) -def _load_context_file(filename): +def _load_context_file(filename, ignore_exceptions=True): try: with open(filename, encoding='utf8') as f: - return json.load(f) + if filename.endswith('.json'): + return json.load(f) + else: + return yaml.safe_load(f) except ValueError as e: # Malformatted JSON -- pass it through as an exception raise except Exception: - # Any other error, just ignore it (?) + if not ignore_exceptions: + raise return {} def load_base_context(rootdir): + c = {} if os.path.isfile(os.path.join(rootdir, 'templates/context.json')): - return _load_context_file(os.path.join(rootdir, 'templates/context.json')) - return {} + deep_update_context(c, _load_context_file(os.path.join(rootdir, 'templates/context.json'))) + if _has_yaml and os.path.isfile(os.path.join(rootdir, 'templates/context.yaml')): + deep_update_context(c, _load_context_file(os.path.join(rootdir, 'templates/context.yaml'))) + return c def load_override_context(rootdir): @@ -46,10 +60,9 @@ def load_override_context(rootdir): c = {} if os.path.isdir(os.path.join(rootdir, 'templates/context.override.d')): for fn in sorted(os.listdir(os.path.join(rootdir, 'templates/context.override.d'))): - if fn.endswith('.json'): + if fn.endswith('.json') or (_has_yaml and fn.endswith('.yaml')): try: - with open(os.path.join(rootdir, 'templates/context.override.d', fn)) as f: - deep_update_context(c, json.load(f)) + deep_update_context(c, _load_context_file(os.path.join(rootdir, 'templates/context.override.d', fn), False)) except Exception as e: logging.getLogger(__name__).warning( 'Failed to load context file {}: {}'.format(os.path.join(rootdir, 'templates/context.override.d', fn), e) |