Modular, context-aware and aspect-oriented dendritic Nix configurations. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ den.oeiuwq.com
configurations den dendritic nix aspect oriented

A template for bug reproduction. (#50)

authored by oeiuwq.com and committed by

GitHub 891c5c58 f2abd24f

+495 -29
+29 -4
README.md
··· 72 72 { den, ... }: { 73 73 den.aspects.my-laptop = { 74 74 includes = [ 75 - den.aspects.vpn # { host } => config 76 - den._.home-manager # battery 75 + den.aspects.workplace-vpn 76 + den.provides.home-manager 77 77 ]; 78 78 nixos = { /* NixOS options */ }; 79 79 darwin = { /* nix-darwin options */ }; ··· 294 294 295 295 </details> 296 296 297 + <details> 298 + <summary> 299 + 297 300 ### Contributing 298 301 299 - Contributions are welcome! Feel free to fix typos, improve documentation, or share ideas in our [discussions](https://github.com/vic/den/discussions). 302 + > Contributions are welcome! Feel free to fix typos, improve documentation, or share ideas in our [discussions](https://github.com/vic/den/discussions). 303 + 304 + </summary> 300 305 301 306 All PRs are checked against the CI. New features should include a test in `_example/ci.nix`. 302 307 ··· 304 309 305 310 ```console 306 311 nix flake check ./checkmate --override-input target . 307 - cd templates/default && nix flake check --override-input den ../.. 312 + nix flake check ./templates/default --override-input den . 313 + ``` 314 + 315 + Ensure code is formatted: 316 + 317 + ```console 318 + nix run ./checkmate#fmt --override-input target . 319 + ``` 320 + 321 + If you have found a bug, please open a discussion (issues are for agreed, actionable items). 322 + 323 + We provide a [`bogus`](templates/bogus/) template you can use 324 + to create a minimal bug reproduction repository. Please share your repo. 325 + 326 + ```console 327 + mkdir bogus && cd bogus 328 + nix flake init -t github:vic/den#bogus 329 + nix flake update den 330 + nix flake check 308 331 ``` 332 + 333 + </details>
+7 -7
flake.nix
··· 1 1 { 2 2 outputs = _: { 3 3 flakeModule = ./nix/flakeModule.nix; 4 - templates.default = { 5 - path = ./templates/default; 6 - description = "Example configuration"; 7 - }; 8 - templates.minimal = { 9 - path = ./templates/minimal; 10 - description = "Minimal configuration"; 4 + templates = { 5 + default.path = ./templates/default; 6 + default.description = "Example configuration"; 7 + minimal.path = ./templates/minimal; 8 + minimal.description = "Minimal configuration"; 9 + bogus.path = ./templates/bogus; 10 + bogus.description = "For bug reproduction"; 11 11 }; 12 12 packages = import ./nix/template-packages.nix; 13 13 namespace = import ./nix/namespace.nix;
+7 -11
modules/aspects/provides.nix
··· 1 - { 2 - inputs, 3 - lib, 4 - ... 5 - }: 1 + { lib, config, ... }: 6 2 { 7 3 options.den = lib.mkOption { 8 - type = lib.types.submodule ({ 9 - # den provides batteries included. 4 + type = lib.types.submodule { 5 + imports = [ 6 + (lib.mkAliasOptionModule [ "_" ] [ "provides" ]) 7 + ]; 10 8 options.provides = lib.mkOption { 11 9 default = { }; 12 10 description = "Batteries Included - re-usable high-level aspects"; 13 11 type = lib.types.submodule { 14 - freeformType = lib.types.attrsOf (inputs.flake-aspects.lib lib).types.providerType; 12 + freeformType = lib.types.attrsOf config.den.lib.aspects.types.providerType; 15 13 }; 16 14 }; 17 - 18 - imports = [ (lib.mkAliasOptionModule [ "_" ] [ "provides" ]) ]; 19 - }); 15 + }; 20 16 }; 21 17 }
+22
templates/bogus/.github/workflows/test.yml
··· 1 + on: 2 + pull_request: 3 + push: 4 + branches: [main] 5 + concurrency: 6 + group: ${{ github.workflow }}-${{ github.ref }} 7 + cancel-in-progress: true 8 + jobs: 9 + flake-check: 10 + strategy: 11 + matrix: 12 + os: [ubuntu-latest, macos-latest] 13 + name: Nix flake check 14 + runs-on: ${{matrix.os}} 15 + steps: 16 + - uses: wimpysworld/nothing-but-nix@main 17 + if: matrix.os == 'ubuntu-latest' 18 + - uses: DeterminateSystems/nix-installer-action@main 19 + - uses: DeterminateSystems/magic-nix-cache-action@main 20 + - uses: actions/checkout@v5 21 + - run: nix flake metadata 22 + - run: nix flake check
+17
templates/bogus/README.md
··· 1 + # Bug Reproduction den 2 + 3 + Use this small template to reproduce bugs in den. 4 + 5 + Create a **minimal** bug reproduction at [`modules/bug.nix`](modules/bug.nix) 6 + 7 + Then run tests: 8 + 9 + ```console 10 + nix flake check 11 + ``` 12 + 13 + Format code with: 14 + 15 + ```console 16 + nix fmt 17 + ```
+222
templates/bogus/flake.lock
··· 1 + { 2 + "nodes": { 3 + "den": { 4 + "locked": { 5 + "lastModified": 1762509696, 6 + "narHash": "sha256-G6Y2rlS7mpTSuCN22O7hsyRdgboJzFZz4UdLHKjfTts=", 7 + "owner": "vic", 8 + "repo": "den", 9 + "rev": "f2abd24fb8bf6183f80fe5f6ac94baf440d77874", 10 + "type": "github" 11 + }, 12 + "original": { 13 + "owner": "vic", 14 + "ref": "main", 15 + "repo": "den", 16 + "type": "github" 17 + } 18 + }, 19 + "flake-aspects": { 20 + "locked": { 21 + "lastModified": 1762465224, 22 + "narHash": "sha256-jfXLTwngKXwFOCVfCupHGcCw/OIpgy5lMYIF8KPfMN8=", 23 + "owner": "vic", 24 + "repo": "flake-aspects", 25 + "rev": "4cbae79bc642311f45c211f9c20d20226544b6f9", 26 + "type": "github" 27 + }, 28 + "original": { 29 + "owner": "vic", 30 + "repo": "flake-aspects", 31 + "type": "github" 32 + } 33 + }, 34 + "flake-file": { 35 + "locked": { 36 + "lastModified": 1762466468, 37 + "narHash": "sha256-OTAbN2Vmdn6Km2AYN+G6QrCdQUtbqaJKAJATP0tGkB8=", 38 + "owner": "vic", 39 + "repo": "flake-file", 40 + "rev": "6a7da81583a42ba339a06aed2d0f3ee4a164f265", 41 + "type": "github" 42 + }, 43 + "original": { 44 + "owner": "vic", 45 + "repo": "flake-file", 46 + "type": "github" 47 + } 48 + }, 49 + "flake-parts": { 50 + "inputs": { 51 + "nixpkgs-lib": [ 52 + "nixpkgs-lib" 53 + ] 54 + }, 55 + "locked": { 56 + "lastModified": 1762440070, 57 + "narHash": "sha256-xxdepIcb39UJ94+YydGP221rjnpkDZUlykKuF54PsqI=", 58 + "owner": "hercules-ci", 59 + "repo": "flake-parts", 60 + "rev": "26d05891e14c88eb4a5d5bee659c0db5afb609d8", 61 + "type": "github" 62 + }, 63 + "original": { 64 + "owner": "hercules-ci", 65 + "repo": "flake-parts", 66 + "type": "github" 67 + } 68 + }, 69 + "home-manager": { 70 + "inputs": { 71 + "nixpkgs": [ 72 + "nixpkgs" 73 + ] 74 + }, 75 + "locked": { 76 + "lastModified": 1762463325, 77 + "narHash": "sha256-33YUsWpPyeBZEWrKQ2a1gkRZ7i0XCC/2MYpU6BVeQSU=", 78 + "owner": "nix-community", 79 + "repo": "home-manager", 80 + "rev": "0562fef070a1027325dd4ea10813d64d2c967b39", 81 + "type": "github" 82 + }, 83 + "original": { 84 + "owner": "nix-community", 85 + "repo": "home-manager", 86 + "type": "github" 87 + } 88 + }, 89 + "import-tree": { 90 + "locked": { 91 + "lastModified": 1762327901, 92 + "narHash": "sha256-AJ96FNj50DU0bTyIzAPkPOjCZTHqjURVjok8qoXvmqM=", 93 + "owner": "vic", 94 + "repo": "import-tree", 95 + "rev": "90fa129798be99cde036b78658e89475710966a1", 96 + "type": "github" 97 + }, 98 + "original": { 99 + "owner": "vic", 100 + "repo": "import-tree", 101 + "type": "github" 102 + } 103 + }, 104 + "nix-auto-follow": { 105 + "inputs": { 106 + "nixpkgs": [ 107 + "nixpkgs" 108 + ] 109 + }, 110 + "locked": { 111 + "lastModified": 1754073254, 112 + "narHash": "sha256-CQp/v2HQ7AtGJQqFGRZLHt4MZAK3NF94I6GDaRyhbsc=", 113 + "owner": "fzakaria", 114 + "repo": "nix-auto-follow", 115 + "rev": "5baa00b79d4cc46523da0b8b3532c5163d151be4", 116 + "type": "github" 117 + }, 118 + "original": { 119 + "owner": "fzakaria", 120 + "repo": "nix-auto-follow", 121 + "type": "github" 122 + } 123 + }, 124 + "nix-unit": { 125 + "inputs": { 126 + "flake-parts": [ 127 + "flake-parts" 128 + ], 129 + "nixpkgs": [ 130 + "nixpkgs" 131 + ], 132 + "treefmt-nix": [ 133 + "treefmt-nix" 134 + ] 135 + }, 136 + "locked": { 137 + "lastModified": 1762507096, 138 + "narHash": "sha256-dE3CbZR8KRDdb3b4fhMnpvhEl6XB+UnrLezuFekQ2ME=", 139 + "owner": "nix-community", 140 + "repo": "nix-unit", 141 + "rev": "0d7230bc54783b812a5817398885aec660a93051", 142 + "type": "github" 143 + }, 144 + "original": { 145 + "owner": "nix-community", 146 + "repo": "nix-unit", 147 + "type": "github" 148 + } 149 + }, 150 + "nixpkgs": { 151 + "locked": { 152 + "lastModified": 1762361079, 153 + "narHash": "sha256-lz718rr1BDpZBYk7+G8cE6wee3PiBUpn8aomG/vLLiY=", 154 + "owner": "nixos", 155 + "repo": "nixpkgs", 156 + "rev": "ffcdcf99d65c61956d882df249a9be53e5902ea5", 157 + "type": "github" 158 + }, 159 + "original": { 160 + "owner": "nixos", 161 + "ref": "nixpkgs-unstable", 162 + "repo": "nixpkgs", 163 + "type": "github" 164 + } 165 + }, 166 + "root": { 167 + "inputs": { 168 + "den": "den", 169 + "flake-aspects": "flake-aspects", 170 + "flake-file": "flake-file", 171 + "flake-parts": "flake-parts", 172 + "home-manager": "home-manager", 173 + "import-tree": "import-tree", 174 + "nix-auto-follow": "nix-auto-follow", 175 + "nix-unit": "nix-unit", 176 + "nixpkgs": "nixpkgs", 177 + "nixpkgs-lib": [ 178 + "nixpkgs" 179 + ], 180 + "systems": "systems", 181 + "treefmt-nix": "treefmt-nix" 182 + } 183 + }, 184 + "systems": { 185 + "locked": { 186 + "lastModified": 1681028828, 187 + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 188 + "owner": "nix-systems", 189 + "repo": "default", 190 + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 191 + "type": "github" 192 + }, 193 + "original": { 194 + "owner": "nix-systems", 195 + "repo": "default", 196 + "type": "github" 197 + } 198 + }, 199 + "treefmt-nix": { 200 + "inputs": { 201 + "nixpkgs": [ 202 + "nixpkgs" 203 + ] 204 + }, 205 + "locked": { 206 + "lastModified": 1762410071, 207 + "narHash": "sha256-aF5fvoZeoXNPxT0bejFUBXeUjXfHLSL7g+mjR/p5TEg=", 208 + "owner": "numtide", 209 + "repo": "treefmt-nix", 210 + "rev": "97a30861b13c3731a84e09405414398fbf3e109f", 211 + "type": "github" 212 + }, 213 + "original": { 214 + "owner": "numtide", 215 + "repo": "treefmt-nix", 216 + "type": "github" 217 + } 218 + } 219 + }, 220 + "root": "root", 221 + "version": 7 222 + }
+77
templates/bogus/flake.nix
··· 1 + # DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file. 2 + # Use `nix run .#write-flake` to regenerate it. 3 + { 4 + 5 + outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules); 6 + 7 + inputs = { 8 + den = { 9 + url = "github:vic/den/main"; 10 + }; 11 + flake-aspects = { 12 + url = "github:vic/flake-aspects"; 13 + }; 14 + flake-file = { 15 + url = "github:vic/flake-file"; 16 + }; 17 + flake-parts = { 18 + inputs = { 19 + nixpkgs-lib = { 20 + follows = "nixpkgs-lib"; 21 + }; 22 + }; 23 + url = "github:hercules-ci/flake-parts"; 24 + }; 25 + home-manager = { 26 + inputs = { 27 + nixpkgs = { 28 + follows = "nixpkgs"; 29 + }; 30 + }; 31 + url = "github:nix-community/home-manager"; 32 + }; 33 + import-tree = { 34 + url = "github:vic/import-tree"; 35 + }; 36 + nix-auto-follow = { 37 + inputs = { 38 + nixpkgs = { 39 + follows = "nixpkgs"; 40 + }; 41 + }; 42 + url = "github:fzakaria/nix-auto-follow"; 43 + }; 44 + nix-unit = { 45 + inputs = { 46 + flake-parts = { 47 + follows = "flake-parts"; 48 + }; 49 + nixpkgs = { 50 + follows = "nixpkgs"; 51 + }; 52 + treefmt-nix = { 53 + follows = "treefmt-nix"; 54 + }; 55 + }; 56 + url = "github:nix-community/nix-unit"; 57 + }; 58 + nixpkgs = { 59 + url = "github:nixos/nixpkgs/nixpkgs-unstable"; 60 + }; 61 + nixpkgs-lib = { 62 + follows = "nixpkgs"; 63 + }; 64 + systems = { 65 + url = "github:nix-systems/default"; 66 + }; 67 + treefmt-nix = { 68 + inputs = { 69 + nixpkgs = { 70 + follows = "nixpkgs"; 71 + }; 72 + }; 73 + url = "github:numtide/treefmt-nix"; 74 + }; 75 + }; 76 + 77 + }
+27
templates/bogus/modules/bug.nix
··· 1 + { inputs, lib, ... }: 2 + { 3 + den.hosts.x86_64-linux.igloo.users.tux = { }; 4 + den.hosts.aarch64-darwin.apple.users.tim = { }; 5 + 6 + # Use aspects to create a **minimal** bug reproduction 7 + den.aspects.igloo.nixos = 8 + { pkgs, ... }: 9 + { 10 + users.users.tux.packages = [ pkgs.hello ]; 11 + }; 12 + 13 + # rename "it works", evidently it has bugs 14 + flake.tests."test it works" = 15 + let 16 + tux = inputs.self.nixosConfigurations.igloo.config.users.users.tux; 17 + 18 + expr.len = lib.length tux.packages; 19 + expr.name = lib.getName (lib.head tux.packages); 20 + 21 + expected.len = 1; 22 + expected.name = "hello"; 23 + in 24 + { 25 + inherit expr expected; 26 + }; 27 + }
+7
templates/bogus/modules/dendritic.nix
··· 1 + { inputs, lib, ... }: 2 + { 3 + flake-file.inputs.flake-file.url = lib.mkDefault "github:vic/flake-file"; 4 + imports = [ 5 + inputs.flake-file.flakeModules.dendritic 6 + ]; 7 + }
+33
templates/bogus/modules/flakes.nix
··· 1 + # DO-NOT-CHANGE. Keep your reproduction minimalistic! 2 + # 3 + # try not adding new inputs 4 + # but if you have no options (pun intended) 5 + # here's the place. 6 + # 7 + # IF you make any change to this file, use: 8 + # `nix run .#write-flake` 9 + # 10 + # We provide nix-unit and home-manager for common 11 + # usage. 12 + { inputs, ... }: 13 + { 14 + # change "main" with a commit where bug is present 15 + flake-file.inputs.den.url = "github:vic/den/main"; 16 + 17 + flake-file.inputs.nix-unit = { 18 + url = "github:nix-community/nix-unit"; 19 + inputs.nixpkgs.follows = "nixpkgs"; 20 + inputs.flake-parts.follows = "flake-parts"; 21 + inputs.treefmt-nix.follows = "treefmt-nix"; 22 + }; 23 + 24 + flake-file.inputs.home-manager = { 25 + url = "github:nix-community/home-manager"; 26 + inputs.nixpkgs.follows = "nixpkgs"; 27 + }; 28 + 29 + imports = [ 30 + inputs.nix-unit.modules.flake.default 31 + ]; 32 + 33 + }
+12
templates/bogus/modules/formatter.nix
··· 1 + { 2 + perSystem = { 3 + treefmt = { 4 + projectRootFile = "flake.nix"; 5 + programs.nixfmt.enable = true; 6 + programs.nixfmt.excludes = [ ".direnv" ]; 7 + programs.deadnix.enable = true; 8 + programs.mdformat.enable = true; 9 + programs.yamlfmt.enable = true; 10 + }; 11 + }; 12 + }
+8
templates/bogus/modules/nix-unit.nix
··· 1 + # DO-NOT-EDIT: nix-unit configuration. 2 + { lib, inputs, ... }: 3 + { 4 + perSystem.nix-unit = { 5 + allowNetwork = lib.mkDefault true; 6 + inputs = lib.mkDefault inputs; 7 + }; 8 + }
+17
templates/bogus/modules/test-base.nix
··· 1 + { den, ... }: 2 + { 3 + den.default.nixos.system.stateVersion = "25.11"; 4 + den.default.homeManager.home.stateVersion = "25.11"; 5 + den.default.darwin.system.stateVersion = 6; 6 + 7 + den.default.includes = [ 8 + den._.home-manager 9 + den._.define-user 10 + den.aspects.no-boot 11 + ]; 12 + 13 + den.aspects.no-boot.nixos = { 14 + boot.loader.grub.enable = false; 15 + fileSystems."/".device = "/dev/fake"; 16 + }; 17 + }
+9 -6
templates/default/flake.lock
··· 22 22 }, 23 23 "den": { 24 24 "locked": { 25 - "lastModified": 1762509213, 26 - "narHash": "sha256-i63BdrYunrGtCaNjeACZ8ulJNx+pJPegWS60HcwCSgI=", 27 - "path": "/home/vic/hk/den", 28 - "type": "path" 25 + "lastModified": 1762509696, 26 + "narHash": "sha256-G6Y2rlS7mpTSuCN22O7hsyRdgboJzFZz4UdLHKjfTts=", 27 + "owner": "vic", 28 + "repo": "den", 29 + "rev": "f2abd24fb8bf6183f80fe5f6ac94baf440d77874", 30 + "type": "github" 29 31 }, 30 32 "original": { 31 - "path": "/home/vic/hk/den", 32 - "type": "path" 33 + "owner": "vic", 34 + "repo": "den", 35 + "type": "github" 33 36 } 34 37 }, 35 38 "flake-aspects": {
+1 -1
templates/default/flake.nix
··· 14 14 url = "github:nix-darwin/nix-darwin"; 15 15 }; 16 16 den = { 17 - url = "path:/home/vic/hk/den"; 17 + url = "github:vic/den"; 18 18 }; 19 19 flake-aspects = { 20 20 url = "github:vic/flake-aspects";