main
 1{
 2  den,
 3  lib,
 4  ...
 5}: let
 6  # Shared collector body for the home-manager persistence quirks. Reused by
 7  # two distinct aspects so that the same logic runs at both the host scope
 8  # (projected onto users via the host-aspects battery) and the user scope.
 9  homeCollector = {
10    persistHome,
11    cacheHome,
12    config,
13    ...
14  }: let
15    _removeHomePrefix = path: lib.removePrefix "${config.home.homeDirectory}/" path;
16    removeHomePrefix = path:
17      if (lib.typeOf path == "string")
18      then _removeHomePrefix path
19      else path // {directory = _removeHomePrefix path.directory;};
20    removeHomePrefixes = paths: lib.map removeHomePrefix paths;
21    mergePersist = entries: {
22      directories = lib.unique (lib.concatMap (e: removeHomePrefixes (e.directories or [])) entries);
23      files = lib.unique (lib.concatMap (e: removeHomePrefixes (e.files or [])) entries);
24    };
25  in {
26    home.persistence."/persist" = mergePersist persistHome;
27    home.persistence."/cache" = mergePersist cacheHome;
28  };
29in {
30  den.quirks.persist.description = "Persistent directories/files collected from aspects (host)";
31  den.quirks.cache.description = "Cache directories/files collected from aspects (host)";
32  den.quirks.persistUser.description = "Persistent directories/files collected from aspects (user)";
33  den.quirks.cacheUser.description = "Cache directories/files collected from aspects (user)";
34  den.quirks.persistHome.description = "Persistent directories/files collected from aspects (home manager)";
35  den.quirks.cacheHome.description = "Cache directories/files collected from aspects (home manager)";
36
37  den.aspects.core.impermanence.persist-collector = {
38    nixos = {
39      persist,
40      cache,
41      ...
42    }: let
43      mergePersist = entries: {
44        directories = lib.unique (lib.concatMap (e: e.directories or []) entries);
45        files = lib.unique (lib.concatMap (e: e.files or []) entries);
46      };
47    in {
48      environment.persistence."/persist" = mergePersist persist;
49      environment.persistence."/cache" = mergePersist cache;
50    };
51  };
52
53  den.aspects.core.impermanence.persist-user-collector = {user, ...}: {
54    nixos = {
55      persistUser,
56      cacheUser,
57      ...
58    }: let
59      mergePersist = entries: {
60        directories = lib.unique (lib.concatMap (e: e.directories or []) entries);
61        files = lib.unique (lib.concatMap (e: e.files or []) entries);
62      };
63    in {
64      environment.persistence."/persist".users.${user.userName} = mergePersist persistUser;
65      environment.persistence."/cache".users.${user.userName} = mergePersist cacheUser;
66    };
67  };
68
69  den.aspects.core.impermanence.persist-home-collector.homeManager = homeCollector;
70  den.aspects.core.impermanence.persist-home-user-collector.homeManager = homeCollector;
71
72  den.default.includes = (
73    den.lib.policy.when
74    ({host, ...}:
75      host.hasAspect {
76        name = "impermanence";
77        meta.provider = ["core"];
78      })
79    [den.aspects.core.impermanence.persist-home-user-collector]
80  );
81}