diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py index da444403bff1..abb136321a3f 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py @@ -27,6 +27,7 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa default=0, help="Enable verbose logging (includes nix)", ) + common_flags.add_argument("--quiet", action="count", default=0) common_flags.add_argument("--max-jobs", "-j") common_flags.add_argument("--cores") common_flags.add_argument("--log-format") @@ -34,12 +35,11 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa common_flags.add_argument("--keep-failed", "-K", action="store_true") common_flags.add_argument("--fallback", action="store_true") common_flags.add_argument("--repair", action="store_true") - common_flags.add_argument("--option", nargs=2) + common_flags.add_argument("--option", nargs=2, action="append") common_build_flags = argparse.ArgumentParser(add_help=False) common_build_flags.add_argument("--builders") common_build_flags.add_argument("--include", "-I", action="append") - common_build_flags.add_argument("--quiet", action="store_true") common_build_flags.add_argument("--print-build-logs", "-L", action="store_true") common_build_flags.add_argument("--show-trace", action="store_true") @@ -54,8 +54,8 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa flake_common_flags.add_argument("--no-write-lock-file", action="store_true") flake_common_flags.add_argument("--no-registries", action="store_true") flake_common_flags.add_argument("--commit-lock-file", action="store_true") - flake_common_flags.add_argument("--update-input") - flake_common_flags.add_argument("--override-input", nargs=2) + flake_common_flags.add_argument("--update-input", action="append") + flake_common_flags.add_argument("--override-input", nargs=2, action="append") classic_build_flags = argparse.ArgumentParser(add_help=False) classic_build_flags.add_argument("--no-build-output", "-Q", action="store_true") diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py index 267ac3357450..c79052f3752f 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py @@ -52,7 +52,7 @@ class BuildAttr: attr: str | None def to_attr(self, *attrs: str) -> str: - return f"{self.attr + '.' if self.attr else ''}{".".join(attrs)}" + return f"{self.attr + '.' if self.attr else ''}{'.'.join(attrs)}" @classmethod def from_arg(cls, attr: str | None, file: str | None) -> Self: @@ -68,7 +68,7 @@ class Flake: _re: ClassVar = re.compile(r"^(?P[^\#]*)\#?(?P[^\#\"]*)$") def to_attr(self, *attrs: str) -> str: - return f"{self}.{".".join(attrs)}" + return f"{self}.{'.'.join(attrs)}" @override def __str__(self) -> str: @@ -83,7 +83,7 @@ class Flake: m = cls._re.match(flake_str) assert m is not None, f"got no matches for {flake_str}" attr = m.group("attr") - nixos_attr = f"nixosConfigurations.{attr or hostname_fn() or "default"}" + nixos_attr = f"nixosConfigurations.{attr or hostname_fn() or 'default'}" path = m.group("path") if ":" in path: return cls(path, nixos_attr) diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py index 54c8b71036e9..8905ab274508 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py @@ -15,7 +15,7 @@ SSH_DEFAULT_OPTS: Final = [ "-o", "ControlMaster=auto", "-o", - f"ControlPath={tmpdir.TMPDIR_PATH / "ssh-%n"}", + f"ControlPath={tmpdir.TMPDIR_PATH / 'ssh-%n'}", "-o", "ControlPersist=60", ] diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/utils.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/utils.py index 6fbf53a8c00b..5a53d2d7ef37 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/utils.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/utils.py @@ -2,7 +2,7 @@ import logging from collections.abc import Mapping, Sequence from typing import Any, assert_never, override -type Arg = bool | str | list[str] | int | None +type Arg = bool | str | list[str] | list[list[str]] | int | None type Args = dict[str, Arg] @@ -43,9 +43,13 @@ def dict_to_flags(d: Args | None) -> list[str]: flags.append(flag) flags.append(value) case list(): - for v in value: + for vs in value: flags.append(flag) - flags.append(v) + if isinstance(vs, list): + for v in vs: + flags.append(v) + else: + flags.append(vs) case _: assert_never(value) return flags diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py index 858916b682c9..ba67fa838578 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py @@ -40,8 +40,21 @@ def test_parse_args() -> None: "--flake", "/etc/nixos", "--option", - "foo", - "bar", + "foo1", + "bar1", + "--option", + "foo2", + "bar2", + "--override-input", + "override1", + "input1", + "--override-input", + "override2", + "input2", + "--update-input", + "input1", + "--update-input", + "input2", ] ) assert nr.logger.level == logging.INFO @@ -50,8 +63,27 @@ def test_parse_args() -> None: assert r1.install_grub is True assert r1.profile_name == "system" assert r1.action == "switch" - assert r1.option == ["foo", "bar"] - assert g1["common_flags"].option == ["foo", "bar"] + # round-trip test (ensure that we have the same flags as parsed) + assert nr.utils.dict_to_flags(vars(g1["common_flags"])) == [ + "--option", + "foo1", + "bar1", + "--option", + "foo2", + "bar2", + ] + assert nr.utils.dict_to_flags(vars(g1["flake_common_flags"])) == [ + "--update-input", + "input1", + "--update-input", + "input2", + "--override-input", + "override1", + "input1", + "--override-input", + "override2", + "input2", + ] r2, g2 = nr.parse_args( [ @@ -63,7 +95,13 @@ def test_parse_args() -> None: "foo", "--attr", "bar", + "-I", + "include1", + "-I", + "include2", "-vvv", + "--quiet", + "--quiet", ] ) assert nr.logger.level == logging.DEBUG @@ -72,7 +110,18 @@ def test_parse_args() -> None: assert r2.action == "dry-build" assert r2.file == "foo" assert r2.attr == "bar" - assert g2["common_flags"].v == 3 + # round-trip test (ensure that we have the same flags as parsed) + assert nr.utils.dict_to_flags(vars(g2["common_flags"])) == [ + "-vvv", + "--quiet", + "--quiet", + ] + assert nr.utils.dict_to_flags(vars(g2["common_build_flags"])) == [ + "--include", + "include1", + "--include", + "include2", + ] @patch.dict(nr.process.os.environ, {}, clear=True) @@ -292,6 +341,10 @@ def test_execute_nix_switch_flake(mock_run: Any, tmp_path: Path) -> None: "--sudo", "--verbose", "--fast", + # https://github.com/NixOS/nixpkgs/issues/374050 + "--option", + "narinfo-cache-negative-ttl", + "1200", ] ) @@ -307,6 +360,9 @@ def test_execute_nix_switch_flake(mock_run: Any, tmp_path: Path) -> None: "--print-out-paths", "/path/to/config#nixosConfigurations.hostname.config.system.build.toplevel", "-v", + "--option", + "narinfo-cache-negative-ttl", + "1200", "--no-link", ], check=True, diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_utils.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_utils.py index cfa224478053..e06c6c73c38c 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_utils.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_utils.py @@ -11,10 +11,11 @@ def test_dict_to_flags() -> None: "test_flag_2": False, "test_flag_3": "value", "test_flag_4": ["v1", "v2"], - "test_flag_5": None, + "test_flag_5": [["o1", "v1"], ["o2", "v2"]], + "test_flag_6": None, "t": True, "v": 5, - "verbose": 2, + "quiet": 2, } ) assert r1 == [ @@ -25,10 +26,16 @@ def test_dict_to_flags() -> None: "v1", "--test-flag-4", "v2", + "--test-flag-5", + "o1", + "v1", + "--test-flag-5", + "o2", + "v2", "-t", "-vvvvv", - "--verbose", - "--verbose", + "--quiet", + "--quiet", ] r2 = u.dict_to_flags({"verbose": 0, "empty_list": []}) assert r2 == []