nixos-rebuild-ng: replace usage of kwargs

This commit is contained in:
Thiago Kenji Okada
2024-12-27 19:20:19 +00:00
parent 58e948dccc
commit a376797b7b
6 changed files with 61 additions and 46 deletions
@@ -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"
@@ -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, "
@@ -350,7 +358,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)
@@ -370,7 +378,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"
@@ -407,9 +418,7 @@ def execute(argv: list[str]) -> None:
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.build_remote(
@@ -424,9 +433,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
@@ -442,7 +449,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(
@@ -468,7 +475,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:
@@ -488,9 +495,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)
@@ -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.
@@ -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.
@@ -74,9 +74,9 @@ 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
@@ -89,12 +89,12 @@ def build_remote(
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(
@@ -109,7 +109,7 @@ def build_remote(
drv,
"--add-root",
remote_tmpdir / uuid4().hex,
*dict_to_flags(build_flags or {}),
*dict_to_flags(build_flags),
],
remote=build_host,
stdout=PIPE,
@@ -128,9 +128,9 @@ 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,
flake_build_flags: Args | None = None,
copy_flags: Args | None = None,
build_flags: Args | None = None,
) -> Path:
r = run_wrapper(
[
@@ -139,12 +139,12 @@ def build_remote_flake(
"eval",
"--raw",
flake.to_attr(attr, "drvPath"),
*dict_to_flags(flake_build_flags or {}),
*dict_to_flags(flake_build_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",
@@ -152,7 +152,7 @@ def build_remote_flake(
"build",
f"{drv}^*",
"--print-out-paths",
*dict_to_flags(build_flags or {}),
*dict_to_flags(build_flags),
],
remote=build_host,
stdout=PIPE,
@@ -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.
@@ -222,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(
@@ -251,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)],
@@ -421,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(
@@ -2,7 +2,8 @@ import logging
from collections.abc import Mapping, Sequence
from typing import Any, assert_never, override
type Args = bool | str | list[str] | int | None
type Arg = bool | str | list[str] | int | None
type Args = dict[str, Arg]
class LogFormatter(logging.Formatter):
@@ -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('_'))}"
@@ -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,
@@ -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,
@@ -349,6 +349,7 @@ def test_execute_nix_switch_flake_build_host(
"eval",
"--raw",
"/path/to/config#nixosConfigurations.hostname.config.system.build.toplevel.drvPath",
"--no-link",
],
check=True,
stdout=PIPE,
@@ -371,6 +372,7 @@ def test_execute_nix_switch_flake_build_host(
"build",
f"'{config_path}^*'",
"--print-out-paths",
"--no-out-link",
],
check=True,
stdout=PIPE,
@@ -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(
[
@@ -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(
[
@@ -237,7 +238,7 @@ 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, copy_flag=True)
n.copy_closure(closure, None, build_host, {"copy_flag": True})
mock_run.assert_called_with(
["nix-copy-closure", "--copy-flag", "--from", "user@build.host", closure],
extra_env={
@@ -251,7 +252,7 @@ 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, copy_flag=True)
n.copy_closure(closure, target_host, build_host, {"copy_flag": True})
mock_run.assert_called_with(
[
"nix",
@@ -287,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",
@@ -472,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"]
)
@@ -483,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
@@ -4,6 +4,7 @@ import nixos_rebuild.utils as u
def test_dict_to_flags() -> None:
assert u.dict_to_flags(None) == []
r1 = u.dict_to_flags(
{
"test_flag_1": True,