mirror of
https://github.com/nix-community/nix-direnv.git
synced 2025-11-09 12:06:10 +01:00
refactor tests
* factor out duplicated code * make tests an importable package * idiomatic pytest usage * do not touch files outside of the tmp test tree and do not depend on external state (except for /nix/store ☹) * run coverage to root out dead code
This commit is contained in:
parent
c3c23453e4
commit
0d145c01d5
12 changed files with 252 additions and 240 deletions
|
|
@ -4,6 +4,11 @@ line-length = 88
|
||||||
select = ["E", "F", "I"]
|
select = ["E", "F", "I"]
|
||||||
ignore = [ "E501" ]
|
ignore = [ "E501" ]
|
||||||
|
|
||||||
|
[tool.coverage.report]
|
||||||
|
exclude_lines = [
|
||||||
|
"pragma: no cover",
|
||||||
|
"pytest.skip",
|
||||||
|
]
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
python_version = "3.10"
|
python_version = "3.10"
|
||||||
warn_redundant_casts = true
|
warn_redundant_casts = true
|
||||||
|
|
|
||||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
105
tests/case.py
Normal file
105
tests/case.py
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import functools
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
CMD = Path | str
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
TEST_ROOT = Path(__file__).parent
|
||||||
|
|
||||||
|
PROJECT_ROOT = TEST_ROOT.parent
|
||||||
|
|
||||||
|
NIX_DIRENV = PROJECT_ROOT / "direnvrc"
|
||||||
|
|
||||||
|
|
||||||
|
class TestCase:
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def _setup(self, tmp_path: Path) -> None:
|
||||||
|
self.root = tmp_path
|
||||||
|
log.debug(f"path: {self.root}")
|
||||||
|
|
||||||
|
@functools.cached_property
|
||||||
|
def home(self) -> Path:
|
||||||
|
return self.root / "home"
|
||||||
|
|
||||||
|
@functools.cached_property
|
||||||
|
def path(self) -> Path:
|
||||||
|
path = self.root / "cwd"
|
||||||
|
shutil.copytree(TEST_ROOT / "testenv", path)
|
||||||
|
return path
|
||||||
|
|
||||||
|
def _log_output(
|
||||||
|
self,
|
||||||
|
result: subprocess.CompletedProcess | subprocess.CalledProcessError,
|
||||||
|
errlevel: str = "debug",
|
||||||
|
) -> None:
|
||||||
|
for out in ("stdout", "stderr"):
|
||||||
|
text = getattr(result, out).strip()
|
||||||
|
setattr(result, out, text)
|
||||||
|
if text:
|
||||||
|
getattr(log, errlevel if out == "stderr" else "debug")(
|
||||||
|
f"{out[3:]}:{os.linesep if os.linesep in text else ' '}{text}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(
|
||||||
|
self,
|
||||||
|
*cmd: CMD,
|
||||||
|
**env: str,
|
||||||
|
) -> subprocess.CompletedProcess:
|
||||||
|
env = dict(PATH=os.environ["PATH"], HOME=str(self.home)) | env
|
||||||
|
command = list(map(str, cmd))
|
||||||
|
log.debug(f"$ {subprocess.list2cmdline(command)}")
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
command,
|
||||||
|
capture_output=True,
|
||||||
|
check=True,
|
||||||
|
text=True,
|
||||||
|
cwd=self.path,
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError as exc: # pragma: no cover
|
||||||
|
self._log_output(exc, errlevel="error")
|
||||||
|
raise
|
||||||
|
self._log_output(result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def nix_run(self, *cmd: CMD, **env: str) -> subprocess.CompletedProcess:
|
||||||
|
return self.run("nix", *cmd, **env)
|
||||||
|
|
||||||
|
def direnv_run(self, *cmd: CMD, **env: str) -> subprocess.CompletedProcess:
|
||||||
|
return self.run("direnv", *cmd, **env)
|
||||||
|
|
||||||
|
def direnv_exec(self, *cmd: CMD, **env: str) -> subprocess.CompletedProcess:
|
||||||
|
return self.run("direnv", "exec", ".", *cmd, **env)
|
||||||
|
|
||||||
|
def direnv_var(self, name: str, **env: str) -> subprocess.CompletedProcess:
|
||||||
|
return self.direnv_exec("sh", "-c", f"echo -n ${name}", **env)
|
||||||
|
|
||||||
|
def setup_envrc(
|
||||||
|
self, content: str, strict_env: bool, **env: str
|
||||||
|
) -> subprocess.CompletedProcess:
|
||||||
|
text = textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
{'strict_env' if strict_env else ''}
|
||||||
|
source {NIX_DIRENV}
|
||||||
|
{content}
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
(self.path / ".envrc").write_text(text.strip())
|
||||||
|
return self.direnv_run("allow", **env)
|
||||||
|
|
||||||
|
def assert_direnv_var(self, name: str, **env: str) -> subprocess.CompletedProcess:
|
||||||
|
result = self.direnv_var(name, **env)
|
||||||
|
assert result.stdout == "OK"
|
||||||
|
assert "renewed cache" in result.stderr
|
||||||
|
return result
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
pytest_plugins = [
|
|
||||||
"direnv_project",
|
|
||||||
"root",
|
|
||||||
]
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
import shutil
|
|
||||||
import textwrap
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from pathlib import Path
|
|
||||||
from tempfile import TemporaryDirectory
|
|
||||||
from typing import Iterator
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from procs import run
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DirenvProject:
|
|
||||||
dir: Path
|
|
||||||
nix_direnv: Path
|
|
||||||
|
|
||||||
@property
|
|
||||||
def envrc(self) -> Path:
|
|
||||||
return self.dir / ".envrc"
|
|
||||||
|
|
||||||
def setup_envrc(self, content: str, strict_env: bool) -> None:
|
|
||||||
text = textwrap.dedent(
|
|
||||||
f"""
|
|
||||||
{'strict_env' if strict_env else ''}
|
|
||||||
source {self.nix_direnv}
|
|
||||||
{content}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
self.envrc.write_text(text)
|
|
||||||
run(["direnv", "allow"], cwd=self.dir)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def direnv_project(test_root: Path, project_root: Path) -> Iterator[DirenvProject]:
|
|
||||||
"""
|
|
||||||
Setups a direnv test project
|
|
||||||
"""
|
|
||||||
with TemporaryDirectory() as _dir:
|
|
||||||
dir = Path(_dir) / "proj"
|
|
||||||
shutil.copytree(test_root / "testenv", dir)
|
|
||||||
shutil.copyfile(project_root / "flake.nix", dir / "flake.nix")
|
|
||||||
shutil.copyfile(project_root / "flake.lock", dir / "flake.lock")
|
|
||||||
nix_direnv = project_root / "direnvrc"
|
|
||||||
|
|
||||||
c = DirenvProject(Path(dir), nix_direnv)
|
|
||||||
try:
|
|
||||||
yield c
|
|
||||||
finally:
|
|
||||||
pass
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import IO, Any, List, Optional, Union
|
|
||||||
|
|
||||||
_FILE = Union[None, int, IO[Any]]
|
|
||||||
_DIR = Union[None, Path, str]
|
|
||||||
|
|
||||||
|
|
||||||
def run(
|
|
||||||
cmd: List[str],
|
|
||||||
text: bool = True,
|
|
||||||
check: bool = True,
|
|
||||||
cwd: _DIR = None,
|
|
||||||
stderr: _FILE = None,
|
|
||||||
stdout: _FILE = None,
|
|
||||||
env: Optional[dict[str, str]] = None,
|
|
||||||
) -> subprocess.CompletedProcess:
|
|
||||||
if cwd is not None:
|
|
||||||
print(f"cd {cwd}")
|
|
||||||
print("$ " + " ".join(cmd))
|
|
||||||
return subprocess.run(
|
|
||||||
cmd, text=text, check=check, cwd=cwd, stderr=stderr, stdout=stdout, env=env
|
|
||||||
)
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
TEST_ROOT = Path(__file__).parent.resolve()
|
|
||||||
PROJECT_ROOT = TEST_ROOT.parent
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def test_root() -> Path:
|
|
||||||
"""
|
|
||||||
Root directory of the tests
|
|
||||||
"""
|
|
||||||
return TEST_ROOT
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def project_root() -> Path:
|
|
||||||
"""
|
|
||||||
Root directory of the tests
|
|
||||||
"""
|
|
||||||
return PROJECT_ROOT
|
|
||||||
133
tests/test_gc.py
133
tests/test_gc.py
|
|
@ -1,92 +1,65 @@
|
||||||
import subprocess
|
from __future__ import annotations
|
||||||
import sys
|
|
||||||
import unittest
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from direnv_project import DirenvProject
|
|
||||||
from procs import run
|
from .case import TestCase
|
||||||
|
|
||||||
|
|
||||||
def common_test(direnv_project: DirenvProject) -> None:
|
class TestGc(TestCase):
|
||||||
run(["nix-collect-garbage"])
|
def common_test(self) -> None:
|
||||||
|
result = self.direnv_exec("hello")
|
||||||
|
assert "renewed cache" in result.stderr
|
||||||
|
assert "Executing shellHook." in result.stderr
|
||||||
|
|
||||||
testenv = str(direnv_project.dir)
|
self.nix_run("store", "gc")
|
||||||
|
|
||||||
out1 = run(
|
result = self.direnv_exec("hello")
|
||||||
["direnv", "exec", testenv, "hello"],
|
assert "using cached dev shell" in result.stderr
|
||||||
stderr=subprocess.PIPE,
|
assert "Executing shellHook." in result.stderr
|
||||||
check=False,
|
|
||||||
cwd=direnv_project.dir,
|
|
||||||
)
|
|
||||||
sys.stderr.write(out1.stderr)
|
|
||||||
assert out1.returncode == 0
|
|
||||||
assert "renewed cache" in out1.stderr
|
|
||||||
assert "Executing shellHook." in out1.stderr
|
|
||||||
|
|
||||||
run(["nix-collect-garbage"])
|
def common_test_clean(self) -> None:
|
||||||
|
self.direnv_exec("hello")
|
||||||
|
files = [path for path in (self.path / ".direnv").iterdir() if path.is_file()]
|
||||||
|
rcs = [f for f in files if f.match("*.rc")]
|
||||||
|
profiles = [f for f in files if not f.match("*.rc")]
|
||||||
|
assert len(rcs) == 1, files
|
||||||
|
assert len(profiles) == 1, files
|
||||||
|
|
||||||
out2 = run(
|
@pytest.mark.parametrize("strict_env", [False, True])
|
||||||
["direnv", "exec", testenv, "hello"],
|
def test_use_nix(self, strict_env: bool) -> None:
|
||||||
stderr=subprocess.PIPE,
|
self.setup_envrc("use nix", strict_env=strict_env)
|
||||||
check=False,
|
self.common_test()
|
||||||
cwd=direnv_project.dir,
|
|
||||||
)
|
|
||||||
sys.stderr.write(out2.stderr)
|
|
||||||
assert out2.returncode == 0
|
|
||||||
assert "using cached dev shell" in out2.stderr
|
|
||||||
assert "Executing shellHook." in out2.stderr
|
|
||||||
|
|
||||||
|
self.setup_envrc(
|
||||||
|
"use nix --argstr shellHook 'echo Executing hijacked shellHook.'",
|
||||||
|
strict_env=strict_env,
|
||||||
|
)
|
||||||
|
self.common_test_clean()
|
||||||
|
|
||||||
def common_test_clean(direnv_project: DirenvProject) -> None:
|
def _parse_inputs(self, inputs: dict) -> list:
|
||||||
testenv = str(direnv_project.dir)
|
paths = [inputs["path"]]
|
||||||
|
for xinput in inputs["inputs"].values():
|
||||||
|
paths.extend(self._parse_inputs(xinput))
|
||||||
|
return paths
|
||||||
|
|
||||||
out3 = run(
|
@pytest.mark.parametrize("strict_env", [False, True])
|
||||||
["direnv", "exec", testenv, "hello"],
|
def test_use_flake(self, strict_env: bool) -> None:
|
||||||
stderr=subprocess.PIPE,
|
self.setup_envrc("use flake", strict_env=strict_env)
|
||||||
check=False,
|
self.common_test()
|
||||||
cwd=direnv_project.dir,
|
inputs = list((self.path / ".direnv/flake-inputs").iterdir())
|
||||||
)
|
flake_inputs = self._parse_inputs(
|
||||||
sys.stderr.write(out3.stderr)
|
json.loads(
|
||||||
|
self.nix_run(
|
||||||
|
"flake", "archive", "--json", "--no-write-lock-file"
|
||||||
|
).stdout
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# should only contain our flake-utils flake
|
||||||
|
assert len(inputs) == len(flake_inputs)
|
||||||
|
for symlink in inputs:
|
||||||
|
assert symlink.is_dir()
|
||||||
|
|
||||||
files = [
|
self.setup_envrc("use flake --impure", strict_env=strict_env)
|
||||||
path for path in (direnv_project.dir / ".direnv").iterdir() if path.is_file()
|
self.common_test_clean()
|
||||||
]
|
|
||||||
rcs = [f for f in files if f.match("*.rc")]
|
|
||||||
profiles = [f for f in files if not f.match("*.rc")]
|
|
||||||
if len(rcs) != 1 or len(profiles) != 1:
|
|
||||||
print(files)
|
|
||||||
assert len(rcs) == 1
|
|
||||||
assert len(profiles) == 1
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict_env", [False, True])
|
|
||||||
def test_use_nix(direnv_project: DirenvProject, strict_env: bool) -> None:
|
|
||||||
direnv_project.setup_envrc("use nix", strict_env=strict_env)
|
|
||||||
common_test(direnv_project)
|
|
||||||
|
|
||||||
direnv_project.setup_envrc(
|
|
||||||
"use nix --argstr shellHook 'echo Executing hijacked shellHook.'",
|
|
||||||
strict_env=strict_env,
|
|
||||||
)
|
|
||||||
common_test_clean(direnv_project)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict_env", [False, True])
|
|
||||||
def test_use_flake(direnv_project: DirenvProject, strict_env: bool) -> None:
|
|
||||||
direnv_project.setup_envrc("use flake", strict_env=strict_env)
|
|
||||||
common_test(direnv_project)
|
|
||||||
inputs = list((direnv_project.dir / ".direnv/flake-inputs").iterdir())
|
|
||||||
# should only contain our flake-utils flake
|
|
||||||
if len(inputs) != 4:
|
|
||||||
run(["nix", "flake", "archive", "--json"], cwd=direnv_project.dir)
|
|
||||||
print(inputs)
|
|
||||||
assert len(inputs) == 4
|
|
||||||
for symlink in inputs:
|
|
||||||
assert symlink.is_dir()
|
|
||||||
|
|
||||||
direnv_project.setup_envrc("use flake --impure", strict_env=strict_env)
|
|
||||||
common_test_clean(direnv_project)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,35 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from direnv_project import DirenvProject
|
|
||||||
from procs import run
|
from .case import TestCase
|
||||||
|
|
||||||
|
|
||||||
def direnv_exec(
|
class TestUseNix(TestCase):
|
||||||
direnv_project: DirenvProject, cmd: str, env: Optional[dict[str, str]] = None
|
@pytest.mark.parametrize("strict_env", [False, True])
|
||||||
) -> None:
|
def test_attrs(self, strict_env: bool) -> None:
|
||||||
args = ["direnv", "exec", str(direnv_project.dir), "sh", "-c", cmd]
|
self.setup_envrc("use nix -A subshell", strict_env=strict_env)
|
||||||
print("$ " + " ".join(args))
|
self.assert_direnv_var("THIS_IS_A_SUBSHELL")
|
||||||
out = run(
|
|
||||||
args,
|
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
check=False,
|
|
||||||
cwd=direnv_project.dir,
|
|
||||||
env=env,
|
|
||||||
)
|
|
||||||
sys.stdout.write(out.stdout)
|
|
||||||
sys.stderr.write(out.stderr)
|
|
||||||
assert out.returncode == 0
|
|
||||||
assert "OK\n" == out.stdout
|
|
||||||
assert "renewed cache" in out.stderr
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("strict_env", [False, True])
|
||||||
|
def test_with_nix_path(self, strict_env: bool) -> None:
|
||||||
|
if (nix_path := os.environ.get("NIX_PATH")) is None:
|
||||||
|
pytest.skip("no parent NIX_PATH")
|
||||||
|
else:
|
||||||
|
self.setup_envrc(
|
||||||
|
"use nix --argstr someArg OK", strict_env=strict_env, NIX_PATH=nix_path
|
||||||
|
)
|
||||||
|
self.assert_direnv_var("SHOULD_BE_SET", NIX_PATH=nix_path)
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict_env", [False, True])
|
@pytest.mark.parametrize("strict_env", [False, True])
|
||||||
def test_attrs(direnv_project: DirenvProject, strict_env: bool) -> None:
|
def test_args(self, strict_env: bool) -> None:
|
||||||
direnv_project.setup_envrc("use nix -A subshell", strict_env=strict_env)
|
self.setup_envrc("use nix --argstr someArg OK", strict_env=strict_env)
|
||||||
direnv_exec(direnv_project, "echo $THIS_IS_A_SUBSHELL")
|
self.assert_direnv_var("SHOULD_BE_SET")
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("strict_env", [False, True])
|
||||||
@pytest.mark.parametrize("strict_env", [False, True])
|
def test_no_files(self, strict_env: bool) -> None:
|
||||||
def test_no_nix_path(direnv_project: DirenvProject, strict_env: bool) -> None:
|
self.setup_envrc("use nix -p hello", strict_env=strict_env)
|
||||||
direnv_project.setup_envrc("use nix --argstr someArg OK", strict_env=strict_env)
|
result = self.direnv_run("status")
|
||||||
env = os.environ.copy()
|
assert 'Loaded watch: "."' not in result.stdout
|
||||||
del env["NIX_PATH"]
|
|
||||||
direnv_exec(direnv_project, "echo $SHOULD_BE_SET", env=env)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict_env", [False, True])
|
|
||||||
def test_args(direnv_project: DirenvProject, strict_env: bool) -> None:
|
|
||||||
direnv_project.setup_envrc("use nix --argstr someArg OK", strict_env=strict_env)
|
|
||||||
direnv_exec(direnv_project, "echo $SHOULD_BE_SET")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict_env", [False, True])
|
|
||||||
def test_no_files(direnv_project: DirenvProject, strict_env: bool) -> None:
|
|
||||||
direnv_project.setup_envrc("use nix -p hello", strict_env=strict_env)
|
|
||||||
out = run(
|
|
||||||
["direnv", "status"],
|
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
check=False,
|
|
||||||
cwd=direnv_project.dir,
|
|
||||||
)
|
|
||||||
assert out.returncode == 0
|
|
||||||
assert 'Loaded watch: "."' not in out.stdout
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
source ../../direnvrc
|
|
||||||
use nix
|
|
||||||
61
tests/testenv/flake.lock
generated
Normal file
61
tests/testenv/flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1694529238,
|
||||||
|
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1700856099,
|
||||||
|
"narHash": "sha256-RnEA7iJ36Ay9jI0WwP+/y4zjEhmeN6Cjs9VOFBH7eVQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "0bd59c54ef06bc34eca01e37d689f5e46b3fe2f1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
description = "A very basic flake";
|
description = "A very basic flake";
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs";
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }:
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue