2626import hmac
2727import logging
2828import sys
29- from typing import Any , Callable
29+ from typing import Any , Callable , Iterable , TextIO
3030
3131import requests
3232import yaml
@@ -244,6 +244,7 @@ def main() -> None:
244244 group .add_argument (
245245 "-c" ,
246246 "--config" ,
247+ action = "append" ,
247248 type = argparse .FileType ("r" ),
248249 help = "Path to server config file. Used to read in shared secret." ,
249250 )
@@ -264,7 +265,7 @@ def main() -> None:
264265
265266 config : dict [str , Any ] | None = None
266267 if "config" in args and args .config :
267- config = yaml . safe_load (args .config )
268+ config = _read_config_files (args .config )
268269
269270 if args .shared_secret :
270271 secret = args .shared_secret
@@ -326,6 +327,33 @@ def main() -> None:
326327 )
327328
328329
330+ # Adapted from synapse.config._base.
331+ def _read_config_files (config_files : Iterable [TextIO ]) -> dict [str , Any ]:
332+ """Read the config files and shallowly merge them into a dict.
333+
334+ Successive configurations are shallowly merged into ones provided earlier,
335+ i.e., entirely replacing top-level sections of the configuration.
336+
337+ Args:
338+ config_files: A list of the config files to read
339+
340+ Returns:
341+ The configuration dictionary.
342+ """
343+ specified_config = {}
344+ for config_file in config_files :
345+ yaml_config = yaml .safe_load (config_file )
346+
347+ if not isinstance (yaml_config , dict ):
348+ err = "File %r is empty or doesn't parse into a key-value map. IGNORING."
349+ print (err % (config_file ,))
350+ continue
351+
352+ specified_config .update (yaml_config )
353+
354+ return specified_config
355+
356+
329357def _read_file (file_path : Any , config_path : str ) -> str :
330358 """Check the given file exists, and read it into a string
331359
0 commit comments