diff --git a/src/libutil/union-source-accessor.cc b/src/libutil/union-source-accessor.cc index e3b39f14ed2..ca239563c66 100644 --- a/src/libutil/union-source-accessor.cc +++ b/src/libutil/union-source-accessor.cc @@ -35,14 +35,18 @@ struct UnionSourceAccessor : SourceAccessor DirEntries readDirectory(const CanonPath & path) override { DirEntries result; + bool exists = false; for (auto & accessor : accessors) { auto st = accessor->maybeLstat(path); if (!st) continue; + exists = true; for (auto & entry : accessor->readDirectory(path)) // Don't override entries from previous accessors. result.insert(entry); } + if (!exists) + throw FileNotFound("path '%s' does not exist", showPath(path)); return result; } diff --git a/tests/functional/lang/eval-fail-readDir-nonexistent-1.err.exp b/tests/functional/lang/eval-fail-readDir-nonexistent-1.err.exp new file mode 100644 index 00000000000..eedce081807 --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-nonexistent-1.err.exp @@ -0,0 +1,16 @@ +error: + … while evaluating the attribute 'absolutePath' + at /pwd/lang/eval-fail-readDir-nonexistent-1.nix:2:3: + 1| { + 2| absolutePath = builtins.readDir /this/path/really/should/not/exist; + | ^ + 3| } + + … while calling the 'readDir' builtin + at /pwd/lang/eval-fail-readDir-nonexistent-1.nix:2:18: + 1| { + 2| absolutePath = builtins.readDir /this/path/really/should/not/exist; + | ^ + 3| } + + error: path '/this/path/really/should/not/exist' does not exist diff --git a/tests/functional/lang/eval-fail-readDir-nonexistent-1.nix b/tests/functional/lang/eval-fail-readDir-nonexistent-1.nix new file mode 100644 index 00000000000..4b9a53c2d7d --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-nonexistent-1.nix @@ -0,0 +1,3 @@ +{ + absolutePath = builtins.readDir /this/path/really/should/not/exist; +} diff --git a/tests/functional/lang/eval-fail-readDir-nonexistent-2.err.exp b/tests/functional/lang/eval-fail-readDir-nonexistent-2.err.exp new file mode 100644 index 00000000000..0be546b27bc --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-nonexistent-2.err.exp @@ -0,0 +1,16 @@ +error: + … while evaluating the attribute 'relativePath' + at /pwd/lang/eval-fail-readDir-nonexistent-2.nix:2:3: + 1| { + 2| relativePath = builtins.readDir ./this/path/really/should/not/exist; + | ^ + 3| } + + … while calling the 'readDir' builtin + at /pwd/lang/eval-fail-readDir-nonexistent-2.nix:2:18: + 1| { + 2| relativePath = builtins.readDir ./this/path/really/should/not/exist; + | ^ + 3| } + + error: path '/pwd/lang/this/path/really/should/not/exist' does not exist diff --git a/tests/functional/lang/eval-fail-readDir-nonexistent-2.nix b/tests/functional/lang/eval-fail-readDir-nonexistent-2.nix new file mode 100644 index 00000000000..14be5671c8a --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-nonexistent-2.nix @@ -0,0 +1,3 @@ +{ + relativePath = builtins.readDir ./this/path/really/should/not/exist; +} diff --git a/tests/functional/lang/eval-fail-readDir-not-a-directory-1.err.exp b/tests/functional/lang/eval-fail-readDir-not-a-directory-1.err.exp new file mode 100644 index 00000000000..f94a7ed7452 --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-not-a-directory-1.err.exp @@ -0,0 +1,16 @@ +error: + … while evaluating the attribute 'regularFile' + at /pwd/lang/eval-fail-readDir-not-a-directory-1.nix:2:3: + 1| { + 2| regularFile = builtins.readDir ./readDir/bar; + | ^ + 3| } + + … while calling the 'readDir' builtin + at /pwd/lang/eval-fail-readDir-not-a-directory-1.nix:2:17: + 1| { + 2| regularFile = builtins.readDir ./readDir/bar; + | ^ + 3| } + + error: cannot read directory "/pwd/lang/readDir/bar": Not a directory diff --git a/tests/functional/lang/eval-fail-readDir-not-a-directory-1.nix b/tests/functional/lang/eval-fail-readDir-not-a-directory-1.nix new file mode 100644 index 00000000000..02b4f8551f3 --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-not-a-directory-1.nix @@ -0,0 +1,3 @@ +{ + regularFile = builtins.readDir ./readDir/bar; +} diff --git a/tests/functional/lang/eval-fail-readDir-not-a-directory-2.err.exp b/tests/functional/lang/eval-fail-readDir-not-a-directory-2.err.exp new file mode 100644 index 00000000000..f5e6775545a --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-not-a-directory-2.err.exp @@ -0,0 +1,16 @@ +error: + … while evaluating the attribute 'symlinkedRegularFile' + at /pwd/lang/eval-fail-readDir-not-a-directory-2.nix:2:3: + 1| { + 2| symlinkedRegularFile = builtins.readDir ./readDir/linked; + | ^ + 3| } + + … while calling the 'readDir' builtin + at /pwd/lang/eval-fail-readDir-not-a-directory-2.nix:2:26: + 1| { + 2| symlinkedRegularFile = builtins.readDir ./readDir/linked; + | ^ + 3| } + + error: cannot read directory "/pwd/lang/readDir/foo/git-hates-directories": Not a directory diff --git a/tests/functional/lang/eval-fail-readDir-not-a-directory-2.nix b/tests/functional/lang/eval-fail-readDir-not-a-directory-2.nix new file mode 100644 index 00000000000..1756684a747 --- /dev/null +++ b/tests/functional/lang/eval-fail-readDir-not-a-directory-2.nix @@ -0,0 +1,3 @@ +{ + symlinkedRegularFile = builtins.readDir ./readDir/linked; +} diff --git a/tests/functional/lang/eval-okay-readDir-symlinked-directory.exp b/tests/functional/lang/eval-okay-readDir-symlinked-directory.exp new file mode 100644 index 00000000000..f9a314482df --- /dev/null +++ b/tests/functional/lang/eval-okay-readDir-symlinked-directory.exp @@ -0,0 +1 @@ +{ git-hates-directories = "regular"; } diff --git a/tests/functional/lang/eval-okay-readDir-symlinked-directory.nix b/tests/functional/lang/eval-okay-readDir-symlinked-directory.nix new file mode 100644 index 00000000000..a052b259774 --- /dev/null +++ b/tests/functional/lang/eval-okay-readDir-symlinked-directory.nix @@ -0,0 +1 @@ +builtins.readDir ./readDir/ldir