]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Keep track of collection resets from CLI arguments (fixes #3208)
authorSeptatrix <24257556+Septatrix@users.noreply.github.com>
Wed, 20 Nov 2024 22:10:45 +0000 (23:10 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 21 Nov 2024 13:36:38 +0000 (14:36 +0100)
Previously it was only possible to completely reset but not append,
or only append but not reset to collection/list settings
via command line arguments.
Now we track if a setting has ever been set to None (i.e. reset)
during command line parsing.
This information is used during value finalization
to decide whether to merge both collections or only keep the CLI value.

mkosi/config.py
tests/test_config.py

index ca88a1e3ec6a95f3c71eede3a2727b4f6834213a..0cb6cb336676f8f0aabf2fd64f2a305805d3fe3a 100644 (file)
@@ -3950,11 +3950,14 @@ class ConfigAction(argparse.Action):
         s = SETTINGS_LOOKUP_BY_DEST[self.dest]
 
         if values is None or isinstance(values, str):
-            setattr(namespace, s.dest, s.parse(values, getattr(namespace, self.dest, None)))
-        else:
-            for v in values:
-                assert isinstance(v, str)
-                setattr(namespace, s.dest, s.parse(v, getattr(namespace, self.dest, None)))
+            values = [values]
+
+        for v in values:
+            assert isinstance(v, str) or v is None
+            parsed_value = s.parse(v, getattr(namespace, self.dest, None))
+            if parsed_value is None:
+                setattr(namespace, f"{s.dest}_was_none", True)
+            setattr(namespace, s.dest, parsed_value)
 
 
 class ParseContext:
@@ -4066,8 +4069,10 @@ class ParseContext:
         # If a value was specified on the CLI, it always takes priority. If the setting is a collection of
         # values, we merge the value from the CLI with the value from the configuration, making sure that the
         # value from the CLI always takes priority.
-        if hasattr(self.cli, setting.dest) and (v := getattr(self.cli, setting.dest)) is not None:
-            if isinstance(v, list):
+        if (v := getattr(self.cli, setting.dest, None)) is not None:
+            if getattr(self.cli, f"{setting.dest}_was_none", False):
+                return v
+            elif isinstance(v, list):
                 return (getattr(self.config, setting.dest, None) or []) + v
             elif isinstance(v, dict):
                 return (getattr(self.config, setting.dest, None) or {}) | v
index 13765dcedeecdcaaba74966db794d7dada8f0f07..f572739b2f19a6557d028fbaed2bfbe1710a0b77 100644 (file)
@@ -1341,3 +1341,27 @@ def test_split_artifacts_compat(tmp_path: Path) -> None:
     with chdir(d):
         _, [config] = parse_config()
         assert config.split_artifacts == ArtifactOutput.compat_yes()
+
+
+def test_cli_collection_reset(tmp_path: Path) -> None:
+    d = tmp_path
+
+    (d / "mkosi.conf").write_text(
+        """
+        [Content]
+        Packages=abc
+        """
+    )
+
+    with chdir(d):
+        _, [config] = parse_config(["--package", ""])
+        assert config.packages == []
+
+        _, [config] = parse_config(["--package", "", "--package", "foo"])
+        assert config.packages == ["foo"]
+
+        _, [config] = parse_config(["--package", "foo", "--package", "", "--package", "bar"])
+        assert config.packages == ["bar"]
+
+        _, [config] = parse_config(["--package", "foo", "--package", ""])
+        assert config.packages == []