121 lines
3.5 KiB
Python
121 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Configuration file core loading functions
|
|
"""
|
|
|
|
# Import python libs
|
|
import os
|
|
import glob
|
|
import fnmatch
|
|
import pop.hub
|
|
|
|
__virtualname__ = "file"
|
|
__contracts__ = [__virtualname__]
|
|
|
|
|
|
def load_file(hub: "pop.hub.Hub", paths, defaults=None, overrides=None, includes=True):
|
|
"""
|
|
Load a single configuration file
|
|
"""
|
|
opts = {}
|
|
if isinstance(defaults, dict):
|
|
opts.update(defaults)
|
|
if not isinstance(paths, list):
|
|
paths = paths.split(",")
|
|
add = []
|
|
for fn_ in paths:
|
|
add.extend(glob.glob(fn_))
|
|
paths.extend(add)
|
|
for fn_ in paths:
|
|
if hub.conf._loader == "yaml":
|
|
opts.update(hub.conf.yaml.load(fn_))
|
|
elif hub.conf._loader == "json":
|
|
opts.update(hub.conf.json.load(fn_))
|
|
elif hub.conf._loader == "toml":
|
|
opts.update(hub.conf.toml.load(fn_))
|
|
if includes:
|
|
hub.conf.file.proc_include(opts)
|
|
if isinstance(overrides, dict):
|
|
opts.update(overrides)
|
|
return opts
|
|
|
|
|
|
def load_dir(
|
|
hub,
|
|
confdir,
|
|
defaults=None,
|
|
overrides=None,
|
|
includes=True,
|
|
recurse=False,
|
|
pattern=None,
|
|
):
|
|
"""
|
|
Load takes a directory location to scan for configuration files. These
|
|
files will be read in. The defaults dict defines what
|
|
configuration options should exist if not found in the confdir. Overrides
|
|
are configuration options which should be included regardless of whether
|
|
those options existed before. If includes is set to True, then the
|
|
statements 'include' and 'include_dir' found in either the defaults or
|
|
in configuration files.
|
|
"""
|
|
opts = {}
|
|
if not isinstance(confdir, list):
|
|
confdir = confdir.split(",")
|
|
confdirs = []
|
|
for dirs in confdir:
|
|
if not isinstance(dirs, (list, tuple)):
|
|
dirs = [dirs]
|
|
for dir_ in dirs:
|
|
confdirs.extend(glob.glob(dir_))
|
|
if isinstance(defaults, dict):
|
|
opts.update(defaults)
|
|
paths = []
|
|
for dir_ in confdirs:
|
|
dirpaths = []
|
|
if os.path.isdir(dir_):
|
|
if not recurse:
|
|
for fn_ in os.listdir(dir_):
|
|
path = os.path.join(dir_, fn_)
|
|
if os.path.isdir(path):
|
|
# Don't process directories
|
|
continue
|
|
if pattern and not fnmatch.fnmatch(fn_, pattern):
|
|
continue
|
|
dirpaths.append(path)
|
|
else:
|
|
for root, dirs, files in os.walk(dir_):
|
|
for fn_ in files:
|
|
path = os.path.join(root, fn_)
|
|
if pattern and not fnmatch.fnmatch(fn_, pattern):
|
|
continue
|
|
dirpaths.append(path)
|
|
|
|
# Sort confdir directory paths like:
|
|
# /b.txt
|
|
# /c.txt
|
|
# /a/x.txt
|
|
# /b/x.txt
|
|
paths.extend(sorted(dirpaths, key=lambda p: (p.count(os.path.sep), p)))
|
|
opts.update(hub.conf.file.load_file(paths, includes))
|
|
if isinstance(overrides, dict):
|
|
opts.update(overrides)
|
|
return opts
|
|
|
|
|
|
def proc_include(hub: "pop.hub.Hub", opts):
|
|
"""
|
|
process include and include_dir
|
|
"""
|
|
rec = False
|
|
if opts.get("include_dir"):
|
|
idir = opts.pop("include_dir")
|
|
opts.update(hub.conf.file.load_dir(idir))
|
|
rec = True
|
|
if opts.get("include"):
|
|
ifn = opts.pop("include")
|
|
opts.update(hub.conf.file.load_file(ifn))
|
|
rec = True
|
|
if rec:
|
|
hub.conf.file.proc_include(opts)
|
|
return opts
|