Generate flake.nix from module options. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ dendrix.oeiuwq.com/Dendritic.html
dendritic nix inputs

discover bootstrap tests and fix npins test

+55 -10
+14 -8
.github/workflows/flake-check.yaml
··· 16 16 templates=$(find templates -mindepth 2 -maxdepth 2 -name flake.nix -print0 | xargs -0 dirname | xargs -n 1 basename | jq -R | jq -sc) 17 17 echo "$templates" 18 18 echo "templates=$templates" >> $GITHUB_OUTPUT 19 + find-bootstrap-tests: 20 + name: Find bootstrap tests 21 + runs-on: ubuntu-latest 22 + outputs: 23 + tests: ${{ steps.tests.outputs.tests }} 24 + steps: 25 + - uses: actions/checkout@v4 26 + - id: tests 27 + run: | 28 + tests=$(awk '/buildInputs = \[/{p=1} p && /test-/{print $1} /^\s*\]/{p=0}' dev/_bootstrap-tests.nix | jq -R | jq -sc) 29 + echo "$tests" 30 + echo "tests=$tests" >> $GITHUB_OUTPUT 19 31 bootstrap: 20 32 name: Bootstrap ${{matrix.bootstrap}} 33 + needs: [find-bootstrap-tests] 21 34 runs-on: ubuntu-latest 22 35 strategy: 23 36 matrix: 24 - bootstrap: 25 - - test-inputs 26 - - test-flake 27 - - test-unflake 28 - - test-nixlock 29 - - test-npins 30 - - test-npins-follows 31 - - test-npins-transitive 37 + bootstrap: ${{ fromJSON(needs.find-bootstrap-tests.outputs.tests) }} 32 38 env: 33 39 NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz" 34 40 steps:
+21 -1
dev/_bootstrap-tests.nix
··· 29 29 inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs-lib"; 30 30 }; 31 31 32 + flake-parts-skip = bootstrap { 33 + inputs.flake-parts.url = "github:hercules-ci/flake-parts"; 34 + inputs.flake-parts.inputs.nixpkgs-lib.follows = ""; 35 + }; 36 + 32 37 test-inputs = pkgs.writeShellApplication { 33 38 name = "test-inputs"; 34 39 runtimeInputs = [ ··· 91 96 write-npins 92 97 cat ${outdir}/npins/sources.json 93 98 jq -e '.pins."flake-parts".url | contains("hercules-ci/flake-parts")' ${outdir}/npins/sources.json 94 - echo FAIL jq -e '.pins."nixpkgs-lib".url | contains("vic/empty")' ${outdir}/npins/sources.json 99 + jq -e '.pins."nixpkgs-lib".url | contains("vic/empty")' ${outdir}/npins/sources.json 100 + ''; 101 + }; 102 + 103 + test-npins-skip = pkgs.writeShellApplication { 104 + name = "test-npins-skip"; 105 + runtimeInputs = [ 106 + (flake-parts-skip.flake-file.apps.write-npins pkgs) 107 + pkgs.jq 108 + ]; 109 + text = '' 110 + write-npins 111 + cat ${outdir}/npins/sources.json 112 + jq -e '.pins."flake-parts".url | contains("hercules-ci/flake-parts")' ${outdir}/npins/sources.json 113 + jq -e '.pins | has("nixpkgs-lib") | not' ${outdir}/npins/sources.json 95 114 ''; 96 115 }; 97 116 ··· 124 143 test-flake 125 144 test-unflake 126 145 test-npins 146 + test-npins-skip 127 147 test-npins-follows 128 148 test-npins-transitive 129 149 test-nixlock
+17 -1
modules/npins/default.nix
··· 14 14 lines = lib.mapAttrsToList (name: input: "${name}\t${input.url or ""}") pinnableInputs; 15 15 in lib.concatStringsSep "\n" lines; 16 16 17 + # Collect names of inputs that are explicitly skipped (follows = "") at any nesting level. 18 + collectSkipped = 19 + inputMap: 20 + lib.concatLists ( 21 + lib.mapAttrsToList ( 22 + name: input: 23 + let 24 + here = lib.optional (input ? follows && input.follows == "") name; 25 + nested = if input ? inputs then collectSkipped input.inputs else [ ]; 26 + in 27 + here ++ nested 28 + ) inputMap 29 + ); 30 + 31 + skipSet = lib.concatStringsSep "\n" (collectSkipped inputs); 32 + 17 33 write-npins = 18 34 pkgs: 19 35 pkgs.writeShellApplication { ··· 26 42 ]; 27 43 runtimeEnv = { 28 44 out = flake-file.intoPath; 29 - inherit queueSeed; 45 + inherit queueSeed skipSet; 30 46 }; 31 47 text = builtins.readFile ./npins.bash; 32 48 };
+3
modules/npins/npins.bash
··· 5 5 QUEUE_FILE=$(mktemp) 6 6 trap 'rm -f "$SEEN_FILE" "$QUEUE_FILE"' EXIT 7 7 8 + # Pre-mark skipped inputs (follows="") as seen so they are never pinned. 9 + printf '%s\n' "$skipSet" | grep -v '^$' >> "$SEEN_FILE" || true 10 + 8 11 # Seed the BFS queue with all declared inputs. 9 12 echo "$queueSeed" > "$QUEUE_FILE" 10 13