Files
lix/tests/functional2/flakes/test_cli.py
T
eldritch horrors 4ef9fb3aee testing: migrate flakes/flakes.sh (part 4)
metadata query functionality

Change-Id: I8f3866316994426664468edfbe154505ed2428af
2026-02-25 12:47:08 +00:00

252 lines
8.7 KiB
Python

from pathlib import Path
import pytest
import re
from testlib.fixtures.nix import Nix
from testlib.fixtures.env import ManagedEnv
from testlib.fixtures.git import Git
from testlib.utils import get_global_asset_pack
from testlib.fixtures.file_helper import with_files, File, FileDeclaration, _init_files # noqa: PLC2701
from testlib.environ import environ
from .common import simple_flake
system = environ.get("system")
def dotgit_other_branch() -> FileDeclaration:
result = get_global_asset_pack(".git")
result[".git"]["HEAD"] = File("ref: refs/heads/other-branch")
return result
@pytest.fixture(autouse=True)
def setup_env(nix: Nix):
nix.settings.add_xp_feature("nix-command", "flakes")
flake1_files = {"flake1": get_global_asset_pack(".git") | simple_flake()}
flake2_files = {
"flake2": dotgit_other_branch()
| {
"flake.nix": File(f"""{{
description = "Fnord";
outputs = {{ self, flake1 }}: rec {{
packages.{system}.bar = flake1.packages.{system}.foo;
}};
}}""")
}
}
flake3_files = {
"flake3": get_global_asset_pack(".git")
| {
"flake.nix": File(f"""{{
description = "Fnord";
outputs = {{ self, flake2 }}: rec {{
packages.{system}.xyzzy = flake2.packages.{system}.bar;
checks.xyzzy = packages.{system}.xyzzy;
}};
}}"""),
"default.nix": File("{ x = 123; }"),
}
}
def _make_flake_repo(
name: str, files: FileDeclaration, git: Git, env: ManagedEnv, request: pytest.FixtureRequest
) -> Path:
_init_files(files, env.dirs.test_root, request.path.parent, env)
repo = env.dirs.test_root / name
git(repo, "add", ".")
git(repo, "commit", "-m", "Initial")
return repo
@pytest.fixture
def flake1(git: Git, env: ManagedEnv, request: pytest.FixtureRequest) -> Path:
return _make_flake_repo("flake1", flake1_files, git, env, request)
def _modify_flake1(flake1: Path, git: Git | None):
(flake1 / "foo").write_text("foo")
(flake1 / "flake.nix").write_text((flake1 / "flake.nix").read_text() + "# foo")
if git is not None:
git(flake1, "add", "foo")
git(flake1, "commit", "-a", "-m", "Foo")
@pytest.fixture
def flake2(git: Git, env: ManagedEnv, request: pytest.FixtureRequest) -> Path:
return _make_flake_repo("flake2", flake2_files, git, env, request)
@pytest.fixture
def flake3(git: Git, env: ManagedEnv, request: pytest.FixtureRequest) -> Path:
return _make_flake_repo("flake3", flake3_files, git, env, request)
@pytest.fixture
def registry(nix: Nix, flake1: Path, flake2: Path, flake3: Path) -> Path:
registry = nix.env.dirs.test_root / "registry.json"
nix.settings.flake_registry = str(registry)
# Construct a custom registry, additionally test the --registry flag
nix.nix(
["registry", "add", "--registry", registry, "flake1", f"git+file://{flake1}"]
).run().ok()
nix.nix(
["registry", "add", "--registry", registry, "flake2", f"git+file://{flake2}"]
).run().ok()
nix.nix(
["registry", "add", "--registry", registry, "flake3", f"git+file://{flake3}"]
).run().ok()
nix.nix(["registry", "add", "--registry", registry, "flake4", "flake3"]).run().ok()
nix.nix(["registry", "add", "--registry", registry, "nixpkgs", "flake1"]).run().ok()
return registry
@pytest.mark.usefixtures("registry")
class TestMetadata:
def test_registry(self, nix: Nix):
metadata = nix.nix(["flake", "metadata", "flake1"]).run().ok().stdout_s
assert re.search(r"Locked URL:.*flake1.*", metadata)
@pytest.mark.parametrize("source", [[], ["."]])
def test_cwd(self, nix: Nix, flake1: Path, source: list[str]):
metadata = nix.nix(["flake", "metadata", *source], cwd=flake1).run().ok().stdout_s
assert re.search(r"Locked URL:.*flake1.*", metadata)
def test_absolute(self, nix: Nix, flake1: Path):
metadata = nix.nix(["flake", "metadata", flake1]).run().ok().stdout_s
assert re.search(r"Locked URL:.*flake1.*", metadata)
@pytest.mark.parametrize("source", ["flake1", None])
def test_json(self, nix: Nix, flake1: Path, source: str | None, git: Git):
flake1_original_commit = git(flake1, "rev-parse", "HEAD").stdout_s.strip()
metadata = nix.nix(["flake", "metadata", source or flake1, "--json"]).run().json()
assert metadata["description"] == "Bla bla"
assert Path(metadata["path"]).is_dir()
assert metadata["lastModified"] == 23
assert metadata["revision"] == flake1_original_commit
def test_json_registry_dirty(self, nix: Nix, flake1: Path, git: Git):
flake1_original_commit = git(flake1, "rev-parse", "HEAD").stdout_s.strip()
(flake1 / "foo").write_text("foo")
git(flake1, "add", "foo")
metadata = nix.nix(["flake", "metadata", "flake1", "--json"]).run().json()
assert metadata["dirtyRevision"] == f"{flake1_original_commit}-dirty"
_modify_flake1(flake1, git)
flake1_modified_commit = git(flake1, "rev-parse", "HEAD").stdout_s.strip()
metadata = nix.nix(["flake", "metadata", "flake1", "--json", "--refresh"]).run().json()
assert metadata["revision"] == flake1_modified_commit
assert "dirtyRevision" not in metadata
class TestAddPath:
@with_files({"badFlake": {"flake.nix": File("INVALID")}})
def test_does_not_eval(self, nix: Nix, files: Path):
nix.nix(["store", "add-path", str(files / "badFlake")]).run().ok()
def test_add_flake(self, nix: Nix, flake1: Path):
path = nix.nix(["store", "add-path", flake1]).run().ok().stdout_s.strip()
info = nix.nix(["path-info", path]).run().ok().stdout_s
assert "flake1" in info
# required to the path: test, otherwise outputs are not valid
nix.nix(["build", flake1]).run().ok()
info = nix.nix(["path-info", f"path:{path}"]).run().ok().stdout_s
assert "simple" in info
@pytest.mark.usefixtures("registry")
class TestLegacyCLI:
def test_instantiate_indirect(self, nix: Nix):
assert (
nix.nix_instantiate(["--eval", "flake:flake3", "-A", "x"]).run().ok().stdout_s
== "123\n"
)
def test_instantiate_url(self, nix: Nix, flake3: Path):
assert (
nix.nix_instantiate(["--eval", f"flake:git+file://{flake3}", "-A", "x"])
.run()
.ok()
.stdout_s
== "123\n"
)
def test_instantiate_nix_path_option(self, nix: Nix):
assert (
nix.nix_instantiate(["-I", "flake3=flake:flake3", "--eval", "<flake3>", "-A", "x"])
.run()
.ok()
.stdout_s
== "123\n"
)
def test_instantiate_nix_path_env(self, nix: Nix):
nix.env["NIX_PATH"] = "flake3=flake:flake3"
assert nix.nix_instantiate(["--eval", "<flake3>", "-A", "x"]).run().ok().stdout_s == "123\n"
class TestAlternateLockFiles:
@pytest.fixture(autouse=True)
def init(self, nix: Nix, flake1: Path, flake2: Path, registry: Path, git: Git): # noqa: ARG002
git(flake1, "commit", "--allow-empty", "-m", "to change branch head")
nix.nix(["flake", "lock", flake2]).run().ok()
def test_other_lockfile_is_identical(self, nix: Nix, flake2: Path):
nix.nix(["flake", "lock", flake2, "--output-lock-file", "flake2.lock"]).run().ok()
assert (nix.env.dirs.home / "flake2.lock").read_text() == (
flake2 / "flake.lock"
).read_text()
def test_input_overrides_change_lockfiles(self, nix: Nix, flake1: Path, flake2: Path, git: Git):
flake1_original_commit = git(flake1, "rev-parse", "HEAD").stdout_s.strip()
nix.nix(
[
"flake",
"lock",
flake2,
"--output-lock-file",
"flake2.lock",
"--override-input",
"flake1",
f"git+file://{flake1}?rev={flake1_original_commit}",
]
).run().ok()
assert (nix.env.dirs.home / "flake2.lock").read_text() != (
flake2 / "flake.lock"
).read_text()
assert (
flake1_original_commit
in nix.nix(["flake", "metadata", flake2, "--reference-lock-file", "flake2.lock"])
.run()
.ok()
.stdout_s
)
def test_reference_lock_file_requires_allow_dirty(nix: Nix, flake2: Path):
assert (
"error: reference lock file was provided, but the `allow-dirty` setting is set to false"
in nix.nix(
[
"flake",
"metadata",
flake2,
"--no-allow-dirty",
"--reference-lock-file",
f"{nix.env.dirs.home}/flake2-overridden.lock",
]
)
.run()
.expect(1)
.stderr_s
)