files: add helper function mkOutOfStoreSymlink

Using this function it is possible to make `home.file` create a
symlink to a path outside the Nix store. For example, a Home Manager
configuration containing

    home.file."foo".source = config.lib.file.mkOutOfStoreSymlink ./bar;

would upon activation create a symlink `~/foo` that points to the
absolute path of the `bar` file relative the configuration file.

PR #1211
This commit is contained in:
Robert Helgesson 2020-05-02 01:06:41 +02:00
parent 70f7c9f355
commit 91551c09d4
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
3 changed files with 37 additions and 0 deletions

View file

@ -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"] (

View file

@ -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;
}

View file

@ -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
'';
};
}