persist: convert the sane.persist.home.<store> => mappings back to a strongly-typed module & add a byPath shorthand

This commit is contained in:
2023-01-06 13:06:39 +00:00
parent b0950e90f4
commit a7bac5de18
2 changed files with 50 additions and 32 deletions

View File

@@ -4,34 +4,15 @@ let
path = sane-lib.path;
cfg = config.sane.persist;
# take a directory attrset and fix its directory to be absolute
fixDir = relativeTo: dir: dir // {
directory = path.concat [ relativeTo dir.directory ];
};
fixDirs = relativeTo: dirs: map (fixDir relativeTo) dirs;
# set the `store` attribute on one dir attrset
fixStore = store: dir: dir // {
inherit store;
};
# String -> [a] -> [a]
# usually called on an attrset to map (AttrSet [a]) -> [a]
fixStoreForDirs = store: dirs: map (fixStore store) dirs;
# populate the `store` attr for all the substores in home
unfixed-home-dirs = builtins.concatLists (lib.mapAttrsToList fixStoreForDirs cfg.home);
# populate the `store` attr for all the substores in sys
unfixed-sys-dirs = builtins.concatLists (lib.mapAttrsToList fixStoreForDirs cfg.sys);
fixed-dirs = (fixDirs "/home/colin" unfixed-home-dirs) ++ (fixDirs "/" unfixed-sys-dirs);
dirToAttrs = dir: {
"${dir.directory}" = {
inherit (dir) user group mode store;
};
};
withPrefix = relativeTo: entries: lib.mapAttrs' (fspath: value: {
name = path.concat [ relativeTo fspath ];
inherit value;
}) entries;
in
{
# compute the `byPath` path => entry mapping from higher-level store => entry mappings.
sane.persist.byPath = lib.mkMerge (map dirToAttrs fixed-dirs);
# merge the `byPath` mappings from both `home` and `sys` into one namespace
sane.persist.byPath = lib.mkMerge [
(withPrefix "/home/colin" cfg.home.byPath)
(withPrefix "/" cfg.sys.byPath)
];
}

View File

@@ -80,12 +80,49 @@ let
};
};
# attrset from { "${storeName}" = [ dirEntry ] }
# the user can specify something like:
# this submodule creates one attr per store, so that the user can specify something like:
# <option>.private.".cache/vim" = { mode = "0700"; };
# to place ".cache/vim" into the private store and create with the appropriate mode
dirsSubModule = types.attrsOf (types.listOf entryInStoreOrShorthand);
dirsSubModule = types.submodule ({ config, ... }: {
options = (mapAttrs (store: store-cfg: mkOption {
default = [];
type = types.listOf entryInStoreOrShorthand;
description = let
suffix = if store-cfg.storeDescription != null then
": ${store-cfg.storeDescription}"
else "";
in "directories to persist in ${store}${suffix}";
}) cfg.stores) // {
byPath = mkOption {
type = types.attrsOf entryAtPath;
default = {};
description = ''
map of <path> => <path config> for all paths to be persisted.
this is computed from the other options, but users can also set it explicitly (useful for overriding)
'';
};
};
config = let
# set the `store` attribute on one dir attrset
annotateWithStore = store: dir: dir // {
inherit store;
};
# String -> [a] -> [a]
# usually called on an attrset to map (AttrSet [a]) -> [a]
annotatedDirsForStore = store: map (annotateWithStore store) config."${store}";
store-names = attrNames cfg.stores;
# flat list where each item is an entryInStore with an additional `store` attribute
annotated-dirs = lib.concatMap annotatedDirsForStore store-names;
# convert an `entryInStore` to an `entryAtPath`
dirToAttrs = dir: {
"${dir.directory}" = {
inherit (dir) user group mode store;
};
};
in {
byPath = lib.mkMerge (map dirToAttrs annotated-dirs);
};
});
in
{
options = {