fake.modules transposition for aspect-oriented Dendritic Nix. with cross-aspect dependencies. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ dendrix.oeiuwq.com/Dendritic.html
dendritic nix aspect oriented

init

oeiuwq.com d97b6415

+232
+14
.github/FUNDING.yml
··· 1 + # These are supported funding model platforms 2 + github: [vic] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 3 + patreon: # Replace with a single Patreon username 4 + open_collective: # Replace with a single Open Collective username 5 + ko_fi: oeiuwq # Replace with a single Ko-fi username 6 + tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 7 + community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 8 + liberapay: # Replace with a single Liberapay username 9 + issuehunt: # Replace with a single IssueHunt username 10 + lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 11 + polar: # Replace with a single Polar username 12 + buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 13 + thanks_dev: # Replace with a single thanks.dev username 14 + custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+11
.github/workflows/test.yml
··· 1 + on: 2 + pull_request: 3 + push: 4 + branches: [main] 5 + jobs: 6 + flake-check: 7 + name: nix flake check 8 + runs-on: ubuntu-latest 9 + steps: 10 + - uses: cachix/install-nix-action@v30 11 + - run: nix flake check -L github:vic/checkmate --override-input target github:$GITHUB_REPOSITORY/$GITHUB_SHA
+69
README.md
··· 1 + # flake-aspects 2 + 3 + Tiny nix function and flake-parts-module that transposes an attribute set like: 4 + 5 + ```nix 6 + { 7 + nixos = { 8 + foo = ...; 9 + bar = ...; 10 + }; 11 + darwin = { 12 + bar = ...; 13 + baz = ...; 14 + }; 15 + } 16 + ``` 17 + 18 + Into 19 + 20 + ```nix 21 + { 22 + foo = { 23 + nixos = ...; 24 + }; 25 + bar = { 26 + nixos = ...; 27 + darwin = ...; 28 + }; 29 + baz = { 30 + darwin = ...; 31 + }; 32 + } 33 + ``` 34 + 35 + ## Motivation 36 + 37 + On [Dendritic](https://github.com/mightyiam/dendritic) setups it is common to expose modules using `flake.modules.<class>.<aspect>` - see [aspect-oriented nix configurations](https://vic.github.io/dendrix/Dendritic.html). 38 + 39 + However, for humans, it might be more intuitive to use a transposed attrset `<aspect>.<class>`. Because it feels more natural to nest classes on aspects than the other way around. 40 + 41 + ## Usage 42 + 43 + As a deps-free library from `./default.nix`: 44 + 45 + ```nix 46 + let transpose = import ./default.nix lib; in 47 + transpose { a.b.c = 1; } # => { b.a.c = 1; } 48 + ``` 49 + 50 + As a *Dendritic* flake-parts module that provides the `flake.aspects` option: 51 + 52 + > `flake.aspects` transposes into `flake.modules`. 53 + 54 + ```nix 55 + { inputs, ... }: { 56 + imports = [ inputs.flake-aspects.flakeModule ]; 57 + flake.aspects.sliding-desktop = { 58 + nixos = { ... }; # configure Niri 59 + darwin = { ... }; # configure Paneru 60 + }; 61 + } 62 + ``` 63 + 64 + ## Testing 65 + 66 + ```shell 67 + nix run ./checkmate#fmt --override-input target . 68 + nix flake check ./checkmate --override-input target . -L 69 + ```
+81
checkmate.nix
··· 1 + { inputs, ... }: 2 + { 3 + perSystem = 4 + { lib, ... }: 5 + let 6 + transpose = import ./. lib; 7 + 8 + mkFlake = 9 + mod: 10 + inputs.flake-parts.lib.mkFlake 11 + { 12 + inputs.self = [ ]; 13 + } 14 + { 15 + systems = [ ]; 16 + imports = [ 17 + ./flakeModule.nix 18 + inputs.flake-parts.flakeModules.modules 19 + mod 20 + { flake.modules.nixos.tooling.imports = [ toolOpt ]; } 21 + { flake.modules.darwin.tooling.imports = [ toolOpt ]; } 22 + ]; 23 + }; 24 + 25 + toolOpt = { 26 + options.tool = lib.mkOption { 27 + type = lib.types.string; 28 + default = "<unset>"; 29 + }; 30 + }; 31 + 32 + evalMod = 33 + class: mod: 34 + (lib.evalModules { 35 + inherit class; 36 + modules = [ mod ]; 37 + }).config; 38 + in 39 + { 40 + nix-unit.tests = { 41 + transpose."test swaps parent and child attrNames" = { 42 + expr = transpose { a.b.c = 1; }; 43 + expected = { 44 + b.a.c = 1; 45 + }; 46 + }; 47 + 48 + transpose."test common childs become one parent" = { 49 + expr = transpose { 50 + a.b = 1; 51 + c.b = 2; 52 + }; 53 + expected.b = { 54 + a = 1; 55 + c = 2; 56 + }; 57 + }; 58 + 59 + aspects."test transposes to flake.modules" = 60 + let 61 + flake = mkFlake { 62 + flake.aspects.tooling = { 63 + nixos.tool = "niri"; 64 + darwin.tool = "paper.spoon"; 65 + }; 66 + }; 67 + expr = { 68 + nixos = (evalMod "nixos" flake.modules.nixos.tooling); 69 + darwin = (evalMod "darwin" flake.modules.darwin.tooling); 70 + }; 71 + expected = { 72 + nixos.tool = "niri"; 73 + darwin.tool = "paper.spoon"; 74 + }; 75 + in 76 + { 77 + inherit expr expected; 78 + }; 79 + }; 80 + }; 81 + }
+1
checkmate/.gitignore
··· 1 + flake.lock
+7
checkmate/flake.nix
··· 1 + { 2 + inputs.target.url = "path:.."; 3 + inputs.checkmate.url = "github:vic/checkmate"; 4 + inputs.checkmate.inputs.target.follows = "target"; 5 + inputs.flake-parts.url = "github:hercules-ci/flake-parts"; 6 + outputs = inputs: inputs.checkmate.lib.newFlake; 7 + }
+30
default.nix
··· 1 + let 2 + transposeChild = child: parent: value: { inherit child parent value; }; 3 + accTransposed = 4 + acc: 5 + { 6 + parent, 7 + child, 8 + value, 9 + }: 10 + acc 11 + // { 12 + ${parent} = (acc.${parent} or { }) // { 13 + ${child} = value; 14 + }; 15 + }; 16 + transpose = 17 + lib: 18 + let 19 + eachChildAttrs = parent: lib.mapAttrsToList (transposeChild parent); 20 + deconstruct = lib.mapAttrsToList eachChildAttrs; 21 + reconstruct = lib.foldl accTransposed { }; 22 + in 23 + attrs: 24 + lib.pipe attrs [ 25 + deconstruct 26 + lib.flatten 27 + reconstruct 28 + ]; 29 + in 30 + transpose
+6
flake.nix
··· 1 + { 2 + outputs = _: { 3 + __functor = _: import ./.; 4 + flakeModule = ./flakeModule.nix; 5 + }; 6 + }
+13
flakeModule.nix
··· 1 + { lib, config, ... }: 2 + { 3 + options.flake.aspects = lib.mkOption { 4 + description = '' 5 + Attribute set of `<aspect>.<class>` modules. 6 + 7 + Convenience transposition of `flake.modules.<class>.<aspect>`. 8 + ''; 9 + default = { }; 10 + type = lib.types.lazyAttrsOf lib.types.attrs; 11 + }; 12 + config.flake.modules = import ./. lib config.flake.aspects; 13 + }