Files
basegame-vcko/python3-vckonline/lib/python3.8/site-packages/pop/mods/conf/file_parser.py
2020-11-03 18:30:14 -08:00

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