Loading pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py +41 −33 Original line number Diff line number Diff line Loading @@ -43,19 +43,19 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa common_build_flags.add_argument("--print-build-logs", "-L", action="store_true") common_build_flags.add_argument("--show-trace", action="store_true") flake_build_flags = argparse.ArgumentParser(add_help=False) flake_build_flags.add_argument("--accept-flake-config", action="store_true") flake_build_flags.add_argument("--refresh", action="store_true") flake_build_flags.add_argument("--impure", action="store_true") flake_build_flags.add_argument("--offline", action="store_true") flake_build_flags.add_argument("--no-net", action="store_true") flake_build_flags.add_argument("--recreate-lock-file", action="store_true") flake_build_flags.add_argument("--no-update-lock-file", action="store_true") flake_build_flags.add_argument("--no-write-lock-file", action="store_true") flake_build_flags.add_argument("--no-registries", action="store_true") flake_build_flags.add_argument("--commit-lock-file", action="store_true") flake_build_flags.add_argument("--update-input") flake_build_flags.add_argument("--override-input", nargs=2) flake_common_flags = argparse.ArgumentParser(add_help=False) flake_common_flags.add_argument("--accept-flake-config", action="store_true") flake_common_flags.add_argument("--refresh", action="store_true") flake_common_flags.add_argument("--impure", action="store_true") flake_common_flags.add_argument("--offline", action="store_true") flake_common_flags.add_argument("--no-net", action="store_true") flake_common_flags.add_argument("--recreate-lock-file", action="store_true") flake_common_flags.add_argument("--no-update-lock-file", action="store_true") 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) classic_build_flags = argparse.ArgumentParser(add_help=False) classic_build_flags.add_argument("--no-build-output", "-Q", action="store_true") Loading @@ -74,7 +74,7 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa sub_parsers = { "common_flags": common_flags, "common_build_flags": common_build_flags, "flake_build_flags": flake_build_flags, "flake_common_flags": flake_common_flags, "classic_build_flags": classic_build_flags, "copy_flags": copy_flags, } Loading Loading @@ -262,8 +262,8 @@ def parse_args( def reexec( argv: list[str], args: argparse.Namespace, build_flags: dict[str, Args], flake_build_flags: dict[str, Args], build_flags: Args, flake_build_flags: Args, ) -> None: drv = None attr = "config.system.build.nixos-rebuild" Loading @@ -271,10 +271,18 @@ def reexec( # Parsing the args here but ignore ask_sudo_password since it is not # needed and we would end up asking sudo password twice if flake := Flake.from_arg(args.flake, Remote.from_arg(args.target_host, None)): drv = nix.build_flake(attr, flake, **flake_build_flags, no_link=True) drv = nix.build_flake( attr, flake, flake_build_flags | {"no_link": True}, ) else: build_attr = BuildAttr.from_arg(args.attr, args.file) drv = nix.build(attr, build_attr, **build_flags, no_out_link=True) drv = nix.build( attr, build_attr, build_flags | {"no_out_link": True}, ) except CalledProcessError: logger.warning( "could not build a newer version of nixos-rebuild, " Loading Loading @@ -319,7 +327,8 @@ def execute(argv: list[str]) -> None: common_flags = vars(args_groups["common_flags"]) common_build_flags = common_flags | vars(args_groups["common_build_flags"]) build_flags = common_build_flags | vars(args_groups["classic_build_flags"]) flake_build_flags = common_build_flags | vars(args_groups["flake_build_flags"]) flake_common_flags = common_flags | vars(args_groups["flake_common_flags"]) flake_build_flags = common_build_flags | flake_common_flags copy_flags = common_flags | vars(args_groups["copy_flags"]) if args.upgrade or args.upgrade_all: Loading Loading @@ -350,7 +359,7 @@ def execute(argv: list[str]) -> None: flake = Flake.from_arg(args.flake, target_host) if can_run and not flake: nixpkgs_path = nix.find_file("nixpkgs", **build_flags) nixpkgs_path = nix.find_file("nixpkgs", build_flags) rev = nix.get_nixpkgs_rev(nixpkgs_path) if nixpkgs_path and rev: (nixpkgs_path / ".version-suffix").write_text(rev) Loading @@ -370,7 +379,10 @@ def execute(argv: list[str]) -> None: dry_run = action == Action.DRY_BUILD no_link = action in (Action.SWITCH, Action.BOOT) build_flags |= {"no_out_link": no_link, "dry_run": dry_run} flake_build_flags |= {"no_link": no_link, "dry_run": dry_run} rollback = bool(args.rollback) match action: case Action.BUILD_VM: attr = "config.system.build.vm" Loading @@ -395,24 +407,22 @@ def execute(argv: list[str]) -> None: case (_, True, _, _): raise NRError(f"--rollback is incompatible with '{action}'") case (_, False, Remote(_), Flake(_)): path_to_config = nix.remote_build_flake( path_to_config = nix.build_remote_flake( attr, flake, build_host, eval_flags=flake_common_flags, flake_build_flags=flake_build_flags, copy_flags=copy_flags, build_flags=build_flags, ) case (_, False, None, Flake(_)): path_to_config = nix.build_flake( attr, flake, no_link=no_link, dry_run=dry_run, **flake_build_flags, flake_build_flags=flake_build_flags, ) case (_, False, Remote(_), None): path_to_config = nix.remote_build( path_to_config = nix.build_remote( attr, build_attr, build_host, Loading @@ -424,9 +434,7 @@ def execute(argv: list[str]) -> None: path_to_config = nix.build( attr, build_attr, no_out_link=no_link, dry_run=dry_run, **build_flags, build_flags=build_flags, ) case never: # should never happen, but mypy is not smart enough to Loading @@ -442,7 +450,7 @@ def execute(argv: list[str]) -> None: path_to_config, to_host=target_host, from_host=build_host, **copy_flags, copy_flags=copy_flags, ) if action in (Action.SWITCH, Action.BOOT): nix.set_profile( Loading @@ -468,7 +476,7 @@ def execute(argv: list[str]) -> None: f"Done. The virtual machine can be started by running '{vm_path}'" ) case Action.EDIT: nix.edit(flake, **flake_build_flags) nix.edit(flake, flake_build_flags) case Action.DRY_RUN: assert False, "DRY_RUN should be a DRY_BUILD alias" case Action.LIST_GENERATIONS: Loading @@ -488,9 +496,9 @@ def execute(argv: list[str]) -> None: print(tabulate(generations, headers=headers)) case Action.REPL: if flake: nix.repl_flake("toplevel", flake, **flake_build_flags) nix.repl_flake("toplevel", flake, flake_build_flags) else: nix.repl("system", build_attr, **build_flags) nix.repl("system", build_attr, build_flags) case _: assert_never(action) Loading pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/nix.py +22 −21 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ logger = logging.getLogger(__name__) def build( attr: str, build_attr: BuildAttr, **build_flags: Args, build_flags: Args | None = None, ) -> Path: """Build NixOS attribute using classic Nix. Loading @@ -52,7 +52,7 @@ def build( def build_flake( attr: str, flake: Flake, **flake_build_flags: Args, flake_build_flags: Args | None = None, ) -> Path: """Build NixOS attribute using Flakes. Loading @@ -70,13 +70,13 @@ def build_flake( return Path(r.stdout.strip()) def remote_build( def build_remote( attr: str, build_attr: BuildAttr, build_host: Remote | None, build_flags: dict[str, Args] | None = None, instantiate_flags: dict[str, Args] | None = None, copy_flags: dict[str, Args] | None = None, build_flags: Args | None = None, instantiate_flags: Args | None = None, copy_flags: Args | None = None, ) -> Path: # We need to use `--add-root` otherwise Nix will print this warning: # > warning: you did not specify '--add-root'; the result might be removed Loading @@ -89,12 +89,12 @@ def remote_build( build_attr.to_attr(attr), "--add-root", tmpdir.TMPDIR_PATH / uuid4().hex, *dict_to_flags(instantiate_flags or {}), *dict_to_flags(instantiate_flags), ], stdout=PIPE, ) drv = Path(r.stdout.strip()).resolve() copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {})) copy_closure(drv, to_host=build_host, from_host=None, copy_flags=copy_flags) # Need a temporary directory in remote to use in `nix-store --add-root` r = run_wrapper( Loading @@ -109,7 +109,7 @@ def remote_build( drv, "--add-root", remote_tmpdir / uuid4().hex, *dict_to_flags(build_flags or {}), *dict_to_flags(build_flags), ], remote=build_host, stdout=PIPE, Loading @@ -124,13 +124,13 @@ def remote_build( run_wrapper(["rm", "-rf", remote_tmpdir], remote=build_host, check=False) def remote_build_flake( def build_remote_flake( attr: str, flake: Flake, build_host: Remote, flake_build_flags: dict[str, Args] | None = None, copy_flags: dict[str, Args] | None = None, build_flags: dict[str, Args] | None = None, eval_flags: Args | None = None, copy_flags: Args | None = None, flake_build_flags: Args | None = None, ) -> Path: r = run_wrapper( [ Loading @@ -139,12 +139,12 @@ def remote_build_flake( "eval", "--raw", flake.to_attr(attr, "drvPath"), *dict_to_flags(flake_build_flags or {}), *dict_to_flags(eval_flags), ], stdout=PIPE, ) drv = Path(r.stdout.strip()) copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {})) copy_closure(drv, to_host=build_host, from_host=None, copy_flags=copy_flags) r = run_wrapper( [ "nix", Loading @@ -152,7 +152,7 @@ def remote_build_flake( "build", f"{drv}^*", "--print-out-paths", *dict_to_flags(build_flags or {}), *dict_to_flags(flake_build_flags), ], remote=build_host, stdout=PIPE, Loading @@ -164,7 +164,7 @@ def copy_closure( closure: Path, to_host: Remote | None, from_host: Remote | None = None, **copy_flags: Args, copy_flags: Args | None = None, ) -> None: """Copy a nix closure to or from host to localhost. Loading Loading @@ -192,6 +192,7 @@ def copy_closure( [ "nix", "copy", *dict_to_flags(copy_flags), "--from", f"ssh://{from_host.host}", "--to", Loading Loading @@ -221,7 +222,7 @@ def copy_closure( nix_copy_closure(to_host, to=True) def edit(flake: Flake | None, **flake_flags: Args) -> None: def edit(flake: Flake | None, flake_flags: Args | None = None) -> None: "Try to find and open NixOS configuration file in editor." if flake: run_wrapper( Loading Loading @@ -250,7 +251,7 @@ def edit(flake: Flake | None, **flake_flags: Args) -> None: raise NRError("cannot find NixOS config file") def find_file(file: str, **nix_flags: Args) -> Path | None: def find_file(file: str, nix_flags: Args | None = None) -> Path | None: "Find classic Nix file location." r = run_wrapper( ["nix-instantiate", "--find-file", file, *dict_to_flags(nix_flags)], Loading Loading @@ -420,14 +421,14 @@ def list_generations(profile: Profile) -> list[GenerationJson]: ) def repl(attr: str, build_attr: BuildAttr, **nix_flags: Args) -> None: def repl(attr: str, build_attr: BuildAttr, nix_flags: Args | None = None) -> None: run_args = ["nix", "repl", "--file", build_attr.path] if build_attr.attr: run_args.append(build_attr.attr) run_wrapper([*run_args, *dict_to_flags(nix_flags)]) def repl_flake(attr: str, flake: Flake, **flake_flags: Args) -> None: def repl_flake(attr: str, flake: Flake, flake_flags: Args | None = None) -> None: expr = Template( files(__package__).joinpath(FLAKE_REPL_TEMPLATE).read_text() ).substitute( Loading pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/utils.py +7 −3 Original line number Diff line number Diff line import logging from collections.abc import Mapping, Sequence from typing import Any, TypeAlias, assert_never, override from typing import Any, assert_never, override Args: TypeAlias = bool | str | list[str] | int | None type Arg = bool | str | list[str] | int | None type Args = dict[str, Arg] class LogFormatter(logging.Formatter): Loading @@ -19,7 +20,10 @@ class LogFormatter(logging.Formatter): return formatter.format(record) def dict_to_flags(d: Mapping[str, Args]) -> list[str]: def dict_to_flags(d: Args | None) -> list[str]: if not d: return [] flags = [] for key, value in d.items(): flag = f"--{'-'.join(key.split('_'))}" Loading pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py +3 −2 Original line number Diff line number Diff line Loading @@ -123,8 +123,8 @@ def test_execute_nix_boot(mock_run: Any, tmp_path: Path) -> None: "<nixpkgs/nixos>", "--attr", "config.system.build.toplevel", "--no-out-link", "-vvv", "--no-out-link", ], check=True, stdout=PIPE, Loading Loading @@ -188,8 +188,8 @@ def test_execute_nix_switch_flake(mock_run: Any, tmp_path: Path) -> None: "build", "--print-out-paths", "/path/to/config#nixosConfigurations.hostname.config.system.build.toplevel", "--no-link", "-v", "--no-link", ], check=True, stdout=PIPE, Loading Loading @@ -371,6 +371,7 @@ def test_execute_nix_switch_flake_build_host( "build", f"'{config_path}^*'", "--print-out-paths", "--no-link", ], check=True, stdout=PIPE, Loading pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_nix.py +17 −15 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ from .helpers import get_qualified_name ) def test_build(mock_run: Any, monkeypatch: Any) -> None: assert n.build( "config.system.build.attr", m.BuildAttr("<nixpkgs/nixos>", None), nix_flag="foo" "config.system.build.attr", m.BuildAttr("<nixpkgs/nixos>", None), {"nix_flag": "foo"}, ) == Path("/path/to/file") mock_run.assert_called_with( [ Loading Loading @@ -55,8 +57,7 @@ def test_build_flake(mock_run: Any) -> None: assert n.build_flake( "config.system.build.toplevel", flake, no_link=True, nix_flag="foo", {"no_link": True, "nix_flag": "foo"}, ) == Path("/path/to/file") mock_run.assert_called_with( [ Loading @@ -76,7 +77,7 @@ def test_build_flake(mock_run: Any) -> None: @patch(get_qualified_name(n.run_wrapper, n), autospec=True) @patch(get_qualified_name(n.uuid4, n), autospec=True) def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: def test_build_remote(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: build_host = m.Remote("user@host", [], None) monkeypatch.setenv("NIX_SSHOPTS", "--ssh opts") Loading @@ -97,7 +98,7 @@ def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: mock_run.side_effect = run_wrapper_side_effect mock_uuid4.side_effect = [uuid.UUID(int=1), uuid.UUID(int=2)] assert n.remote_build( assert n.build_remote( "config.system.build.toplevel", m.BuildAttr("<nixpkgs/nixos>", "preAttr"), build_host, Loading Loading @@ -164,18 +165,18 @@ def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: autospec=True, return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "), ) def test_remote_build_flake(mock_run: Any, monkeypatch: Any) -> None: def test_build_remote_flake(mock_run: Any, monkeypatch: Any) -> None: flake = m.Flake.parse(".#hostname") build_host = m.Remote("user@host", [], None) monkeypatch.setenv("NIX_SSHOPTS", "--ssh opts") assert n.remote_build_flake( assert n.build_remote_flake( "config.system.build.toplevel", flake, build_host, flake_build_flags={"flake": True}, eval_flags={"flake": True}, copy_flags={"copy": True}, build_flags={"build": True}, flake_build_flags={"build": True}, ) == Path("/path/to/file") mock_run.assert_has_calls( [ Loading Loading @@ -237,9 +238,9 @@ def test_copy_closure(monkeypatch: Any) -> None: monkeypatch.setenv("NIX_SSHOPTS", "--ssh build-opt") with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run: n.copy_closure(closure, None, build_host) n.copy_closure(closure, None, build_host, {"copy_flag": True}) mock_run.assert_called_with( ["nix-copy-closure", "--from", "user@build.host", closure], ["nix-copy-closure", "--copy-flag", "--from", "user@build.host", closure], extra_env={ "NIX_SSHOPTS": " ".join(p.SSH_DEFAULT_OPTS + ["--ssh build-opt"]) }, Loading @@ -251,11 +252,12 @@ def test_copy_closure(monkeypatch: Any) -> None: "NIX_SSHOPTS": " ".join(p.SSH_DEFAULT_OPTS + ["--ssh build-target-opt"]) } with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run: n.copy_closure(closure, target_host, build_host) n.copy_closure(closure, target_host, build_host, {"copy_flag": True}) mock_run.assert_called_with( [ "nix", "copy", "--copy-flag", "--from", "ssh://user@build.host", "--to", Loading Loading @@ -286,7 +288,7 @@ def test_copy_closure(monkeypatch: Any) -> None: def test_edit(mock_run: Any, monkeypatch: Any, tmpdir: Any) -> None: # Flake flake = m.Flake.parse(".#attr") n.edit(flake, commit_lock_file=True) n.edit(flake, {"commit_lock_file": True}) mock_run.assert_called_with( [ "nix", Loading Loading @@ -471,7 +473,7 @@ def test_list_generations(mock_get_generations: Any, tmp_path: Path) -> None: @patch(get_qualified_name(n.run_wrapper, n), autospec=True) def test_repl(mock_run: Any) -> None: n.repl("attr", m.BuildAttr("<nixpkgs/nixos>", None), nix_flag=True) n.repl("attr", m.BuildAttr("<nixpkgs/nixos>", None), {"nix_flag": True}) mock_run.assert_called_with( ["nix", "repl", "--file", "<nixpkgs/nixos>", "--nix-flag"] ) Loading @@ -482,7 +484,7 @@ def test_repl(mock_run: Any) -> None: @patch(get_qualified_name(n.run_wrapper, n), autospec=True) def test_repl_flake(mock_run: Any) -> None: n.repl_flake("attr", m.Flake(Path("flake.nix"), "myAttr"), nix_flag=True) n.repl_flake("attr", m.Flake(Path("flake.nix"), "myAttr"), {"nix_flag": True}) # See nixos-rebuild-ng.tests.repl for a better test, # this is mostly for sanity check assert mock_run.call_count == 1 Loading Loading
pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py +41 −33 Original line number Diff line number Diff line Loading @@ -43,19 +43,19 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa common_build_flags.add_argument("--print-build-logs", "-L", action="store_true") common_build_flags.add_argument("--show-trace", action="store_true") flake_build_flags = argparse.ArgumentParser(add_help=False) flake_build_flags.add_argument("--accept-flake-config", action="store_true") flake_build_flags.add_argument("--refresh", action="store_true") flake_build_flags.add_argument("--impure", action="store_true") flake_build_flags.add_argument("--offline", action="store_true") flake_build_flags.add_argument("--no-net", action="store_true") flake_build_flags.add_argument("--recreate-lock-file", action="store_true") flake_build_flags.add_argument("--no-update-lock-file", action="store_true") flake_build_flags.add_argument("--no-write-lock-file", action="store_true") flake_build_flags.add_argument("--no-registries", action="store_true") flake_build_flags.add_argument("--commit-lock-file", action="store_true") flake_build_flags.add_argument("--update-input") flake_build_flags.add_argument("--override-input", nargs=2) flake_common_flags = argparse.ArgumentParser(add_help=False) flake_common_flags.add_argument("--accept-flake-config", action="store_true") flake_common_flags.add_argument("--refresh", action="store_true") flake_common_flags.add_argument("--impure", action="store_true") flake_common_flags.add_argument("--offline", action="store_true") flake_common_flags.add_argument("--no-net", action="store_true") flake_common_flags.add_argument("--recreate-lock-file", action="store_true") flake_common_flags.add_argument("--no-update-lock-file", action="store_true") 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) classic_build_flags = argparse.ArgumentParser(add_help=False) classic_build_flags.add_argument("--no-build-output", "-Q", action="store_true") Loading @@ -74,7 +74,7 @@ def get_parser() -> tuple[argparse.ArgumentParser, dict[str, argparse.ArgumentPa sub_parsers = { "common_flags": common_flags, "common_build_flags": common_build_flags, "flake_build_flags": flake_build_flags, "flake_common_flags": flake_common_flags, "classic_build_flags": classic_build_flags, "copy_flags": copy_flags, } Loading Loading @@ -262,8 +262,8 @@ def parse_args( def reexec( argv: list[str], args: argparse.Namespace, build_flags: dict[str, Args], flake_build_flags: dict[str, Args], build_flags: Args, flake_build_flags: Args, ) -> None: drv = None attr = "config.system.build.nixos-rebuild" Loading @@ -271,10 +271,18 @@ def reexec( # Parsing the args here but ignore ask_sudo_password since it is not # needed and we would end up asking sudo password twice if flake := Flake.from_arg(args.flake, Remote.from_arg(args.target_host, None)): drv = nix.build_flake(attr, flake, **flake_build_flags, no_link=True) drv = nix.build_flake( attr, flake, flake_build_flags | {"no_link": True}, ) else: build_attr = BuildAttr.from_arg(args.attr, args.file) drv = nix.build(attr, build_attr, **build_flags, no_out_link=True) drv = nix.build( attr, build_attr, build_flags | {"no_out_link": True}, ) except CalledProcessError: logger.warning( "could not build a newer version of nixos-rebuild, " Loading Loading @@ -319,7 +327,8 @@ def execute(argv: list[str]) -> None: common_flags = vars(args_groups["common_flags"]) common_build_flags = common_flags | vars(args_groups["common_build_flags"]) build_flags = common_build_flags | vars(args_groups["classic_build_flags"]) flake_build_flags = common_build_flags | vars(args_groups["flake_build_flags"]) flake_common_flags = common_flags | vars(args_groups["flake_common_flags"]) flake_build_flags = common_build_flags | flake_common_flags copy_flags = common_flags | vars(args_groups["copy_flags"]) if args.upgrade or args.upgrade_all: Loading Loading @@ -350,7 +359,7 @@ def execute(argv: list[str]) -> None: flake = Flake.from_arg(args.flake, target_host) if can_run and not flake: nixpkgs_path = nix.find_file("nixpkgs", **build_flags) nixpkgs_path = nix.find_file("nixpkgs", build_flags) rev = nix.get_nixpkgs_rev(nixpkgs_path) if nixpkgs_path and rev: (nixpkgs_path / ".version-suffix").write_text(rev) Loading @@ -370,7 +379,10 @@ def execute(argv: list[str]) -> None: dry_run = action == Action.DRY_BUILD no_link = action in (Action.SWITCH, Action.BOOT) build_flags |= {"no_out_link": no_link, "dry_run": dry_run} flake_build_flags |= {"no_link": no_link, "dry_run": dry_run} rollback = bool(args.rollback) match action: case Action.BUILD_VM: attr = "config.system.build.vm" Loading @@ -395,24 +407,22 @@ def execute(argv: list[str]) -> None: case (_, True, _, _): raise NRError(f"--rollback is incompatible with '{action}'") case (_, False, Remote(_), Flake(_)): path_to_config = nix.remote_build_flake( path_to_config = nix.build_remote_flake( attr, flake, build_host, eval_flags=flake_common_flags, flake_build_flags=flake_build_flags, copy_flags=copy_flags, build_flags=build_flags, ) case (_, False, None, Flake(_)): path_to_config = nix.build_flake( attr, flake, no_link=no_link, dry_run=dry_run, **flake_build_flags, flake_build_flags=flake_build_flags, ) case (_, False, Remote(_), None): path_to_config = nix.remote_build( path_to_config = nix.build_remote( attr, build_attr, build_host, Loading @@ -424,9 +434,7 @@ def execute(argv: list[str]) -> None: path_to_config = nix.build( attr, build_attr, no_out_link=no_link, dry_run=dry_run, **build_flags, build_flags=build_flags, ) case never: # should never happen, but mypy is not smart enough to Loading @@ -442,7 +450,7 @@ def execute(argv: list[str]) -> None: path_to_config, to_host=target_host, from_host=build_host, **copy_flags, copy_flags=copy_flags, ) if action in (Action.SWITCH, Action.BOOT): nix.set_profile( Loading @@ -468,7 +476,7 @@ def execute(argv: list[str]) -> None: f"Done. The virtual machine can be started by running '{vm_path}'" ) case Action.EDIT: nix.edit(flake, **flake_build_flags) nix.edit(flake, flake_build_flags) case Action.DRY_RUN: assert False, "DRY_RUN should be a DRY_BUILD alias" case Action.LIST_GENERATIONS: Loading @@ -488,9 +496,9 @@ def execute(argv: list[str]) -> None: print(tabulate(generations, headers=headers)) case Action.REPL: if flake: nix.repl_flake("toplevel", flake, **flake_build_flags) nix.repl_flake("toplevel", flake, flake_build_flags) else: nix.repl("system", build_attr, **build_flags) nix.repl("system", build_attr, build_flags) case _: assert_never(action) Loading
pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/nix.py +22 −21 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ logger = logging.getLogger(__name__) def build( attr: str, build_attr: BuildAttr, **build_flags: Args, build_flags: Args | None = None, ) -> Path: """Build NixOS attribute using classic Nix. Loading @@ -52,7 +52,7 @@ def build( def build_flake( attr: str, flake: Flake, **flake_build_flags: Args, flake_build_flags: Args | None = None, ) -> Path: """Build NixOS attribute using Flakes. Loading @@ -70,13 +70,13 @@ def build_flake( return Path(r.stdout.strip()) def remote_build( def build_remote( attr: str, build_attr: BuildAttr, build_host: Remote | None, build_flags: dict[str, Args] | None = None, instantiate_flags: dict[str, Args] | None = None, copy_flags: dict[str, Args] | None = None, build_flags: Args | None = None, instantiate_flags: Args | None = None, copy_flags: Args | None = None, ) -> Path: # We need to use `--add-root` otherwise Nix will print this warning: # > warning: you did not specify '--add-root'; the result might be removed Loading @@ -89,12 +89,12 @@ def remote_build( build_attr.to_attr(attr), "--add-root", tmpdir.TMPDIR_PATH / uuid4().hex, *dict_to_flags(instantiate_flags or {}), *dict_to_flags(instantiate_flags), ], stdout=PIPE, ) drv = Path(r.stdout.strip()).resolve() copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {})) copy_closure(drv, to_host=build_host, from_host=None, copy_flags=copy_flags) # Need a temporary directory in remote to use in `nix-store --add-root` r = run_wrapper( Loading @@ -109,7 +109,7 @@ def remote_build( drv, "--add-root", remote_tmpdir / uuid4().hex, *dict_to_flags(build_flags or {}), *dict_to_flags(build_flags), ], remote=build_host, stdout=PIPE, Loading @@ -124,13 +124,13 @@ def remote_build( run_wrapper(["rm", "-rf", remote_tmpdir], remote=build_host, check=False) def remote_build_flake( def build_remote_flake( attr: str, flake: Flake, build_host: Remote, flake_build_flags: dict[str, Args] | None = None, copy_flags: dict[str, Args] | None = None, build_flags: dict[str, Args] | None = None, eval_flags: Args | None = None, copy_flags: Args | None = None, flake_build_flags: Args | None = None, ) -> Path: r = run_wrapper( [ Loading @@ -139,12 +139,12 @@ def remote_build_flake( "eval", "--raw", flake.to_attr(attr, "drvPath"), *dict_to_flags(flake_build_flags or {}), *dict_to_flags(eval_flags), ], stdout=PIPE, ) drv = Path(r.stdout.strip()) copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {})) copy_closure(drv, to_host=build_host, from_host=None, copy_flags=copy_flags) r = run_wrapper( [ "nix", Loading @@ -152,7 +152,7 @@ def remote_build_flake( "build", f"{drv}^*", "--print-out-paths", *dict_to_flags(build_flags or {}), *dict_to_flags(flake_build_flags), ], remote=build_host, stdout=PIPE, Loading @@ -164,7 +164,7 @@ def copy_closure( closure: Path, to_host: Remote | None, from_host: Remote | None = None, **copy_flags: Args, copy_flags: Args | None = None, ) -> None: """Copy a nix closure to or from host to localhost. Loading Loading @@ -192,6 +192,7 @@ def copy_closure( [ "nix", "copy", *dict_to_flags(copy_flags), "--from", f"ssh://{from_host.host}", "--to", Loading Loading @@ -221,7 +222,7 @@ def copy_closure( nix_copy_closure(to_host, to=True) def edit(flake: Flake | None, **flake_flags: Args) -> None: def edit(flake: Flake | None, flake_flags: Args | None = None) -> None: "Try to find and open NixOS configuration file in editor." if flake: run_wrapper( Loading Loading @@ -250,7 +251,7 @@ def edit(flake: Flake | None, **flake_flags: Args) -> None: raise NRError("cannot find NixOS config file") def find_file(file: str, **nix_flags: Args) -> Path | None: def find_file(file: str, nix_flags: Args | None = None) -> Path | None: "Find classic Nix file location." r = run_wrapper( ["nix-instantiate", "--find-file", file, *dict_to_flags(nix_flags)], Loading Loading @@ -420,14 +421,14 @@ def list_generations(profile: Profile) -> list[GenerationJson]: ) def repl(attr: str, build_attr: BuildAttr, **nix_flags: Args) -> None: def repl(attr: str, build_attr: BuildAttr, nix_flags: Args | None = None) -> None: run_args = ["nix", "repl", "--file", build_attr.path] if build_attr.attr: run_args.append(build_attr.attr) run_wrapper([*run_args, *dict_to_flags(nix_flags)]) def repl_flake(attr: str, flake: Flake, **flake_flags: Args) -> None: def repl_flake(attr: str, flake: Flake, flake_flags: Args | None = None) -> None: expr = Template( files(__package__).joinpath(FLAKE_REPL_TEMPLATE).read_text() ).substitute( Loading
pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/utils.py +7 −3 Original line number Diff line number Diff line import logging from collections.abc import Mapping, Sequence from typing import Any, TypeAlias, assert_never, override from typing import Any, assert_never, override Args: TypeAlias = bool | str | list[str] | int | None type Arg = bool | str | list[str] | int | None type Args = dict[str, Arg] class LogFormatter(logging.Formatter): Loading @@ -19,7 +20,10 @@ class LogFormatter(logging.Formatter): return formatter.format(record) def dict_to_flags(d: Mapping[str, Args]) -> list[str]: def dict_to_flags(d: Args | None) -> list[str]: if not d: return [] flags = [] for key, value in d.items(): flag = f"--{'-'.join(key.split('_'))}" Loading
pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py +3 −2 Original line number Diff line number Diff line Loading @@ -123,8 +123,8 @@ def test_execute_nix_boot(mock_run: Any, tmp_path: Path) -> None: "<nixpkgs/nixos>", "--attr", "config.system.build.toplevel", "--no-out-link", "-vvv", "--no-out-link", ], check=True, stdout=PIPE, Loading Loading @@ -188,8 +188,8 @@ def test_execute_nix_switch_flake(mock_run: Any, tmp_path: Path) -> None: "build", "--print-out-paths", "/path/to/config#nixosConfigurations.hostname.config.system.build.toplevel", "--no-link", "-v", "--no-link", ], check=True, stdout=PIPE, Loading Loading @@ -371,6 +371,7 @@ def test_execute_nix_switch_flake_build_host( "build", f"'{config_path}^*'", "--print-out-paths", "--no-link", ], check=True, stdout=PIPE, Loading
pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_nix.py +17 −15 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ from .helpers import get_qualified_name ) def test_build(mock_run: Any, monkeypatch: Any) -> None: assert n.build( "config.system.build.attr", m.BuildAttr("<nixpkgs/nixos>", None), nix_flag="foo" "config.system.build.attr", m.BuildAttr("<nixpkgs/nixos>", None), {"nix_flag": "foo"}, ) == Path("/path/to/file") mock_run.assert_called_with( [ Loading Loading @@ -55,8 +57,7 @@ def test_build_flake(mock_run: Any) -> None: assert n.build_flake( "config.system.build.toplevel", flake, no_link=True, nix_flag="foo", {"no_link": True, "nix_flag": "foo"}, ) == Path("/path/to/file") mock_run.assert_called_with( [ Loading @@ -76,7 +77,7 @@ def test_build_flake(mock_run: Any) -> None: @patch(get_qualified_name(n.run_wrapper, n), autospec=True) @patch(get_qualified_name(n.uuid4, n), autospec=True) def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: def test_build_remote(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: build_host = m.Remote("user@host", [], None) monkeypatch.setenv("NIX_SSHOPTS", "--ssh opts") Loading @@ -97,7 +98,7 @@ def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: mock_run.side_effect = run_wrapper_side_effect mock_uuid4.side_effect = [uuid.UUID(int=1), uuid.UUID(int=2)] assert n.remote_build( assert n.build_remote( "config.system.build.toplevel", m.BuildAttr("<nixpkgs/nixos>", "preAttr"), build_host, Loading Loading @@ -164,18 +165,18 @@ def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None: autospec=True, return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "), ) def test_remote_build_flake(mock_run: Any, monkeypatch: Any) -> None: def test_build_remote_flake(mock_run: Any, monkeypatch: Any) -> None: flake = m.Flake.parse(".#hostname") build_host = m.Remote("user@host", [], None) monkeypatch.setenv("NIX_SSHOPTS", "--ssh opts") assert n.remote_build_flake( assert n.build_remote_flake( "config.system.build.toplevel", flake, build_host, flake_build_flags={"flake": True}, eval_flags={"flake": True}, copy_flags={"copy": True}, build_flags={"build": True}, flake_build_flags={"build": True}, ) == Path("/path/to/file") mock_run.assert_has_calls( [ Loading Loading @@ -237,9 +238,9 @@ def test_copy_closure(monkeypatch: Any) -> None: monkeypatch.setenv("NIX_SSHOPTS", "--ssh build-opt") with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run: n.copy_closure(closure, None, build_host) n.copy_closure(closure, None, build_host, {"copy_flag": True}) mock_run.assert_called_with( ["nix-copy-closure", "--from", "user@build.host", closure], ["nix-copy-closure", "--copy-flag", "--from", "user@build.host", closure], extra_env={ "NIX_SSHOPTS": " ".join(p.SSH_DEFAULT_OPTS + ["--ssh build-opt"]) }, Loading @@ -251,11 +252,12 @@ def test_copy_closure(monkeypatch: Any) -> None: "NIX_SSHOPTS": " ".join(p.SSH_DEFAULT_OPTS + ["--ssh build-target-opt"]) } with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run: n.copy_closure(closure, target_host, build_host) n.copy_closure(closure, target_host, build_host, {"copy_flag": True}) mock_run.assert_called_with( [ "nix", "copy", "--copy-flag", "--from", "ssh://user@build.host", "--to", Loading Loading @@ -286,7 +288,7 @@ def test_copy_closure(monkeypatch: Any) -> None: def test_edit(mock_run: Any, monkeypatch: Any, tmpdir: Any) -> None: # Flake flake = m.Flake.parse(".#attr") n.edit(flake, commit_lock_file=True) n.edit(flake, {"commit_lock_file": True}) mock_run.assert_called_with( [ "nix", Loading Loading @@ -471,7 +473,7 @@ def test_list_generations(mock_get_generations: Any, tmp_path: Path) -> None: @patch(get_qualified_name(n.run_wrapper, n), autospec=True) def test_repl(mock_run: Any) -> None: n.repl("attr", m.BuildAttr("<nixpkgs/nixos>", None), nix_flag=True) n.repl("attr", m.BuildAttr("<nixpkgs/nixos>", None), {"nix_flag": True}) mock_run.assert_called_with( ["nix", "repl", "--file", "<nixpkgs/nixos>", "--nix-flag"] ) Loading @@ -482,7 +484,7 @@ def test_repl(mock_run: Any) -> None: @patch(get_qualified_name(n.run_wrapper, n), autospec=True) def test_repl_flake(mock_run: Any) -> None: n.repl_flake("attr", m.Flake(Path("flake.nix"), "myAttr"), nix_flag=True) n.repl_flake("attr", m.Flake(Path("flake.nix"), "myAttr"), {"nix_flag": True}) # See nixos-rebuild-ng.tests.repl for a better test, # this is mostly for sanity check assert mock_run.call_count == 1 Loading