def apply_gin_configs(
    config_folders: Path | list[Path],
    configs: list[str] = None,
    overrides: list[str] = None,
    skip_unknown: bool = False,
    finalize_config=False,
    mandatory_folders: list[Path] = None,
    mutually_exclusive_folders: list[Path] = None,
):
    """
    Apply gin configuration files and bindings.

    Parameters
    ----------
    configs_folder : Path
        The path to the toplevel folder containing the gin configuration files.
    configs : list[str]
        A list of filenames to find within the configs_folder.
    overrides : list[str]
        A list of gin-formatted pairs to override the configs with.
    skip_unknown : bool
        If True, ignore errors for configs that were set by the user but not used anywhere
    mandatory_folders : list[Path]
        For each folder in the list, at least one config file must be loaded from that folder.
    mutually_exclusive_folders : list[Path]
        For each folder in the list, at most one config file must be loaded from that folder.

    """

    if configs is None:
        configs = []
    if overrides is None:
        overrides = []
    if mandatory_folders is None:
        mandatory_folders = []
    if mutually_exclusive_folders is None:
        mutually_exclusive_folders = []

    if not isinstance(config_folders, list):
        config_folders = [config_folders]

    root = infinigen.repo_root()

    def find_config(p):
        p = Path(p)
        for folder_rel in config_folders:
            folder = root / folder_rel

            if not folder.exists():
                raise ValueError(
                    f"{apply_gin_configs.__name__} got bad {folder_rel=}, {folder=} did not exist"
                )

            for file in folder.glob("**/*.gin"):
                if file.stem == p.stem:
                    logger.debug(f"Resolved {p} to file {file}")
                    return file
            logger.debug(f"Could not find {p} in {folder}")

        raise FileNotFoundError(
            f"Could not find {p} or {p.stem} in any of {config_folders}"
        )

    configs = [find_config(g) for g in ["base.gin"] + configs]
    overrides = [sanitize_override(o) for o in overrides]

    for mandatory_folder in mandatory_folders:
        mandatory_folder = resolve_folder_maybe_relative(mandatory_folder, root)
        if not contained_stems(configs, mandatory_folder):
            raise FileNotFoundError(
                f"At least one config file must be loaded from {mandatory_folder} to avoid unexpected behavior"
            )

    for mutex_folder in mutually_exclusive_folders:
        mutex_folder = resolve_folder_maybe_relative(mutex_folder, root)
        stems = {s.stem for s in mutex_folder.iterdir()}
        config_stems = {s.stem for s in configs}
        both = stems.intersection(config_stems)
        if len(both) > 1:
            raise ValueError(
                f"At most one config file must be loaded from {mutex_folder} to avoid unexpected behavior, instead got {both=}"
            )

    with LogLevel(logger=logging.getLogger(), level=logging.WARNING):
        gin.parse_config_files_and_bindings(
            configs,
            bindings=overrides,
            skip_unknown=skip_unknown,
            finalize_config=finalize_config,
        )

    Apply gin configuration files and bindings.

    Parameters
    ----------
    configs_folder : Path
        The path to the toplevel folder containing the gin configuration files.
    configs : list[str]
        A list of filenames to find within the configs_folder.
    overrides : list[str]
        A list of gin-formatted pairs to override the configs with.
    skip_unknown : bool
        If True, ignore errors for configs that were set by the user but not used anywhere
    mandatory_folders : list[Path]
        For each folder in the list, at least one config file must be loaded from that folder.
    mutually_exclusive_folders : list[Path]
        For each folder in the list, at most one config file must be loaded from that folder.

    
infinigen/core/init.py