From 11a1dcc43b3830dc25319719bccc71572136c57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Wed, 28 Feb 2024 16:59:06 +0100 Subject: [PATCH 1/2] Properly fail on flakerefs that don't point to a directory Directly fail if a flakeref points to something that isn't a directory instead of falling back to the logic of trying to look up the hierarchy to find a valid flake root. Fix https://github.com/NixOS/nix/issues/9868 --- src/libexpr/flake/flakeref.cc | 6 +++--- tests/functional/flakes/search-root.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 86a0982f3..09b5cecbc 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -102,6 +102,9 @@ std::pair parsePathFlakeRefWithFragment( if (isFlake) { + if (!S_ISDIR(lstat(path).st_mode)) + throw BadURL("path '%s' is not a flake (because it's not a directory)", path); + if (!allowMissing && !pathExists(path + "/flake.nix")){ notice("path '%s' does not contain a 'flake.nix', searching up",path); @@ -124,9 +127,6 @@ std::pair parsePathFlakeRefWithFragment( throw BadURL("could not find a flake.nix file"); } - if (!S_ISDIR(lstat(path).st_mode)) - throw BadURL("path '%s' is not a flake (because it's not a directory)", path); - if (!allowMissing && !pathExists(path + "/flake.nix")) throw BadURL("path '%s' is not a flake (because it doesn't contain a 'flake.nix' file)", path); diff --git a/tests/functional/flakes/search-root.sh b/tests/functional/flakes/search-root.sh index d8586dc8a..6b137aa86 100644 --- a/tests/functional/flakes/search-root.sh +++ b/tests/functional/flakes/search-root.sh @@ -22,7 +22,7 @@ mkdir subdir pushd subdir success=("" . .# .#test ../subdir ../subdir#test "$PWD") -failure=("path:$PWD") +failure=("path:$PWD" "../simple.nix") for i in "${success[@]}"; do nix build $i || fail "flake should be found by searching up directories" From 2f0bc6373ce1cc62f6b0ec955a227762904a66df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Sat, 2 Mar 2024 10:34:20 +0100 Subject: [PATCH 2/2] Don't fail if a flakeref directly points to the flake.nix Just warn and redirect it to the parent directory --- src/libexpr/flake/flakeref.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 09b5cecbc..6c534f429 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -102,8 +102,18 @@ std::pair parsePathFlakeRefWithFragment( if (isFlake) { - if (!S_ISDIR(lstat(path).st_mode)) - throw BadURL("path '%s' is not a flake (because it's not a directory)", path); + if (!S_ISDIR(lstat(path).st_mode)) { + if (baseNameOf(path) == "flake.nix") { + // Be gentle with people who accidentally write `/foo/bar/flake.nix` instead of `/foo/bar` + warn( + "Path '%s' should point at the directory containing the 'flake.nix' file, not the file itself. " + "Pretending that you meant '%s'" + , path, dirOf(path)); + path = dirOf(path); + } else { + throw BadURL("path '%s' is not a flake (because it's not a directory)", path); + } + } if (!allowMissing && !pathExists(path + "/flake.nix")){ notice("path '%s' does not contain a 'flake.nix', searching up",path);