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
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from testlib.fixtures.nix import Nix
from testlib.fixtures.git import Git
from testlib.fixtures.file_helper import with_files, File, EnvTemplate, CopyFile
from testlib.environ import environ
from testlib.utils import get_global_asset, get_global_asset_pack
from pathlib import Path
import pytest

system = environ.get("system")

flake = {
    "flake.nix": EnvTemplate(f"""{{
        inputs.nixpkgs.url = "@HOME@/nixpkgs";
        outputs = {{self, nixpkgs}}: {{
          packages.{system}.hello = (import ./config.nix).mkDerivation {{
            name = "hello";
            outputs = [ "out" "dev" ];
            meta.outputsToInstall = [ "out" ];
            buildCommand = "";
          }};
        }};
    }}"""),
    "config.nix": get_global_asset("config.nix"),
    "shell-hello.nix": CopyFile("assets/shell-hello.nix"),
}
nixpkgs = {
    "flake.nix": File(f"""{{
        outputs = {{self}}: {{
          legacyPackages.{system}.bashInteractive = (import ./shell.nix {{}}).bashInteractive;
        }};
    }}"""),
    "config.nix": get_global_asset("config.nix"),
    "shell.nix": get_global_asset("shell.nix"),
}


@pytest.fixture(autouse=True)
def common_init(nix: Nix):
    nix.settings.add_xp_feature("nix-command", "flakes")


@with_files(flake | {"nixpkgs": nixpkgs})
class TestDevelop:
    def test_env_passthrough(self, nix: Nix):
        nix.env["ENVVAR"] = "a"

        result = (
            nix.nix(["develop", "--no-write-lock-file", ".#hello"])
            .with_stdin(b'echo "$ENVVAR"')
            .run()
            .ok()
        )
        assert result.stdout_s == "a\n"

    def test_no_env_passthrough_on_ignore_environment(self, nix: Nix):
        nix.env["ENVVAR"] = "a"

        result = (
            nix.nix(["develop", "--ignore-environment", "--no-write-lock-file", ".#hello"])
            .with_stdin(b'echo "$ENVVAR"')
            .run()
            .ok()
        )
        assert result.stdout_s == "\n"

    class TestShell:
        @pytest.fixture(autouse=True)
        def shell_init(self, nix: Nix, files: Path):  # noqa: ARG002
            nix.nix(
                [
                    "build",
                    "--no-write-lock-file",
                    "./nixpkgs#bashInteractive",
                    "--out-link",
                    "./bash-interactive",
                ]
            ).run().ok()
            self.bash_interactive = nix.env.dirs.home / "bash-interactive/bin/bash"

            nix.env["SHELL"] = "custom"

        @pytest.mark.parametrize("extra_args", [[], ["--ignore-environment"]])
        def test_shell_is_bash_interactive(self, nix: Nix, extra_args: list[str]):
            result = (
                nix.nix(["develop", *extra_args, "--no-write-lock-file", ".#hello"])
                .with_stdin(b'echo "$SHELL"')
                .run()
                .ok()
            )
            assert Path(result.stdout_s.strip()).samefile(self.bash_interactive)

    @pytest.mark.parametrize("extra_args", [[], ["--ignore-environment"]])
    def test_sets_in_nix_shell(self, nix: Nix, extra_args: list[str]):
        result = (
            nix.nix(
                [
                    "develop",
                    "--no-write-lock-file",
                    *extra_args,
                    ".#hello",
                    "-c",
                    "sh",
                    "-c",
                    "echo $IN_NIX_SHELL",
                ]
            )
            .run()
            .ok()
        )
        assert result.stdout_s == "impure\n"


@with_files(
    {
        "t": flake | get_global_asset_pack(".git") | {".gitignore": File("flake.lock\n")},
        "nixpkgs": nixpkgs,
    }
)
def test_ignoring_lockfile_does_not_break_develop(nix: Nix, files: Path, git: Git):
    git(files / "t", "add", "config.nix", "shell-hello.nix", "flake.nix", ".gitignore")

    nix.nix(["develop", ".#hello"], cwd=files / "t").with_stdin(b"true").run().ok()