diff --git a/mkosi/config.py b/mkosi/config.py index c966260a86..268ca4966b 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -1768,6 +1768,7 @@ class Args: cmdline: list[str] force: int directory: Optional[Path] + default_config: Optional[Path] debug: bool debug_shell: bool debug_workspace: bool @@ -4328,6 +4329,14 @@ def create_argument_parser(chdir: bool = True) -> argparse.ArgumentParser: help="Change to specified directory before doing anything", metavar="PATH", ) + parser.add_argument( + "--default", + dest="default_config", + help="Use a specific configuration file as the entry point, allowing to set various defaults", + type=Path, + default=None, + metavar="PATH", + ) parser.add_argument( "--debug", help="Turn on debugging output", @@ -4412,10 +4421,6 @@ def create_argument_parser(chdir: bool = True) -> argparse.ArgumentParser: nargs=0, action=IgnoreAction, ) - parser.add_argument( - "--default", - action=IgnoreAction, - ) parser.add_argument( "--cache", action=IgnoreAction, @@ -4531,6 +4536,7 @@ def __call__( class ParseContext: def __init__(self, resources: Path = Path("/")) -> None: + self.default_config: Optional[Path] = None self.resources = resources # We keep two namespaces around, one for the settings specified on the CLI and one for # the settings specified in configuration files. This is required to implement both [Match] @@ -4810,10 +4816,14 @@ def parse_config_one(self, path: Path, parse_profiles: bool = False, parse_local if extras: if parse_local: - for localpath in ( - *([p] if (p := path.parent / "mkosi.local").is_dir() else []), - *([p] if (p := path.parent / "mkosi.local.conf").is_file() else []), - ): + localpaths = [] + if (p := path.parent / "mkosi.local").is_dir(): + localpaths.append(p) + if (p := path.parent / "mkosi.local.conf").is_file(): + localpaths.append(p) + if self.default_config is not None and self.default_config.is_file(): + localpaths.append(self.default_config) + for localpath in localpaths: with chdir(localpath if localpath.is_dir() else Path.cwd()): self.parse_config_one(localpath if localpath.is_file() else Path.cwd()) @@ -5146,6 +5156,15 @@ def parse_config( # One of the specifiers needs access to the directory, so make sure it is available. context.config["directory"] = args.directory + # Config paths need to be absolute - as a special case, if it is not, look in the parent + # of --directory. This works nicely on OBS, where the --directory is the git repository + # and the --default is the mkosi.conf selected at source service time, placed in the parent. + if args.default_config is not None: + if args.directory is not None and not args.default_config.is_absolute(): + context.default_config = args.directory.parent / args.default_config + else: + context.default_config = args.default_config + context.parse_new_includes() context.config["files"] = [] diff --git a/mkosi/resources/man/mkosi.1.md b/mkosi/resources/man/mkosi.1.md index feea867a98..867b7359fa 100644 --- a/mkosi/resources/man/mkosi.1.md +++ b/mkosi/resources/man/mkosi.1.md @@ -256,6 +256,12 @@ Those settings cannot be configured in the configuration files. working directory. If the empty string is specified, all configuration in the current working directory will be ignored. +`--default=` +: Takes an absolute path to a configuration file. **mkosi** parses this file + before doing anything. This allows a user to select an entry point to + programmatically decide among various available options (e.g.: profiles) + without having to select them on the command line. + `--debug` : Enable additional debugging output. diff --git a/tests/test_json.py b/tests/test_json.py index 2fc1925f6a..7a2a073563 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -61,6 +61,7 @@ def test_args(path: Optional[Path]) -> None: "DebugSandbox": false, "DebugShell": false, "DebugWorkspace": false, + "DefaultConfig": null, "Directory": {f'"{os.fspath(path)}"' if path is not None else "null"}, "DocFormat": "auto", "Force": 9001, @@ -82,6 +83,7 @@ def test_args(path: Optional[Path]) -> None: debug_sandbox=False, debug_shell=False, debug_workspace=False, + default_config=None, directory=Path(path) if path is not None else None, doc_format=DocFormat.auto, force=9001,