comparison configmix/__init__.py @ 266:46571485b7d4

Allow loading configuration files from directories when using the "<dir>" prefix in filenames. Unknown filetypes within these directories are ignored automatically.
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 10 Sep 2020 02:00:11 +0200
parents 39c379fa8c65
children d715c10f2930
comparison
equal deleted inserted replaced
265:39c379fa8c65 266:46571485b7d4
26 26
27 27
28 import fnmatch 28 import fnmatch
29 import copy 29 import copy
30 import io 30 import io
31 import os
31 import re 32 import re
32 33
33 from .compat import u, u2fs 34 from .compat import u, u2fs
34 from .config import Configuration 35 from .config import Configuration
35 36
68 if defaults is None: 69 if defaults is None:
69 ex = Configuration() 70 ex = Configuration()
70 else: 71 else:
71 ex = merge(None, Configuration(defaults)) 72 ex = merge(None, Configuration(defaults))
72 for f in files: 73 for f in files:
73 nx = _load_cfg_from_file(f) 74 if f.startswith("<dir>"):
74 if nx is not None: 75 for f2 in _get_configuration_files_from_dir(f[5:]):
75 ex = merge(nx, ex) 76 nx = _load_cfg_from_file(f2, ignore_unknown=True)
77 if nx is not None:
78 ex = merge(nx, ex)
79 else:
80 nx = _load_cfg_from_file(f)
81 if nx is not None:
82 ex = merge(nx, ex)
76 if extras: 83 if extras:
77 ex = merge(Configuration(extras), ex) 84 ex = merge(Configuration(extras), ex)
78 return Configuration(ex) 85 return Configuration(ex)
79 86
80 87
88 if defaults is None: 95 if defaults is None:
89 ex = Configuration() 96 ex = Configuration()
90 else: 97 else:
91 ex = safe_merge(None, Configuration(defaults)) 98 ex = safe_merge(None, Configuration(defaults))
92 for f in files: 99 for f in files:
93 nx = _load_cfg_from_file(f) 100 if f.startswith("<dir>"):
94 if nx is not None: 101 for f2 in _get_configuration_files_from_dir(f[5:]):
95 ex = safe_merge(nx, ex) 102 nx = _load_cfg_from_file(f2, ignore_unknown=True)
103 if nx is not None:
104 ex = safe_merge(nx, ex)
105 else:
106 nx = _load_cfg_from_file(f)
107 if nx is not None:
108 ex = safe_merge(nx, ex)
96 if extras: 109 if extras:
97 ex = safe_merge(Configuration(extras), ex) 110 ex = safe_merge(Configuration(extras), ex)
98 return Configuration(ex) 111 return Configuration(ex)
112
113
114 def _get_configuration_files_from_dir(root):
115 """Returns the sorted list of files within directory `root`
116
117 """
118 files = []
119
120 if not os.path.isdir(root):
121 return files
122
123 dirfiles = os.listdir(root)
124 dirfiles.sort()
125 for f in dirfiles:
126 path = os.path.join(root, f)
127 if os.path.isdir(path):
128 # XXX TBD Recurse??? depth-first???
129 continue
130 files.append(path)
131 return files
99 132
100 133
101 def _load_yaml(filename): 134 def _load_yaml(filename):
102 from . import yaml 135 from . import yaml
103 with open(u2fs(filename), "rb") as yf: 136 with open(u2fs(filename), "rb") as yf:
291 _extensions.append((fnpattern, mode)) 324 _extensions.append((fnpattern, mode))
292 else: 325 else:
293 _extensions.insert(0, (fnpattern, mode)) 326 _extensions.insert(0, (fnpattern, mode))
294 327
295 328
296 def _load_cfg_from_file(filename): 329 def _load_cfg_from_file(filename, ignore_unknown=False):
297 """Determine the loader for file `filename` and return the loaded 330 """Determine the loader for file `filename` and return the loaded
298 configuration dict. 331 configuration dict.
332
333 If `ignore_unknown` is `True` then unknown extensions are ignored.
334 Otherwise a :exc:`ValueError` exception is raised.
299 335
300 Can return `None` is the file should be ignored by the caller. 336 Can return `None` is the file should be ignored by the caller.
301 337
302 """ 338 """
303 for p, m in _extensions: 339 for p, m in _extensions:
306 m = m(filename) 342 m = m(filename)
307 if m is None: 343 if m is None:
308 continue 344 continue
309 return mode_loaders[m](filename) 345 return mode_loaders[m](filename)
310 else: 346 else:
311 raise ValueError("Unknown configuration file type for filename " 347 if ignore_unknown:
312 "%r" % filename) 348 return None
349 else:
350 raise ValueError("Unknown configuration file type for filename "
351 "%r" % filename)
313 352
314 353
315 if 0: 354 if 0:
316 # 355 #
317 # From: https://github.com/jet9/python-yconfig/blob/master/yconfig.py 356 # From: https://github.com/jet9/python-yconfig/blob/master/yconfig.py