diff --git a/lib/customisation.nix b/lib/customisation.nix index 9c50e6a26c3d..c73f2f2911bb 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -291,7 +291,7 @@ rec { if loc != null then loc.file + ":" + toString loc.line else if !isFunction fn then - toString fn + optionalString (pathIsDirectory fn) "/default.nix" + toString (lib.filesystem.resolveDefaultNix fn) else ""; in diff --git a/lib/filesystem.nix b/lib/filesystem.nix index 49e4f8363513..1014c274041f 100644 --- a/lib/filesystem.nix +++ b/lib/filesystem.nix @@ -454,4 +454,46 @@ in ) else processDir args; + + /** + Append `/default.nix` if the passed path is a directory. + + # Type + + ``` + resolveDefaultNix :: (Path | String) -> (Path | String) + ``` + + # Inputs + + A single argument which can be a [path](https://nix.dev/manual/nix/stable/language/types#type-path) value or a string containing an absolute path. + + # Output + + If the input refers to a directory that exists, the output is that same path with `/default.nix` appended. + Furthermore, if the input is a string that ends with `/`, `default.nix` is appended to it. + Otherwise, the input is returned unchanged. + + # Examples + :::{.example} + ## `lib.filesystem.resolveDefaultNix` usage example + + This expression checks whether `a` and `b` refer to the same locally available Nix file path. + + ```nix + resolveDefaultNix a == resolveDefaultNix b + ``` + + For instance, if `a` is `/some/dir` and `b` is `/some/dir/default.nix`, and `/some/dir/` exists, the expression evaluates to `true`, despite `a` and `b` being different references to the same Nix file. + */ + resolveDefaultNix = + v: + if pathIsDirectory v then + v + "/default.nix" + else if lib.isString v && hasSuffix "/" v then + # A path ending in `/` can only refer to a directory, so we take the hint, even if we can't verify the validity of the path's `/` assertion. + # A `/` is already present, so we don't add another one. + v + "default.nix" + else + v; } diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 437714a2822e..a723d198cb88 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -4255,4 +4255,50 @@ runTests { }; }; }; + + testFilesystemResolveDefaultNixFile1 = { + expr = lib.filesystem.resolveDefaultNix ./foo.nix; + expected = ./foo.nix; + }; + + testFilesystemResolveDefaultNixFile2 = { + expr = lib.filesystem.resolveDefaultNix ./default.nix; + expected = ./default.nix; + }; + + testFilesystemResolveDefaultNixDir1 = { + expr = lib.filesystem.resolveDefaultNix ./.; + expected = ./default.nix; + }; + + testFilesystemResolveDefaultNixFile1_toString = { + expr = lib.filesystem.resolveDefaultNix (toString ./foo.nix); + expected = toString ./foo.nix; + }; + + testFilesystemResolveDefaultNixFile2_toString = { + expr = lib.filesystem.resolveDefaultNix (toString ./default.nix); + expected = toString ./default.nix; + }; + + testFilesystemResolveDefaultNixDir1_toString = { + expr = lib.filesystem.resolveDefaultNix (toString ./.); + expected = toString ./default.nix; + }; + + testFilesystemResolveDefaultNixDir1_toString2 = { + expr = lib.filesystem.resolveDefaultNix (toString ./.); + expected = toString ./. + "/default.nix"; + }; + + testFilesystemResolveDefaultNixNonExistent = { + expr = lib.filesystem.resolveDefaultNix "/non-existent/this/does/not/exist/for/real/please-dont-mess-with-your-local-fs"; + expected = "/non-existent/this/does/not/exist/for/real/please-dont-mess-with-your-local-fs"; + }; + + testFilesystemResolveDefaultNixNonExistentDir = { + expr = lib.filesystem.resolveDefaultNix "/non-existent/this/does/not/exist/for/real/please-dont-mess-with-your-local-fs/"; + expected = "/non-existent/this/does/not/exist/for/real/please-dont-mess-with-your-local-fs/default.nix"; + }; + }