summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--modules/foundation/default.nix9
-rw-r--r--modules/foundation/home/default.nix7
-rw-r--r--modules/foundation/home/mutable.nix81
-rw-r--r--modules/home/common.nix2
4 files changed, 99 insertions, 0 deletions
diff --git a/modules/foundation/default.nix b/modules/foundation/default.nix
new file mode 100644
index 0000000..19b1462
--- /dev/null
+++ b/modules/foundation/default.nix
@@ -0,0 +1,9 @@
+{ ... }:
+
+{
+  # currently there are no foundation
+  # modules in the `minerals` configuration.
+  # after the (possible) merge with the
+  # network configuration, it will house
+  # more modules.
+}
diff --git a/modules/foundation/home/default.nix b/modules/foundation/home/default.nix
new file mode 100644
index 0000000..627dac6
--- /dev/null
+++ b/modules/foundation/home/default.nix
@@ -0,0 +1,7 @@
+{ ... }:
+
+{
+  imports = [
+    ./mutable.nix
+  ];
+}
diff --git a/modules/foundation/home/mutable.nix b/modules/foundation/home/mutable.nix
new file mode 100644
index 0000000..76f44af
--- /dev/null
+++ b/modules/foundation/home/mutable.nix
@@ -0,0 +1,81 @@
+# this module is heavily inspired by a home-manager module
+# created by @piousdeer, although improved and slightly simplified.
+# see: https://gist.github.com/piousdeer/b29c272eaeba398b864da6abf6cb5daa
+{ config, lib, ... }:
+
+let
+  inherit (lib)
+    hm
+    types
+    assertMsg
+    mkOption
+    escapeShellArg
+    splitString
+    recursiveUpdate
+    setAttrByPath
+    concatLines
+    ;
+
+  optionPathsToExtend = [
+    "home.file"
+    "xdg.configFile"
+    "xdg.dataFile"
+    "xdg.stateFile"
+  ];
+in
+{
+  options =
+    let
+      # like `mergeAttrsList`, but doesn't overwrite deep paths,
+      # adding to the inner attrsets instead.
+      recursiveMergeAttrsList = builtins.foldl' recursiveUpdate { };
+
+      path = p: splitString "." p;
+
+      mutableOption = mkOption {
+        type = types.attrsOf (
+          types.submodule {
+            options.mutable = mkOption {
+              type = types.bool;
+              default = false;
+              description = ''
+                Instead of linking from this file to the nix store,
+                copy the contents to the path directly, thus making
+                the file writable to programs.
+                Requires the `force` option to be true.
+              '';
+            };
+          }
+        );
+      };
+    in
+    recursiveMergeAttrsList (map (p: setAttrByPath (path p) mutableOption) optionPathsToExtend);
+
+  config = {
+    home.activation.overwriteMutableFiles = hm.dag.entryAfter [ "linkGeneration" ] (
+      let
+        # all xdg files end up inside the normal `home.file`
+        # list either way, we don't have to look into the others.
+        cfg = config.home.file // config.xdg.configFile;
+        allFiles = builtins.attrValues cfg;
+        mutableFiles = builtins.filter (
+          f: (f.mutable or false) && assertMsg f.force "`mutable` also requires `force` to be set to true"
+        ) allFiles;
+
+        copyFileCommand =
+          { source, target, ... }:
+          ''
+            run cp $VERBOSE_ARG --remove-destination --no-preserve=mode \
+              ${escapeShellArg source} ${escapeShellArg target} \
+              || errorEcho "Overwriting mutable file '${escapeShellArg target}' failed!"
+          '';
+      in
+      ''
+        ${config.lib.bash.initHomeManagerLib}
+
+        verboseEcho "Overwriting symlinks with mutable files"
+        ${concatLines (map copyFileCommand mutableFiles)}
+      ''
+    );
+  };
+}
diff --git a/modules/home/common.nix b/modules/home/common.nix
index 7e10560..f87bf99 100644
--- a/modules/home/common.nix
+++ b/modules/home/common.nix
@@ -2,6 +2,8 @@
 
 {
   imports = [
+    ../foundation/home
+
     ./code.nix
   ];