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)
|