# HG changeset patch # User Franz Glasner # Date 1599696011 -7200 # Node ID 46571485b7d416e56f32d990e1dc66496a20e103 # Parent 39c379fa8c65f6c61779351f366d8fa737864441 Allow loading configuration files from directories when using the "" prefix in filenames. Unknown filetypes within these directories are ignored automatically. diff -r 39c379fa8c65 -r 46571485b7d4 CHANGES.txt --- a/CHANGES.txt Thu Sep 10 01:09:16 2020 +0200 +++ b/CHANGES.txt Thu Sep 10 02:00:11 2020 +0200 @@ -13,6 +13,19 @@ -------------- .. changelog:: + :version: n/a + :released: n/a + + .. change:: + :tags: feature + + Allow loading configuration files from directories when using + the "" prefix in filenames. + + Unknown filetypes within these directories are ignored + automatically. + +.. changelog:: :version: 0.9 :released: 2020-07-28 diff -r 39c379fa8c65 -r 46571485b7d4 configmix/__init__.py --- a/configmix/__init__.py Thu Sep 10 01:09:16 2020 +0200 +++ b/configmix/__init__.py Thu Sep 10 02:00:11 2020 +0200 @@ -28,6 +28,7 @@ import fnmatch import copy import io +import os import re from .compat import u, u2fs @@ -70,9 +71,15 @@ else: ex = merge(None, Configuration(defaults)) for f in files: - nx = _load_cfg_from_file(f) - if nx is not None: - ex = merge(nx, ex) + if f.startswith(""): + for f2 in _get_configuration_files_from_dir(f[5:]): + nx = _load_cfg_from_file(f2, ignore_unknown=True) + if nx is not None: + ex = merge(nx, ex) + else: + nx = _load_cfg_from_file(f) + if nx is not None: + ex = merge(nx, ex) if extras: ex = merge(Configuration(extras), ex) return Configuration(ex) @@ -90,14 +97,40 @@ else: ex = safe_merge(None, Configuration(defaults)) for f in files: - nx = _load_cfg_from_file(f) - if nx is not None: - ex = safe_merge(nx, ex) + if f.startswith(""): + for f2 in _get_configuration_files_from_dir(f[5:]): + nx = _load_cfg_from_file(f2, ignore_unknown=True) + if nx is not None: + ex = safe_merge(nx, ex) + else: + nx = _load_cfg_from_file(f) + if nx is not None: + ex = safe_merge(nx, ex) if extras: ex = safe_merge(Configuration(extras), ex) return Configuration(ex) +def _get_configuration_files_from_dir(root): + """Returns the sorted list of files within directory `root` + + """ + files = [] + + if not os.path.isdir(root): + return files + + dirfiles = os.listdir(root) + dirfiles.sort() + for f in dirfiles: + path = os.path.join(root, f) + if os.path.isdir(path): + # XXX TBD Recurse??? depth-first??? + continue + files.append(path) + return files + + def _load_yaml(filename): from . import yaml with open(u2fs(filename), "rb") as yf: @@ -293,10 +326,13 @@ _extensions.insert(0, (fnpattern, mode)) -def _load_cfg_from_file(filename): +def _load_cfg_from_file(filename, ignore_unknown=False): """Determine the loader for file `filename` and return the loaded configuration dict. + If `ignore_unknown` is `True` then unknown extensions are ignored. + Otherwise a :exc:`ValueError` exception is raised. + Can return `None` is the file should be ignored by the caller. """ @@ -308,8 +344,11 @@ continue return mode_loaders[m](filename) else: - raise ValueError("Unknown configuration file type for filename " - "%r" % filename) + if ignore_unknown: + return None + else: + raise ValueError("Unknown configuration file type for filename " + "%r" % filename) if 0: