settings_lookup_by_name = {name: s for s in SETTINGS for name in [s.name, *s.compat_names]}
settings_lookup_by_dest = {s.dest: s for s in SETTINGS}
match_lookup = {m.name: m for m in MATCHES}
+ # Compare inodes instead of paths so we can't get tricked by bind mounts and such.
+ parsed_includes: set[tuple[int, int]] = set()
@contextlib.contextmanager
def parse_new_includes(
finally:
# Parse any includes that were added after yielding.
for p in getattr(namespace, "include", [])[l:]:
+ st = p.stat()
+
+ if (st.st_dev, st.st_ino) in parsed_includes:
+ continue
+
parse_config(p, namespace, defaults)
+ parsed_includes.add((st.st_dev, st.st_ino))
class MkosiAction(argparse.Action):
def __call__(
configuration is included after parsing all the other configuration
files.
+: Note that each path containing extra configuration is only parsed
+ once, even if included more than once with `Include=`.
+
### [Preset] Section
`Presets=`, `--preset=`
"""\
[Content]
Bootable=yes
+ BuildPackages=abc
"""
)
(tmp_path / "abc/mkosi.conf.d").mkdir()
assert config.split_artifacts == False
# Passing the directory should include both the main config file and the dropin.
- _, [config] = parse_config(["--include", os.fspath(tmp_path / "abc")])
+ _, [config] = parse_config(["--include", os.fspath(tmp_path / "abc")] * 2)
assert config.bootable == ConfigFeature.enabled
assert config.split_artifacts == True
+ # The same extra config should not be parsed more than once.
+ assert config.build_packages == ["abc"]
# Passing the main config file should not include the dropin.
_, [config] = parse_config(["--include", os.fspath(tmp_path / "abc/mkosi.conf")])