aboutsummaryrefslogtreecommitdiff
blob: aab5356c6178445e0d842c5b12d544db2948f8c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""Various command-line specific support."""

import configparser
import os
import sys

from pkgcore.util import commandline
from snakeoil.cli import arghparse
from snakeoil.klass import jit_attr_none
from snakeoil.contexts import patch
from snakeoil.log import suppress_logging

from .base import PkgcheckException


class Tool(commandline.Tool):
    """Suppress log messages globally."""

    def main(self):
        with suppress_logging():
            try:
                return super().main()
            except PkgcheckException as e:
                sys.exit(str(e))


class ConfigArgumentParser(arghparse.ArgumentParser):
    """Argument parser that supports loading settings from specified config files."""

    def __init__(self, configs=(), **kwargs):
        super().__init__(**kwargs)
        self._configs = tuple(x for x in set(configs) if os.path.isfile(x))

    @property
    def configs(self):
        return self._configs

    @configs.setter
    def configs(self, value):
        self._configs += value
        # reset jit attr to force re-parse
        self._config = None

    @jit_attr_none
    def config(self):
        return self.parse_config(self._configs)

    def parse_config(self, configs):
        """Parse given config files."""
        config = configparser.ConfigParser()
        try:
            for f in configs:
                config.read(f)
        except configparser.ParsingError as e:
            self.error(f'parsing config file failed: {e}')
        return config

    def parse_config_options(self, namespace=None, section='DEFAULT'):
        """Parse options from config if they exist."""
        namespace = arghparse.Namespace() if namespace is None else namespace
        config_args = [f'--{k}={v}' if v else f'--{k}' for k, v in self.config.items(section)]
        if config_args:
            with patch('snakeoil.cli.arghparse.ArgumentParser.error', self._config_error):
                namespace, args = self.parse_known_optionals(config_args, namespace)
                if args:
                    self.error(f"unknown arguments: {'  '.join(args)}")
        return namespace

    def _config_error(self, message, status=2):
        """Stub to replace error method that notes config failure."""
        self.exit(status, f'{self.prog}: failed loading config: {message}\n')