diff --git a/tests/functional/flakes/search-root.sh b/tests/functional/flakes/search-root.sh deleted file mode 100644 index d8586dc8a..000000000 --- a/tests/functional/flakes/search-root.sh +++ /dev/null @@ -1,50 +0,0 @@ -source common.sh - -clearStore - -writeSimpleFlake $TEST_HOME -cd $TEST_HOME -mkdir -p foo/subdir - -echo '{ outputs = _: {}; }' > foo/flake.nix -cat < flake.nix -{ - inputs.foo.url = "$PWD/foo"; - outputs = a: { - packages.$system = rec { - test = import ./simple.nix; - default = test; - }; - }; -} -EOF -mkdir subdir -pushd subdir - -success=("" . .# .#test ../subdir ../subdir#test "$PWD") -failure=("path:$PWD") - -for i in "${success[@]}"; do - nix build $i || fail "flake should be found by searching up directories" -done - -for i in "${failure[@]}"; do - ! nix build $i || fail "flake should not search up directories when using 'path:'" -done - -popd - -nix build --override-input foo . || fail "flake should search up directories when not an installable" - -sed "s,$PWD/foo,$PWD/foo/subdir,g" -i flake.nix -! nix build || fail "flake should not search upwards when part of inputs" - -if [[ -n $(type -p git) ]]; then - pushd subdir - git init - for i in "${success[@]}" "${failure[@]}"; do - ! nix build $i || fail "flake should not search past a git repository" - done - rm -rf .git - popd -fi diff --git a/tests/functional/meson.build b/tests/functional/meson.build index aefa18ac7..dee9ae40f 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -89,7 +89,6 @@ functional_tests_scripts = [ 'secure-drv-outputs.sh', 'restricted.sh', 'fetchGitSubmodules.sh', - 'flakes/search-root.sh', 'readfile-context.sh', 'nix-channel.sh', 'dependencies.sh', diff --git a/tests/functional2/flakes/test_search_path.py b/tests/functional2/flakes/test_search_path.py new file mode 100644 index 000000000..1ea25d391 --- /dev/null +++ b/tests/functional2/flakes/test_search_path.py @@ -0,0 +1,89 @@ +from testlib.fixtures.nix import Nix +from testlib.fixtures.git import Git +from testlib.fixtures.file_helper import with_files, File +from testlib.environ import environ +from pathlib import Path +import pytest +from .common import simple_flake + +system = environ.get("system") + +files = simple_flake() | {"foo": {"flake.nix": File("{ outputs = _: {}; }")}, "subdir": {}} + + +@pytest.fixture(autouse=True) +def common_init(nix: Nix, files: Path): + nix.settings.add_xp_feature("nix-command", "flakes") + + flake = files / "flake.nix" + flake.write_text(f""" + {{ + inputs.foo.url = "{files}/foo"; + outputs = a: {{ + packages.{system} = rec {{ + test = import ./simple.nix; + default = test; + }}; + }}; + }} + """) + + +good_uris: list[list[str]] = [ + [], + ["."], + [".#"], + [".#test"], + ["../subdir"], + ["../subdir#test"], + ["$PWD"], +] + + +@with_files(files) +class TestFlakeSearchPath: + @pytest.mark.parametrize("args", good_uris) + def test_flake_search_goes_up(self, nix: Nix, files: Path, args: list[str]): + subdir = files / "subdir" + nix.nix( + ["build", *[arg.replace("$PWD", str(subdir)) for arg in args]], cwd=subdir + ).run().ok() + + def test_flake_search_inactive_with_path_uri(self, nix: Nix, files: Path): + subdir = files / "subdir" + assert ( + "does not contain a '/flake.nix' file" + in nix.nix(["build", f"path:{subdir}"], cwd=subdir).run().expect(1).stderr_s + ) + + def test_flake_search_goes_up_without_installable(self, nix: Nix): + nix.nix(["build", "--override-input", "foo", "."]).run().ok() + + def test_flake_inputs_do_not_search(self, nix: Nix, files: Path): + flake = files / "flake.nix" + flake.write_text(flake.read_text().replace(str(files / "foo"), str(files / "foo/subdir"))) + nix.nix(["build"]).run().expect(1) + + @pytest.mark.parametrize("args", good_uris) + def test_flake_search_does_not_cross_git_repo( + self, git: Git, nix: Nix, files: Path, args: list[str] + ): + subdir = files / "subdir" + git(subdir, "init") + assert ( + "is not part of a flake" + in nix.nix(["build", *[arg.replace("$PWD", str(subdir)) for arg in args]], cwd=subdir) + .run() + .expect(1) + .stderr_s + ) + + def test_flake_search_does_not_cross_git_repo_with_path_ru( + self, git: Git, nix: Nix, files: Path + ): + subdir = files / "subdir" + git(subdir, "init") + assert ( + "does not contain a '/flake.nix' file" + in nix.nix(["build", f"path:{subdir}"], cwd=subdir).run().expect(1).stderr_s + ) diff --git a/tests/functional2/testlib/fixtures/nix.py b/tests/functional2/testlib/fixtures/nix.py index 8bfe58791..bebe0bd52 100644 --- a/tests/functional2/testlib/fixtures/nix.py +++ b/tests/functional2/testlib/fixtures/nix.py @@ -155,7 +155,7 @@ class Nix: return self._settings - def nix_cmd(self, argv: list[str], flake: bool = False) -> Command: + def nix_cmd(self, argv: list[str], flake: bool = False, cwd: Path | None = None) -> Command: """ Constructs a NixCommand with the appropriate settings. :param build: if the executed command wants to build stuff. This is required due to darwin shenanigans. "auto" will try to autodetect, override using `True` or `False`. Has no effect on linux. @@ -166,10 +166,12 @@ class Nix: settings.add_xp_feature("nix-command", "flakes") settings.to_env_overlay(self.env) - return Command(argv=argv, exe=self._nix_executable, _env=self.env) + return Command(argv=argv, exe=self._nix_executable, _env=self.env, cwd=cwd) - def nix(self, cmd: list[str], nix_exe: str = "nix", flake: bool = False) -> Command: - return self.nix_cmd([nix_exe, *cmd], flake=flake) + def nix( + self, cmd: list[str], nix_exe: str = "nix", flake: bool = False, cwd: Path | None = None + ) -> Command: + return self.nix_cmd([nix_exe, *cmd], flake=flake, cwd=cwd) @contextlib.contextmanager def daemon(