]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Unify the parsers for the path options
authorGeorges Discry <georges@discry.be>
Thu, 20 Apr 2023 20:09:56 +0000 (22:09 +0200)
committerGeorges Discry <georges@discry.be>
Fri, 21 Apr 2023 12:31:36 +0000 (14:31 +0200)
There were several parsers for path options/arguments, each with their
own implementation. They now all use `parse_path` internally.

mkosi/config.py

index ebb8cc8313db29acb31e217a40777e7cdd84e638..9be1f54c9f127a3aa23c427220122c4f540b0de9 100644 (file)
@@ -3,6 +3,7 @@ import configparser
 import dataclasses
 import enum
 import fnmatch
+import functools
 import os
 import platform
 import sys
@@ -44,13 +45,28 @@ def parse_boolean(s: str) -> bool:
     die(f"Invalid boolean literal: {s!r}")
 
 
+def parse_path(value: str, *, required: bool, absolute: bool = True) -> Path:
+    path = Path(value)
+
+    if required and not path.exists():
+        die(f"{value} does not exist")
+
+    if absolute:
+        path = path.absolute()
+
+    return path
+
+
 def parse_source_target_paths(value: str) -> tuple[Path, Optional[Path]]:
     src, _, target = value.partition(':')
-    if not Path(src).exists():
-        die(f"{src} does not exist")
-    if target and not Path(target).is_absolute():
-        die("Target path must be absolute")
-    return Path(src).absolute(), Path(target) if target else None
+    src_path = parse_path(src, required=True)
+    if target:
+        target_path = parse_path(target, required=False, absolute=False)
+        if not target_path.is_absolute():
+            die("Target path must be absolute")
+    else:
+        target_path = None
+    return src_path, target_path
 
 
 def config_parse_string(dest: str, value: Optional[str], namespace: argparse.Namespace) -> Optional[str]:
@@ -69,12 +85,12 @@ def config_parse_script(dest: str, value: Optional[str], namespace: argparse.Nam
         return getattr(namespace, dest) # type: ignore
 
     if value:
-        if not Path(value).exists():
-            die(f"{value} does not exist")
-        if not os.access(value, os.X_OK):
+        path = parse_path(value, required=True)
+        if not os.access(path, os.X_OK):
             die(f"{value} is not executable")
+        return path
 
-    return Path(value).absolute() if value else None
+    return None
 
 
 def config_parse_boolean(dest: str, value: Optional[str], namespace: argparse.Namespace) -> bool:
@@ -197,26 +213,25 @@ def config_make_list_parser(delimiter: str, parse: Callable[[str], Any] = str) -
     return config_parse_list
 
 
-def make_path_parser(required: bool) -> Callable[[str], Path]:
-    def parse_path(value: str) -> Path:
-        if required and not Path(value).exists():
-            die(f"{value} does not exist")
-
-        return Path(value).absolute()
-
-    return parse_path
+def make_path_parser(*, required: bool, absolute: bool = True) -> Callable[[str], Path]:
+    return functools.partial(
+        parse_path,
+        required=required,
+        absolute=absolute,
+    )
 
 
-def config_make_path_parser(required: bool, absolute: bool = True) -> ConfigParseCallback:
+def config_make_path_parser(*, required: bool, absolute: bool = True) -> ConfigParseCallback:
     def config_parse_path(dest: str, value: Optional[str], namespace: argparse.Namespace) -> Optional[Path]:
         if dest in namespace:
             return getattr(namespace, dest) # type: ignore
 
-        if value and required and not Path(value).exists():
-            die(f"{value} does not exist")
-
         if value:
-            return Path(value).absolute() if absolute else Path(value)
+            return parse_path(
+                value,
+                required=required,
+                absolute=absolute,
+            )
 
         return None