Exemple #1
0
def get_config(config_file=None):
    """Loads the configuration

    Loads either the user supplied configuration, the configuration in the XDG
    path, or the default config. Configuration may be given incompletely, so if
    you only supply the color (for example), other configuration values are
    taken from the defaults. The user can also supply a configuration as a
    dictionary as an argument to this function, this takes first priority.

    Parameters
    ----------
    config_file : str or Path
        Which config to load

    Returns
    -------
    config : dict
        The configuration to use

    Example
    -------

    >>> config = get_config()
    >>> debug = config.get("debug")  # Evaluates to whatever debug is set in
                                     # the first configuration found
    """

    environments = [
        # Look in OS process environment first
        ConfigOSEnv(),
        # Look in YAML files in order specified
        ConfigYamlEnv(CONFIG_FILES),
    ]
    if config_file:
        environments.insert(0, config_file)
    manager = ConfigManager(
        # Specify one or more configuration environments in
        # the order they should be checked
        environments=environments,
        # Provide users a link to documentation for when they hit
        # configuration errors
        doc="Check https://example.com/configuration for docs.",
    )

    # Apply the configuration class to the configuration manager
    # so that it handles option properties like defaults, parsers,
    # documentation, and so on.
    return manager.with_options(AppConfig())
Exemple #2
0
def get_config():
    config = ConfigManager(environments=[ConfigOSEnv()])
    return config.with_options(BotConfig())
Exemple #3
0
def run_program(app, args, parser=None):
    if parser is None:
        parser = argparse.ArgumentParser(prog=app.program_name)

    parser.add_argument(
        '--config',
        help=('Config file in ENV format. Setting options on the command line '
              'will override values in the config file.'),
    )

    options = app.get_required_config()

    for opt in options:
        # We don't enforce required here--we do that in a later pass so we can
        # take configuration files into account.
        kwargs = {
            'help': opt.doc,
            'type': handle_no_value(opt.parser),
            'action': 'store',
        }

        if opt.default is not NO_VALUE:
            kwargs['help'] += ' Default is %s.' % opt.default

        parser.add_argument('--%s' % opt.key.lower(), **kwargs)

    parser.set_defaults(handler=app)

    # Parse the args--this will exit if there's a --help
    vals, extra = parser.parse_known_args(args)

    config = ConfigManager([
        ConfigObjEnv(vals),

        # FIXME(willkg): It'd be better if this was an INI file.
        ConfigEnvFileEnv(vals.config),
    ])

    # Now go through and make sure all the required options were supplied.
    missing_opts = []
    parse_errors = []
    comp_config = config.with_options(app)
    for opt in options:
        try:
            comp_config(opt.key.lower())
        except ConfigurationMissingError as cme:
            missing_opts.append(opt.key.lower())
        except Exception as exc:
            parse_errors.append((opt.key.lower(), str(exc)))

    if missing_opts:
        parser.print_usage(sys.stderr)
        print_error('the following are required: %s\n' %
                    ', '.join([opt for opt in missing_opts]))
        return 2

    if parse_errors:
        parser.print_usage(sys.stderr)
        print_error('the following have value errors:\n')
        for opt, msg in parse_errors:
            print_error('%s:\n%s\n' % (opt, indent(msg)))
        return 2

    return vals.handler(config).invoke()