70 lines
2.4 KiB
Nix
70 lines
2.4 KiB
Nix
# Taken from: https://github.com/urob/dotfiles/blob/main/lib/mkSymlinkAttrs.nix
|
|
|
|
# This function adds and interpretes outOfStoreSymlink option to home.file attribute sets.
|
|
#
|
|
# Usage:
|
|
# home.file = mkSymlinkAttrs {
|
|
# .foo = { source = "foo"; outOfStoreSymlink = true; recursive = true; };
|
|
# .bar = { source = "foo/bar"; outOfStoreSymlink = true; };
|
|
# };
|
|
{ pkgs, hm, context, runtimeRoot, ... }:
|
|
|
|
let
|
|
inherit (pkgs) lib;
|
|
|
|
# Swap a path inside the nix store with the same path in runtimeRoot
|
|
runtimePath = path:
|
|
let
|
|
rootStr = toString context; # context is the `self` passed to flake outputs
|
|
pathStr = toString path;
|
|
in
|
|
assert lib.assertMsg (lib.hasPrefix rootStr pathStr)
|
|
"${pathStr} does not start with ${rootStr}";
|
|
runtimeRoot + lib.removePrefix rootStr pathStr;
|
|
|
|
# Make outOfStoreSymlink against runtimeRoot. This replicates
|
|
# config.lib.file.mkOutOfStoreSymlink as_mkOutOfStoreSymlink and wraps it to
|
|
# replace the target path in the nix store with the original target path
|
|
# inside runtimeRoot. This is necessary because flakes live in the nix store.
|
|
mkOutOfStoreSymlink =
|
|
let
|
|
_mkOutOfStoreSymlink = path:
|
|
let
|
|
pathStr = toString path;
|
|
name = hm.strings.storeFileName (baseNameOf pathStr);
|
|
in
|
|
pkgs.runCommandLocal name { } ''ln -s ${lib.strings.escapeShellArg pathStr} $out'';
|
|
in
|
|
file: _mkOutOfStoreSymlink (runtimePath file);
|
|
|
|
# Recursively make OutOfStoreSymlinks for all files inside path.
|
|
mkRecursiveOutOfStoreSymlink = path: link:
|
|
builtins.listToAttrs (
|
|
map
|
|
(file: {
|
|
name = link + "${lib.removePrefix (toString path) (toString file)}";
|
|
value = { source = mkOutOfStoreSymlink file; };
|
|
})
|
|
(lib.filesystem.listFilesRecursive path)
|
|
);
|
|
|
|
# Remove custom attributes from attribute set.
|
|
rmopts = attrs: builtins.removeAttrs attrs [ "source" "recursive" "outOfStoreSymlink" ];
|
|
|
|
in fileAttrs: lib.attrsets.concatMapAttrs
|
|
(
|
|
name: value:
|
|
# Make outOfStoreSymlinks
|
|
if value.outOfStoreSymlink or false
|
|
then
|
|
if value.recursive or false
|
|
then
|
|
lib.attrsets.mapAttrs
|
|
(_: attrs: attrs // rmopts value)
|
|
(mkRecursiveOutOfStoreSymlink value.source name)
|
|
else { "${name}" = { source = mkOutOfStoreSymlink value.source; } // rmopts value; }
|
|
# Handle all other cases as usual
|
|
else { "${name}" = value; }
|
|
)
|
|
fileAttrs
|