Skip to content

Commit

Permalink
configuration: Allow including multiple files into one mapping.
Browse files Browse the repository at this point in the history
The key for 'include#' can now be either a scalar or a list.
A scalar triggers the same behaviour as before.
If the value is a list it must be a list of scalars (filepaths).
The paths will be loaded and merged in order, and finally the resulting
dict is included into the current scope.
  • Loading branch information
Fabian Gruber authored and marcbonnici committed Mar 29, 2024
1 parent b6ecc18 commit 4839ab3
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions wa/framework/configuration/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,20 +238,47 @@ def _load_file(filepath, error_name):
return raw, includes


def _config_values_from_includes(filepath, include_path, error_name):
source_dir = os.path.dirname(filepath)
included_files = []

if isinstance(include_path, str):
include_path = os.path.expanduser(os.path.join(source_dir, include_path))

replace_value, includes = _load_file(include_path, error_name)

included_files.append(include_path)
included_files.extend(includes)
elif isinstance(include_path, list):
replace_value = {}

for path in include_path:
include_path = os.path.expanduser(os.path.join(source_dir, path))

sub_replace_value, includes = _load_file(include_path, error_name)
for key, val in sub_replace_value.items():
replace_value[key] = merge_config_values(val, replace_value.get(key, None))

included_files.append(include_path)
included_files.extend(includes)
else:
message = "{} does not contain a valid {} structure; value for 'include#' must be a string or a list"
raise ConfigError(message.format(filepath, error_name))

return replace_value, included_files


def _process_includes(raw, filepath, error_name):
if not raw:
return []

source_dir = os.path.dirname(filepath)
included_files = []
replace_value = None

if hasattr(raw, 'items'):
for key, value in raw.items():
if key == 'include#':
include_path = os.path.expanduser(os.path.join(source_dir, value))
included_files.append(include_path)
replace_value, includes = _load_file(include_path, error_name)
replace_value, includes = _config_values_from_includes(filepath, value, error_name)
included_files.extend(includes)
elif hasattr(value, 'items') or isiterable(value):
includes = _process_includes(value, filepath, error_name)
Expand Down

0 comments on commit 4839ab3

Please sign in to comment.