nixos-rebuild-ng: introduce models.BuildingAttr

This commit is contained in:
Thiago Kenji Okada
2024-11-30 17:54:27 +00:00
parent a3a9591051
commit d325edd627
5 changed files with 45 additions and 33 deletions
@@ -9,7 +9,7 @@ from tempfile import TemporaryDirectory
from typing import assert_never
from . import nix
from .models import Action, Flake, NRError, Profile
from .models import Action, BuildAttr, Flake, NRError, Profile
from .process import Remote, cleanup_ssh
from .utils import info
@@ -170,6 +170,7 @@ def execute(argv: list[str]) -> None:
profile = Profile.from_name(args.profile_name)
target_host = Remote.from_arg(args.target_host, args.ask_sudo_password, tmpdir_path)
build_attr = BuildAttr.from_arg(args.attr, args.file)
flake = Flake.from_arg(args.flake, target_host)
if args.upgrade or args.upgrade_all:
@@ -204,8 +205,7 @@ def execute(argv: list[str]) -> None:
else:
path_to_config = nix.nixos_build(
"system",
args.attr,
args.file,
build_attr,
no_out_link=True,
**build_flags,
)
@@ -244,8 +244,7 @@ def execute(argv: list[str]) -> None:
else:
path_to_config = nix.nixos_build(
"system",
args.attr,
args.file,
build_attr,
dry_run=dry_run,
**build_flags,
)
@@ -269,8 +268,7 @@ def execute(argv: list[str]) -> None:
else:
path_to_config = nix.nixos_build(
attr,
args.attr,
args.file,
build_attr,
**build_flags,
)
vm_path = next(path_to_config.glob("bin/run-*-vm"), "./result/bin/run-*-vm")
@@ -307,12 +305,10 @@ def execute(argv: list[str]) -> None:
)
print(table)
case Action.REPL:
# For now just redirect it to `nixos-rebuild` instead of
# duplicating the code
os.execv(
"@nixos_rebuild@",
argv,
)
if flake:
nix.repl_flake("toplevel", flake, **flake_build_flags)
else:
nix.repl("system", build_attr, **build_flags)
case _:
assert_never(action)
@@ -45,6 +45,18 @@ class Action(Enum):
return [a.value for a in Action]
@dataclass(frozen=True)
class BuildAttr:
path: Path
attr: str | None
@classmethod
def from_arg(cls, attr: str | None, file: str | None) -> Self | None:
if not (attr or file):
return None
return cls(Path(file or "default.nix"), attr)
@dataclass(frozen=True)
class Flake:
path: Path
@@ -6,6 +6,7 @@ from typing import Final
from .models import (
Action,
BuildAttr,
Flake,
Generation,
GenerationJson,
@@ -235,24 +236,20 @@ def list_generations(profile: Profile) -> list[GenerationJson]:
def nixos_build(
attr: str,
pre_attr: str | None,
file: str | None,
build_attr: BuildAttr | None,
**nix_flags: Args,
) -> Path:
"""Build NixOS attribute using classic Nix.
It will by default build `<nixpkgs/nixos>` with `attr`, however it
optionally supports building from an external file and custom attributes
paths.
Returns the built attribute as path.
"""
if pre_attr or file:
run_args: list[str | Path]
if build_attr:
run_args = [
"nix-build",
file or "default.nix",
build_attr.path,
"--attr",
f"{'.'.join(x for x in [pre_attr, attr] if x)}",
f"{'.'.join(x for x in [build_attr.attr, attr] if x)}",
]
else:
run_args = ["nix-build", "<nixpkgs/nixos>", "--attr", attr]
@@ -9,6 +9,19 @@ import nixos_rebuild.models as m
from .helpers import get_qualified_name
def test_building_attr_from_arg() -> None:
assert m.BuildAttr.from_arg(None, None) is None
assert m.BuildAttr.from_arg("attr", None) == m.BuildAttr(
Path("default.nix"), "attr"
)
assert m.BuildAttr.from_arg("attr", "file.nix") == m.BuildAttr(
Path("file.nix"), "attr"
)
assert m.BuildAttr.from_arg(None, "file.nix") == m.BuildAttr(
Path("file.nix"), None
)
def test_flake_parse() -> None:
assert m.Flake.parse("/path/to/flake#attr") == m.Flake(
Path("/path/to/flake"), "nixosConfigurations.attr"
@@ -229,27 +229,21 @@ def test_nixos_build_flake(mock_run: Any) -> None:
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
)
def test_nixos_build(mock_run: Any, monkeypatch: Any) -> None:
assert n.nixos_build("attr", None, None, nix_flag="foo") == Path("/path/to/file")
assert n.nixos_build("attr", None, nix_flag="foo") == Path("/path/to/file")
mock_run.assert_called_with(
["nix-build", "<nixpkgs/nixos>", "--attr", "attr", "--nix-flag", "foo"],
stdout=PIPE,
)
n.nixos_build("attr", "preAttr", "file")
n.nixos_build("attr", m.BuildAttr(Path("file"), "preAttr"))
mock_run.assert_called_with(
["nix-build", "file", "--attr", "preAttr.attr"],
["nix-build", Path("file"), "--attr", "preAttr.attr"],
stdout=PIPE,
)
n.nixos_build("attr", None, "file", no_out_link=True)
n.nixos_build("attr", m.BuildAttr(Path("file"), None))
mock_run.assert_called_with(
["nix-build", "file", "--attr", "attr", "--no-out-link"],
stdout=PIPE,
)
n.nixos_build("attr", "preAttr", None, no_out_link=False, keep_going=True)
mock_run.assert_called_with(
["nix-build", "default.nix", "--attr", "preAttr.attr", "--keep-going"],
["nix-build", Path("file"), "--attr", "attr"],
stdout=PIPE,
)