summaryrefslogtreecommitdiffstats
path: root/tests/testlib/__init__.py
blob: 3aa5dc16eb615536b43f497f8d830be6c0b4cd88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import dataclasses
import json
import os
import shutil
import subprocess
from pathlib import Path
from typing import Any

src = Path(__file__).parent.parent

flake_compat_arg = ("--arg", "flake-compat", str(src / "../default.nix"))


def copy_fixture(name: str, to: Path):
    print(f"copying {name} to {to}")
    shutil.copytree(src / name, to, dirs_exist_ok=True)


def format_nix_config(vals: dict[str, str]) -> str:
    return "\n".join(f"{name} = {value}" for (name, value) in vals.items())


@dataclasses.dataclass
class NixResult:
    proc: subprocess.CompletedProcess[bytes]

    def ok(self):
        self.proc.check_returncode()

    def json(self):
        return json.loads(self.proc.stdout)


def nix_eval_flake_compat(tmpdir: Path, attr: str, extra_args: list[str] = []) -> Any:
    return nix(
        "eval",
        "--show-trace",
        "--json",
        *flake_compat_arg,
        *extra_args,
        "-f",
        "default.nix",
        attr,
        work_dir=tmpdir,
    ).json()


def nix_eval_flake_attr(tmpdir: Path, attr: str, extra_args: list[str] = []) -> Any:
    return nix("eval", "--json", *extra_args, ".#" + attr, work_dir=tmpdir).json()


def nix(
    *args: str,
    work_dir: Path | None = None,
    command: str = "nix",
    experimental_features: set[str] = {"nix-command", "flakes"},
    capture_stderr: bool = False,
) -> NixResult:
    # FIXME(jade): maybe should copy or reference the lix functional2 test suite?
    config = {"experimental-features": " ".join(experimental_features)}
    new_env = os.environ.copy()
    new_env["NIX_CONFIG"] = (
        new_env.get("NIX_CONFIG", "") + "\n" + format_nix_config(config)
    )
    print(f"$ {command}", " ".join(args))

    stderr = subprocess.PIPE if capture_stderr else None
    res = NixResult(
        subprocess.run(
            [command] + list(args),
            env=new_env,
            cwd=work_dir,
            stdout=subprocess.PIPE,
            stderr=stderr,
        )
    )
    print(res.proc.stdout.decode())
    return res


def write_file(path: Path, content: str):
    with open(path, "w") as handle:
        handle.write(content)