def parse_config(argv: Sequence[str] = ()) -> tuple[MkosiArgs, tuple[MkosiConfig, ...]]:
# Compare inodes instead of paths so we can't get tricked by bind mounts and such.
parsed_includes: set[tuple[int, int]] = set()
+ immutable_settings: set[str] = set()
def expand_specifiers(text: str, namespace: argparse.Namespace, defaults: argparse.Namespace) -> str:
percent = False
if not (s := SETTINGS_LOOKUP_BY_NAME.get(name)):
die(f"Unknown setting {k}")
+ if name in immutable_settings:
+ die(f"Setting {name} cannot be modified anymore at this point")
if section != s.section:
logging.warning(f"Setting {k} should be configured in [{s.section}], not [{section}].")
finalize_default(SETTINGS_LOOKUP_BY_DEST["presets"], namespace, defaults)
include = getattr(namespace, "presets")
+ immutable_settings.add("Presets")
if Path("mkosi.presets").exists():
for p in Path("mkosi.presets").iterdir():