diff --git a/modules/files.nix b/modules/files.nix index 0b87d5391..ae48e30d1 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -39,6 +39,13 @@ in }; config = { + lib.file.mkOutOfStoreSymlink = path: + let + pathStr = toString path; + name = hm.strings.storeFileName (baseNameOf pathStr); + in + pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out''; + # This verifies that the links we are about to create will not # overwrite an existing file. home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] ( diff --git a/tests/modules/files/default.nix b/tests/modules/files/default.nix index 04c61d3b8..77743a760 100644 --- a/tests/modules/files/default.nix +++ b/tests/modules/files/default.nix @@ -1,6 +1,7 @@ { files-executable = ./executable.nix; files-hidden-source = ./hidden-source.nix; + files-out-of-store-symlink = ./out-of-store-symlink.nix; files-source-with-spaces = ./source-with-spaces.nix; files-text = ./text.nix; } diff --git a/tests/modules/files/out-of-store-symlink.nix b/tests/modules/files/out-of-store-symlink.nix new file mode 100644 index 000000000..af274aaeb --- /dev/null +++ b/tests/modules/files/out-of-store-symlink.nix @@ -0,0 +1,29 @@ +{ config, lib, ... }: + +with lib; + +let + + filePath = ./. + "/source with spaces!"; + +in { + config = { + home.file."oos".source = config.lib.file.mkOutOfStoreSymlink filePath; + + nmt.script = '' + assertLinkExists "home-files/oos" + + storePath="$(readlink $TESTED/home-files/oos)" + + if [[ ! -L $storePath ]]; then + fail "Expected $storePath to be a symbolic link, but it was not." + fi + + actual="$(readlink "$storePath")" + expected="${toString filePath}" + if [[ $actual != $expected ]]; then + fail "Symlink home-files/oos should point to $expected via the Nix store, but it actually points to $actual." + fi + ''; + }; +}