nix-files/modules/lib/fs.nix

42 lines
1.4 KiB
Nix

{ lib, sane-lib, ... }:
let
sane-path = sane-lib.path;
in rec {
wanted = lib.attrsets.unionOfDisjoint { wantedBeforeBy = [ "multi-user.target" ]; };
wantedDir = wanted { dir = {}; };
wantedSymlink = symlink: wanted { inherit symlink; };
wantedSymlinkTo = target: wantedSymlink { inherit target; };
wantedText = text: wantedSymlink { inherit text; };
# Type: derefSymlinkOrNul :: config.sane.fs.type -> str -> (str|null)
# N.B.: the returned path, even though absolute, might not be "canonical".
# for example, if the symlink is relative, to "../Pictures", this function
# could return "/home/colin/Music/../Pictures".
# consider feeding the output into `sane-lib.path.realpath` to correct this.
derefSymlinkOrNull = fs: logical: let
symlinkedPrefixes = lib.filter
(p: ((fs."${p}" or {}).symlink or null) != null)
(sane-path.walk "/" logical);
firstSymlink = builtins.head symlinkedPrefixes;
firstSymlinkDest = fs."${firstSymlink}".symlink.target;
firstSymlinkParent = sane-path.parent firstSymlink;
firstSymlinkDestAbs = if lib.hasPrefix "/" firstSymlinkDest then
firstSymlinkDest
else
sane-path.join [ firstSymlinkParent firstSymlinkDest ];
in
if symlinkedPrefixes != [] then
firstSymlinkDestAbs
else
null
;
derefSymlink = fs: logical:
if derefSymlinkOrNull fs logical != null then
derefSymlinkOrNull fs logical
else
logical
;
}