From 079c2c3f253abe28d020d7f670b00f0f49f0e1d7 Mon Sep 17 00:00:00 2001 From: StudioEtrange Date: Sat, 13 May 2023 01:01:54 +0200 Subject: [PATCH] authorize to specify a list of path to loader. Make repeteable -p option for ctdump script --- configtree/loader.py | 30 +++++++++++++++++------------- configtree/script.py | 35 ++++++++++++++++++++++++++++++++--- tox.ini | 2 +- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/configtree/loader.py b/configtree/loader.py index 84398fc..600dc18 100644 --- a/configtree/loader.py +++ b/configtree/loader.py @@ -55,28 +55,32 @@ def fromconf(cls, path): conf = dict((k, v) for k, v in conf.items() if k in keys) return cls(**conf) - def __call__(self, path): + def __call__(self, pathlist): """ Loads configuration - :param str path: Path to a directory that contains configuration files. + :param str or list pathlist: Path or List of paths to directories that contains configuration files. :returns: Result tree object :rtype: Tree """ from . import logger - logger.info('Walking over "%s"', path) - for f in self.walk(path): - relpath = os.path.relpath(f, path) - logger.info('Loading "%s"', relpath) - ext = os.path.splitext(f)[1] - with open(f) as data: - data = source.map[ext](data) - if not data: - continue - for key, value in flatten(data): - self.update(self.tree, key, value, f) + if not type(pathlist) in (tuple, list): + pathlist=[pathlist] + + for path in pathlist: + logger.info('Walking over "%s"', path) + for f in self.walk(path): + relpath = os.path.relpath(f, path) + logger.info('Loading "%s"', relpath) + ext = os.path.splitext(f)[1] + with open(f) as data: + data = source.map[ext](data) + if not data: + continue + for key, value in flatten(data): + self.update(self.tree, key, value, f) logger.info("Post-processing") self.postprocess(self.tree) return self.tree diff --git a/configtree/script.py b/configtree/script.py index 326b853..1589f65 100644 --- a/configtree/script.py +++ b/configtree/script.py @@ -8,6 +8,35 @@ from . import formatter from .loader import Loader, ProcessingError, UpdateAction +class CustomAppendAction(argparse.Action): + """Custom action to append values to a list. + + When using the `append` action, the default value is not removed + from the list. This problem is described in + https://github.com/python/cpython/issues/60603 + + This custom action aims to fix this problem by removing the default + value when the argument is specified for the first time. + + picked from https://github.com/python/cpython/issues/60603#issuecomment-1492883530 + """ + + def __init__(self, option_strings, dest, nargs=None, **kwargs): + """Initialize the action.""" + self.called_times = 0 + self.default_value = kwargs.get("default") + super().__init__(option_strings, dest, **kwargs) + + def __call__(self, parser, namespace, values, option_string=None): + """When the argument is specified on the commandline.""" + current_values = getattr(namespace, self.dest) + + if self.called_times == 0 and current_values == self.default_value: + current_values = [] + + current_values.append(values) + setattr(namespace, self.dest, current_values) + self.called_times += 1 def ctdump(argv=None, stdout=None, stderr=None): """ @@ -85,7 +114,8 @@ def format_usage(option_group): "--path", default=default_path, metavar="", - help="path to configuration tree", + action=CustomAppendAction, + help="paths to configuration tree", ) common_options.add_argument( "-v", "--verbose", action="store_true", help="print debug output" @@ -128,8 +158,7 @@ def format_usage(option_group): raise loader_error if args["verbose"]: logger.setLevel(logging.INFO) - - logger.info("Loading tree") + logger.info("Loading tree from path %s", args["path"]) try: tree = load(args["path"]) except ProcessingError as e: diff --git a/tox.ini b/tox.ini index f06501a..d963612 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py35,py36,py37,py38,pypy2,pypy3 +envlist = py27,py35,py36,py37,py39,py310,pypy2,pypy3 [testenv] deps =