nixos-rebuild-ng: make build functions more generic
This commit is contained in:
@@ -194,13 +194,14 @@ def execute(argv: list[str]) -> None:
|
||||
match action:
|
||||
case Action.SWITCH | Action.BOOT:
|
||||
logger.info("building the system configuration...")
|
||||
attr = "config.system.build.toplevel"
|
||||
if args.rollback:
|
||||
path_to_config = nix.rollback(profile, target_host, sudo=args.sudo)
|
||||
else:
|
||||
if flake:
|
||||
if build_host:
|
||||
path_to_config = nix.nixos_remote_build_flake(
|
||||
"toplevel",
|
||||
path_to_config = nix.remote_build_flake(
|
||||
attr,
|
||||
flake,
|
||||
build_host,
|
||||
flake_build_flags=flake_build_flags,
|
||||
@@ -208,16 +209,16 @@ def execute(argv: list[str]) -> None:
|
||||
build_flags=build_flags,
|
||||
)
|
||||
else:
|
||||
path_to_config = nix.nixos_build_flake(
|
||||
"toplevel",
|
||||
path_to_config = nix.build_flake(
|
||||
attr,
|
||||
flake,
|
||||
no_link=True,
|
||||
**flake_build_flags,
|
||||
)
|
||||
else:
|
||||
if build_host:
|
||||
path_to_config = nix.nixos_remote_build(
|
||||
"toplevel",
|
||||
path_to_config = nix.remote_build(
|
||||
attr,
|
||||
build_attr,
|
||||
build_host,
|
||||
instantiate_flags=common_flags,
|
||||
@@ -225,8 +226,8 @@ def execute(argv: list[str]) -> None:
|
||||
build_flags=build_flags,
|
||||
)
|
||||
else:
|
||||
path_to_config = nix.nixos_build(
|
||||
"toplevel",
|
||||
path_to_config = nix.build(
|
||||
attr,
|
||||
build_attr,
|
||||
no_out_link=True,
|
||||
**build_flags,
|
||||
@@ -253,6 +254,7 @@ def execute(argv: list[str]) -> None:
|
||||
)
|
||||
case Action.TEST | Action.BUILD | Action.DRY_BUILD | Action.DRY_ACTIVATE:
|
||||
logger.info("building the system configuration...")
|
||||
attr = "config.system.build.toplevel"
|
||||
dry_run = action == Action.DRY_BUILD
|
||||
if args.rollback:
|
||||
if action not in (Action.TEST, Action.BUILD):
|
||||
@@ -267,15 +269,15 @@ def execute(argv: list[str]) -> None:
|
||||
else:
|
||||
raise NRError("could not find previous generation")
|
||||
elif flake:
|
||||
path_to_config = nix.nixos_build_flake(
|
||||
"toplevel",
|
||||
path_to_config = nix.build_flake(
|
||||
attr,
|
||||
flake,
|
||||
dry_run=dry_run,
|
||||
**flake_build_flags,
|
||||
)
|
||||
else:
|
||||
path_to_config = nix.nixos_build(
|
||||
"toplevel",
|
||||
path_to_config = nix.build(
|
||||
attr,
|
||||
build_attr,
|
||||
dry_run=dry_run,
|
||||
**build_flags,
|
||||
@@ -292,14 +294,14 @@ def execute(argv: list[str]) -> None:
|
||||
logger.info("building the system configuration...")
|
||||
attr = "vm" if action == Action.BUILD_VM else "vmWithBootLoader"
|
||||
if flake:
|
||||
path_to_config = nix.nixos_build_flake(
|
||||
attr,
|
||||
path_to_config = nix.build_flake(
|
||||
f"config.system.build.{attr}",
|
||||
flake,
|
||||
**flake_build_flags,
|
||||
)
|
||||
else:
|
||||
path_to_config = nix.nixos_build(
|
||||
attr,
|
||||
path_to_config = nix.build(
|
||||
f"config.system.build.{attr}",
|
||||
build_attr,
|
||||
**build_flags,
|
||||
)
|
||||
|
||||
@@ -25,6 +25,112 @@ FLAKE_REPL_TEMPLATE: Final = "repl.template.nix"
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def build(
|
||||
attr: str,
|
||||
build_attr: BuildAttr,
|
||||
**build_flags: Args,
|
||||
) -> Path:
|
||||
"""Build NixOS attribute using classic Nix.
|
||||
|
||||
Returns the built attribute as path.
|
||||
"""
|
||||
run_args = [
|
||||
"nix-build",
|
||||
build_attr.path,
|
||||
"--attr",
|
||||
build_attr.to_attr(attr),
|
||||
*dict_to_flags(build_flags),
|
||||
]
|
||||
r = run_wrapper(run_args, stdout=PIPE)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def build_flake(
|
||||
attr: str,
|
||||
flake: Flake,
|
||||
**flake_build_flags: Args,
|
||||
) -> Path:
|
||||
"""Build NixOS attribute using Flakes.
|
||||
|
||||
Returns the built attribute as path.
|
||||
"""
|
||||
run_args = [
|
||||
"nix",
|
||||
*FLAKE_FLAGS,
|
||||
"build",
|
||||
"--print-out-paths",
|
||||
flake.to_attr(attr),
|
||||
*dict_to_flags(flake_build_flags),
|
||||
]
|
||||
r = run_wrapper(run_args, stdout=PIPE)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def remote_build(
|
||||
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,
|
||||
) -> Path:
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix-instantiate",
|
||||
"--raw",
|
||||
build_attr.path,
|
||||
"--attr",
|
||||
build_attr.to_attr(attr),
|
||||
*dict_to_flags(instantiate_flags or {}),
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
drv = Path(r.stdout.strip())
|
||||
copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {}))
|
||||
r = run_wrapper(
|
||||
["nix-store", "--realise", drv, *dict_to_flags(build_flags or {})],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def remote_build_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,
|
||||
) -> Path:
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix",
|
||||
*FLAKE_FLAGS,
|
||||
"eval",
|
||||
"--raw",
|
||||
flake.to_attr(attr, "drvPath"),
|
||||
*dict_to_flags(flake_build_flags or {}),
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
drv = Path(r.stdout.strip())
|
||||
copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {}))
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix",
|
||||
*FLAKE_FLAGS,
|
||||
"build",
|
||||
f"{drv}^*",
|
||||
"--print-out-paths",
|
||||
*dict_to_flags(build_flags or {}),
|
||||
],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def copy_closure(
|
||||
closure: Path,
|
||||
to_host: Remote | None,
|
||||
@@ -248,112 +354,6 @@ def list_generations(profile: Profile) -> list[GenerationJson]:
|
||||
return result
|
||||
|
||||
|
||||
def nixos_build(
|
||||
attr: str,
|
||||
build_attr: BuildAttr,
|
||||
**build_flags: Args,
|
||||
) -> Path:
|
||||
"""Build NixOS attribute using classic Nix.
|
||||
|
||||
Returns the built attribute as path.
|
||||
"""
|
||||
run_args = [
|
||||
"nix-build",
|
||||
build_attr.path,
|
||||
"--attr",
|
||||
build_attr.to_attr("config", "system", "build", attr),
|
||||
*dict_to_flags(build_flags),
|
||||
]
|
||||
r = run_wrapper(run_args, stdout=PIPE)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def nixos_build_flake(
|
||||
attr: str,
|
||||
flake: Flake,
|
||||
**flake_build_flags: Args,
|
||||
) -> Path:
|
||||
"""Build NixOS attribute using Flakes.
|
||||
|
||||
Returns the built attribute as path.
|
||||
"""
|
||||
run_args = [
|
||||
"nix",
|
||||
*FLAKE_FLAGS,
|
||||
"build",
|
||||
"--print-out-paths",
|
||||
flake.to_attr("config", "system", "build", attr),
|
||||
*dict_to_flags(flake_build_flags),
|
||||
]
|
||||
r = run_wrapper(run_args, stdout=PIPE)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def nixos_remote_build(
|
||||
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,
|
||||
) -> Path:
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix-instantiate",
|
||||
"--raw",
|
||||
build_attr.path,
|
||||
"--attr",
|
||||
build_attr.to_attr("config", "system", "build", attr),
|
||||
*dict_to_flags(instantiate_flags or {}),
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
drv = Path(r.stdout.strip())
|
||||
copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {}))
|
||||
r = run_wrapper(
|
||||
["nix-store", "--realise", drv, *dict_to_flags(build_flags or {})],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def nixos_remote_build_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,
|
||||
) -> Path:
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix",
|
||||
*FLAKE_FLAGS,
|
||||
"eval",
|
||||
"--raw",
|
||||
flake.to_attr("config", "system", "build", attr, "drvPath"),
|
||||
*dict_to_flags(flake_build_flags or {}),
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
drv = Path(r.stdout.strip())
|
||||
copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {}))
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix",
|
||||
*FLAKE_FLAGS,
|
||||
"build",
|
||||
f"{drv}^*",
|
||||
"--print-out-paths",
|
||||
*dict_to_flags(build_flags or {}),
|
||||
],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
)
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def repl(attr: str, build_attr: BuildAttr, **nix_flags: Args) -> None:
|
||||
run_args = ["nix", "repl", "--file", build_attr.path]
|
||||
if build_attr.attr:
|
||||
|
||||
@@ -12,6 +12,173 @@ import nixos_rebuild.nix as n
|
||||
from .helpers import get_qualified_name
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_build(mock_run: Any, monkeypatch: Any) -> None:
|
||||
assert n.build(
|
||||
"config.system.build.attr", m.BuildAttr("<nixpkgs/nixos>", None), nix_flag="foo"
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_called_with(
|
||||
[
|
||||
"nix-build",
|
||||
"<nixpkgs/nixos>",
|
||||
"--attr",
|
||||
"config.system.build.attr",
|
||||
"--nix-flag",
|
||||
"foo",
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
|
||||
assert n.build(
|
||||
"config.system.build.attr", m.BuildAttr(Path("file"), "preAttr")
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_called_with(
|
||||
["nix-build", Path("file"), "--attr", "preAttr.config.system.build.attr"],
|
||||
stdout=PIPE,
|
||||
)
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_build_flake(mock_run: Any) -> None:
|
||||
flake = m.Flake.parse(".#hostname")
|
||||
|
||||
assert n.build_flake(
|
||||
"config.system.build.toplevel",
|
||||
flake,
|
||||
no_link=True,
|
||||
nix_flag="foo",
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_called_with(
|
||||
[
|
||||
"nix",
|
||||
"--extra-experimental-features",
|
||||
"nix-command flakes",
|
||||
"build",
|
||||
"--print-out-paths",
|
||||
".#nixosConfigurations.hostname.config.system.build.toplevel",
|
||||
"--no-link",
|
||||
"--nix-flag",
|
||||
"foo",
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_remote_build(mock_run: Any, monkeypatch: Any) -> None:
|
||||
build_host = m.Remote("user@host", ["--ssh", "opts"], None)
|
||||
assert n.remote_build(
|
||||
"config.system.build.toplevel",
|
||||
m.BuildAttr("<nixpkgs/nixos>", "preAttr"),
|
||||
build_host,
|
||||
build_flags={"build": True},
|
||||
instantiate_flags={"inst": True},
|
||||
copy_flags={"copy": True},
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
[
|
||||
"nix-instantiate",
|
||||
"--raw",
|
||||
"<nixpkgs/nixos>",
|
||||
"--attr",
|
||||
"preAttr.config.system.build.toplevel",
|
||||
"--inst",
|
||||
],
|
||||
stdout=PIPE,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix-copy-closure",
|
||||
"--copy",
|
||||
"--to",
|
||||
"user@host",
|
||||
Path("/path/to/file"),
|
||||
],
|
||||
extra_env={"NIX_SSHOPTS": "--ssh opts"},
|
||||
remote=None,
|
||||
),
|
||||
call(
|
||||
["nix-store", "--realise", Path("/path/to/file"), "--build"],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_remote_build_flake(mock_run: Any) -> None:
|
||||
flake = m.Flake.parse(".#hostname")
|
||||
build_host = m.Remote("user@host", ["--ssh", "opts"], None)
|
||||
|
||||
assert n.remote_build_flake(
|
||||
"config.system.build.toplevel",
|
||||
flake,
|
||||
build_host,
|
||||
flake_build_flags={"flake": True},
|
||||
copy_flags={"copy": True},
|
||||
build_flags={"build": True},
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
[
|
||||
"nix",
|
||||
"--extra-experimental-features",
|
||||
"nix-command flakes",
|
||||
"eval",
|
||||
"--raw",
|
||||
".#nixosConfigurations.hostname.config.system.build.toplevel.drvPath",
|
||||
"--flake",
|
||||
],
|
||||
stdout=PIPE,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix-copy-closure",
|
||||
"--copy",
|
||||
"--to",
|
||||
"user@host",
|
||||
Path("/path/to/file"),
|
||||
],
|
||||
extra_env={"NIX_SSHOPTS": "--ssh opts"},
|
||||
remote=None,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix",
|
||||
"--extra-experimental-features",
|
||||
"nix-command flakes",
|
||||
"build",
|
||||
"/path/to/file^*",
|
||||
"--print-out-paths",
|
||||
"--build",
|
||||
],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
|
||||
def test_copy_closure(mock_run: Any, monkeypatch: Any) -> None:
|
||||
closure = Path("/path/to/closure")
|
||||
@@ -211,173 +378,6 @@ def test_list_generations(mock_get_generations: Any, tmp_path: Path) -> None:
|
||||
]
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_nixos_build_flake(mock_run: Any) -> None:
|
||||
flake = m.Flake.parse(".#hostname")
|
||||
|
||||
assert n.nixos_build_flake(
|
||||
"toplevel",
|
||||
flake,
|
||||
no_link=True,
|
||||
nix_flag="foo",
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_called_with(
|
||||
[
|
||||
"nix",
|
||||
"--extra-experimental-features",
|
||||
"nix-command flakes",
|
||||
"build",
|
||||
"--print-out-paths",
|
||||
".#nixosConfigurations.hostname.config.system.build.toplevel",
|
||||
"--no-link",
|
||||
"--nix-flag",
|
||||
"foo",
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
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", m.BuildAttr("<nixpkgs/nixos>", None), nix_flag="foo"
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_called_with(
|
||||
[
|
||||
"nix-build",
|
||||
"<nixpkgs/nixos>",
|
||||
"--attr",
|
||||
"config.system.build.attr",
|
||||
"--nix-flag",
|
||||
"foo",
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
|
||||
assert n.nixos_build("attr", m.BuildAttr(Path("file"), "preAttr")) == Path(
|
||||
"/path/to/file"
|
||||
)
|
||||
mock_run.assert_called_with(
|
||||
["nix-build", Path("file"), "--attr", "preAttr.config.system.build.attr"],
|
||||
stdout=PIPE,
|
||||
)
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_nixos_remote_build_flake(mock_run: Any) -> None:
|
||||
flake = m.Flake.parse(".#hostname")
|
||||
build_host = m.Remote("user@host", ["--ssh", "opts"], None)
|
||||
|
||||
assert n.nixos_remote_build_flake(
|
||||
"toplevel",
|
||||
flake,
|
||||
build_host,
|
||||
flake_build_flags={"flake": True},
|
||||
copy_flags={"copy": True},
|
||||
build_flags={"build": True},
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
[
|
||||
"nix",
|
||||
"--extra-experimental-features",
|
||||
"nix-command flakes",
|
||||
"eval",
|
||||
"--raw",
|
||||
".#nixosConfigurations.hostname.config.system.build.toplevel.drvPath",
|
||||
"--flake",
|
||||
],
|
||||
stdout=PIPE,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix-copy-closure",
|
||||
"--copy",
|
||||
"--to",
|
||||
"user@host",
|
||||
Path("/path/to/file"),
|
||||
],
|
||||
extra_env={"NIX_SSHOPTS": "--ssh opts"},
|
||||
remote=None,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix",
|
||||
"--extra-experimental-features",
|
||||
"nix-command flakes",
|
||||
"build",
|
||||
"/path/to/file^*",
|
||||
"--print-out-paths",
|
||||
"--build",
|
||||
],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@patch(
|
||||
get_qualified_name(n.run_wrapper, n),
|
||||
autospec=True,
|
||||
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
|
||||
)
|
||||
def test_nixos_remote_build(mock_run: Any, monkeypatch: Any) -> None:
|
||||
build_host = m.Remote("user@host", ["--ssh", "opts"], None)
|
||||
assert n.nixos_remote_build(
|
||||
"attr",
|
||||
m.BuildAttr("<nixpkgs/nixos>", "preAttr"),
|
||||
build_host,
|
||||
build_flags={"build": True},
|
||||
instantiate_flags={"inst": True},
|
||||
copy_flags={"copy": True},
|
||||
) == Path("/path/to/file")
|
||||
mock_run.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
[
|
||||
"nix-instantiate",
|
||||
"--raw",
|
||||
"<nixpkgs/nixos>",
|
||||
"--attr",
|
||||
"preAttr.config.system.build.attr",
|
||||
"--inst",
|
||||
],
|
||||
stdout=PIPE,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix-copy-closure",
|
||||
"--copy",
|
||||
"--to",
|
||||
"user@host",
|
||||
Path("/path/to/file"),
|
||||
],
|
||||
extra_env={"NIX_SSHOPTS": "--ssh opts"},
|
||||
remote=None,
|
||||
),
|
||||
call(
|
||||
["nix-store", "--realise", Path("/path/to/file"), "--build"],
|
||||
remote=build_host,
|
||||
stdout=PIPE,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@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)
|
||||
|
||||
Reference in New Issue
Block a user