예제 #1
0
def load_config(
        conf_files: t.Union[t.Iterable[str], str, None] = None) -> t.Dict:
    """
    Load configuration.

    Load configuration from all found conf files.  The default configuration is loaded
    followed by a system-wide location, user-location, and then any files specified in
    the ``conf_files`` parameter.  Toplevel keys in later files will overwrite earlier
    those same keys in earlier files.

    :arg conf_files: An iterable of conf_files to load configuration information from.
    :returns: A dict containing the configuration.
    """
    flog = mlog.fields(func='load_config')
    flog.debug('Enter')

    if isinstance(conf_files, str):
        conf_files = (conf_files, )
    elif conf_files is None:
        conf_files = ()

    user_config_file = os.path.expanduser(USER_CONFIG_FILE)
    available_files = find_config_files(
        itertools.chain((SYSTEM_CONFIG_FILE, user_config_file), conf_files))

    includes = list(available_files)

    flog.debug('loading config files')
    # Perky has some bugs that prevent this simple way from working:
    # https://github.com/ansible-community/antsibull/pull/118
    # cfg = {'includes': includes}
    # cfg = perky.includes(cfg, recursive=True)

    # Workaround for above bug.  Note that includes specified in the config files will not work
    # but we can just add that as a new feature when perky gets it working.
    cfg = {}
    for filename in includes:
        new_cfg = perky.load(filename)
        cfg.update(new_cfg)

    flog.debug('validating configuration')
    # Note: We parse the object but discard the model because we want to validate the config but let
    # the context handle all setting of defaults
    ConfigModel.parse_obj(cfg)

    flog.fields(config=cfg).debug('Leave')
    return cfg
예제 #2
0
def read_config(filename: str) -> ConfigModel:
    """
    Parse a config file and return the data from it.

    :arg filename: The filename of the config file to parse.
    :returns: A ConfigModel model containing the config data.
    """
    flog = mlog.fields(func='read_config')
    flog.debug('Enter')

    filename = os.path.abspath(filename)

    flog.fields(filename=filename).info('loading config file')
    raw_config_data = perky.load(filename)
    flog.debug('Validatinging the config file data')
    # Note: We parse the object but discard the model because we want to validate the config but let
    # the context handle all setting of defaults
    ConfigModel.parse_obj(raw_config_data)

    flog.debug('Leave')
    return raw_config_data
예제 #3
0
 def test_perky_include_nested(self):
     with perky.pushd("include_nested"):
         root = perky.load("main.pky",
                           pragmas={'include': perky.pragma_include()})
     self.assertEqual(
         root, {
             'a': '1',
             'b': {
                 'ba': '1',
                 'bb': '2',
                 'bc': '3',
                 'bd': '4',
                 'nested_dict': {
                     'x': '3',
                     'y': '2',
                     'z': ['1', '2', '3', '4']
                 },
                 'nested_list': ['a', 'b', 'c'],
             },
             'c': '3',
             'd': '4'
         })
예제 #4
0
 def test_perky_include_path(self):
     with perky.pushd("include_path"):
         root = perky.load(
             "dir1/main.pky",
             pragmas={'include': perky.pragma_include(['dir1', 'dir2'])})
     self.assertEqual(root, dict(zip("abc", "345")))
예제 #5
0
 def test_perky_include_dict(self):
     with perky.pushd("include_dict"):
         root = perky.load("main.pky",
                           pragmas={'include': perky.pragma_include()})
     self.assertEqual(root, dict(zip("abcd", "1234")))
예제 #6
0
 def test_perky_include_list(self):
     with perky.pushd("include_list"):
         root = perky.load("main.pky",
                           root=[],
                           pragmas={'include': perky.pragma_include()})
     self.assertEqual(root, list("abcd"))
예제 #7
0
 def test_read_file(self):
     test_input = perky.load("test_input.txt", encoding="utf-8")
     self.assertIsNotNone(self, test_input)