zaphyra's git: haumea

fork of https://github.com/nix-community/haumea

commit eb1c2879eb9f9197f045277690a7e97d989011f1
parent abc84235524004a26acd8c93dae8b9470292e4f4
Author: figsoda <figsoda@pm.me>
Date: Fri, 7 Apr 2023 12:47:13 -0400

Merge pull request #1 from nix-community/transformer

8 files changed, 85 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
@@ -22,7 +22,7 @@ A list of available versions can be found on the
 
 ### [`load`](src/load.nix)
 
-Type: `{ src, loader?, inputs? } -> { ... }`
+Type: `{ src, loader?, inputs?, transformer? } -> { ... }`
 
 Arguments:
 

@@ -41,6 +41,11 @@ Arguments:
   `self`, `super`, and `root` are reserved names that cannot be passed as an input.
   To work around that, remove them using `removeAttrs`, or pass them by overriding the loader.
 
+- (optional) `transformer` : `{ ... } -> a`
+
+  Module transformer, defaults to `id` (no transformation).
+  This will transform each directory module in `src`, including the root.
+
 The main entry point of haumea. This is probably the function you are looking for.
 
 Nix files found in `src` are loaded into an attribute set with the specified `loader`.

@@ -161,6 +166,14 @@ Type: `{ ... } -> Path -> a`
 This loader will simply `import` the file without providing any input.
 It is useful when the files being loaded are mostly functions that don't require any external input.
 
+### [`transformers.liftDefault`](src/transformers/liftDefault.nix)
+
+Type: `{ ... } -> { ... }`
+
+This transformer will lift the contents of `default` into the module.
+It will fail if `default` is not an attribute set,
+or has any overlapping attributes with the module.
+
 ## Alternatives
 
 [std](https://github.com/divnix/std) is a more full-featured framework that also has filesystem-based auto-importing.
diff --git a/src/load.nix b/src/load.nix
@@ -17,6 +17,7 @@ let
     flip
     getAttrFromPath
     hasSuffix
+    id
     nameValuePair
     optionalAttrs
     pipe

@@ -40,21 +41,22 @@ let
   entry = { isDir, path, ... }:
     "${if isDir then "directory" else "file"} '${path}'";
 
-  view = { cursor ? [ ], node, pov }:
+  view = { cursor ? [ ], node, pov, transformer }:
     if node.isDir then
-      flip concatMapAttrs node.children
-        (name: node: optionalAttrs
-          {
-            public = true;
-            root = pov != "external";
-            super = pov != "external" && take (length cursor) pov == cursor;
-          }.${node.visibility}
-          {
-            ${name} = view {
-              cursor = cursor ++ [ name ];
-              inherit node pov;
-            };
-          })
+      transformer
+        (flip concatMapAttrs node.children
+          (name: node: optionalAttrs
+            {
+              public = true;
+              root = pov != "external";
+              super = pov != "external" && take (length cursor) pov == cursor;
+            }.${node.visibility}
+            {
+              ${name} = view {
+                cursor = cursor ++ [ name ];
+                inherit node pov transformer;
+              };
+            }))
     else
       node.content;
 

@@ -116,7 +118,11 @@ let
     ];
 in
 
-{ src, loader ? root.loaders.default, inputs ? { } }:
+{ src
+, loader ? root.loaders.default
+, inputs ? { }
+, transformer ? id
+}:
 
 assert all
   (name: inputs ? ${name}

@@ -124,13 +130,14 @@ assert all
   [ "self" "super" "root" ];
 
 view {
+  inherit transformer;
   pov = "external";
   node = fix (node: {
     isDir = true;
     children = aggregate {
       inherit src loader inputs;
       tree = {
-        inherit node;
+        inherit node transformer;
         pov = [ ];
       };
     };
diff --git a/src/transformers/liftDefault.nix b/src/transformers/liftDefault.nix
@@ -0,0 +1,13 @@
+{ lib }:
+
+let
+  inherit (lib.attrsets)
+    unionOfDisjoint
+    ;
+in
+
+mod:
+
+unionOfDisjoint
+  (removeAttrs mod [ "default" ])
+  (mod.default or { })
diff --git a/tests/liftDefault/__fixture/bar.nix b/tests/liftDefault/__fixture/bar.nix
@@ -0,0 +1 @@
+"bar"
diff --git a/tests/liftDefault/__fixture/default.nix b/tests/liftDefault/__fixture/default.nix
@@ -0,0 +1,4 @@
+{
+  bar = "notbar";
+  baz = "baz";
+}
diff --git a/tests/liftDefault/__fixture/foo.nix b/tests/liftDefault/__fixture/foo.nix
@@ -0,0 +1 @@
+"foo"
diff --git a/tests/liftDefault/expected.nix b/tests/liftDefault/expected.nix
@@ -0,0 +1,14 @@
+{
+  foo = {
+    success = true;
+    value = "foo";
+  };
+  bar = {
+    success = false;
+    value = false;
+  };
+  baz = {
+    success = true;
+    value = "baz";
+  };
+}
diff --git a/tests/liftDefault/expr.nix b/tests/liftDefault/expr.nix
@@ -0,0 +1,15 @@
+{ haumea }:
+
+let
+  inherit (builtins)
+    mapAttrs
+    tryEval
+    ;
+
+  loaded = haumea.load {
+    src = ./__fixture;
+    transformer = haumea.transformers.liftDefault;
+  };
+in
+
+mapAttrs (_: tryEval) loaded